I have a component which renders only once and then is being destroyed, I've implemented the "Comp3" way.
Using "useEffect" to calculate the str with the num value I received as a prop, then stored the result using "useEffect" setter in order to use the result in the html.
//Let say this function is inside the functional component
function numToStr(num:number):string{
switch(num){
case 1:
return "One";
case 2:
return "Two";
...
}
}
function Comp1({num:number}){
const numAsStr = numToStr(num);
return <span>{numAsStr}</span>
}
function Comp2({num:number}){
const [numAsStr] = useState(numToStr(num));
return <span>{numAsStr}</span>
}
function Comp3({num:number}){
const [numAsStr,setNumAsStr] = useState();
useEffect(()=>{
setNumAsStr(numToStr(num));
},[])
return <span>{numAsStr}</span>
}
function Comp4({num:number}){
const numAsStr = useMemo(()=>numToStr(num),[]);
return <span>{numAsStr}</span>
}
My question is:
What is the best solution in terms of best-practice/ "react-way"?
How each implementation effect the performance?
Does the fact that I know the component only renders once should impact way I choose to implement?
Or should I treat this component as if i don't know it should be render once and in this case still support the option to "watch" over the prop being changed? (add it to the useEffect / useMemo arrays)
Thanks!
If the calculations being done by strToNum
are cheap (as they are in your simplified example), then the approach in Comp1
is probably the best and simplest. They'll run each time the component re-renders, so they're always up-to-date.
If the calculations are expensive, the recommended way to deal with this is the useMemo
hook, like in your Comp4
example. However, you'd want to make sure to include num
input variable in your dependents array so that numAsStr
gets re-computed whenever num
changes. E.g:
function Comp4({num:number}){
const numAsStr = useMemo(()=>numToStr(num),[num]);
return <span>{numAsStr}</span>
}
Using useState
as you have in Comp2
would only run numToStr
in the initial render, so you'd get stale values if num
ever changed.
Using useEffect
as you have in Comp3
introduces an unnecessary double-render - e.g. it renders first without a value for numAsStr
and then renders again.
I know you said that you are currently sure that it never re-renders again - so some of the downsides/gotchas mentioned above might not apply in this case (and then I'd just go with the Comp1
approach, because it's simpler) but in my experience, it's best not to make that assumption - will you (or a team-mate) remember that in a month when you try to refactor something?