Issue
Using a stateful pattern, I usually initialize a kind of helper class in my constructor and consume its methods in some component lifecycle methods like below:
class StatefulComponent extends Component {
constructor(props) {
super(props);
this.helper = new HelperClass();
}
componentDidMount() {
this.helper.doSomething();
}
}
Now, I wanted to convert the same logic into a stateless function component like this:
const StatelessFunction = (props) => {
this.helper = new HelperClass();
useEffect(() => {
this.helper.doSomething();
}, []);
}
But I worried when I saw that this component is being called every prop change from the beginning. And this made me think that my class instance is being created over and over. Am I wrong? Is there anything I can do for preventing re-creation of my class and use a ref instead?
I came across useRef but not sure if it fits my case.
Solution
Looking back at this and some of the comments I can see that useMemo can not be trusted to not run the HelperClass constructor again and useRef will only set the helper after the first render because it's initial value can't be a function. Probably useState is the easiest and most reliable way to do this:
const [helper] = useState(()=>new HelperClass());
You can use useMemo to create an instance of HelperClass and useEffect to call it. Giving them both empty array of dependencies means they will only be called "on mount". I put on mount in quotes because memo will be called only on first render and effect will be called after first render cycle is finished.
const StatelessFunction = props => {
const helper = useMemo(() => new HelperClass(), []);
useEffect(() => {
helper.doSomething();
}, [helper]);
return (<JSX />);
};
If the only thing you'll ever do is just call doSomething and never use the helper instance again you can just do it with useEffect:
useEffect(() => {
new HelperClass().doSomething();
}, []);
If you do plan to use the helper instance at some later time then you could use the previous example with useMemo or useRef:
const helper = useRef();
useEffect(() => {
helper.current = new HelperClass();
//only called once after first render
helper.current.doSomething();
}, []);
//you still have the helper instance as helper.current
Answered By - HMR
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.