If I have a variable whose value can be fully derived based on the value of another property, is there any consequence/pitfall to initializing a computed variable vs using a combination of useState
/useEffect
to track the variable? Let me illustrate with a contrived example:
/**
* ex paymentAmounts: [100, 300, 400]
*/
const Option1 = ({paymentAmounts}) => {
const [average, setAverage] = useState(paymentAmounts.reduce((acc, curr) => curr + acc, 0) / paymentAmounts.length)
useEffect(() => {
setAverage(paymentAmounts.reduce((acc, curr) => curr + acc, 0) / paymentAmounts.length)
}, [paymentAmounts])
return (
<div>
Average: {average}
</div>
)
}
or more simply
/**
* ex paymentAmounts: [100, 300, 400]
*/
const Option2 = ({paymentAmounts}) => {
const average = paymentAmounts.reduce((acc, curr) => curr + acc, 0) / paymentAmounts.length
return (
<div>
Average: {average}
</div>
)
}
Am I giving up any control and/or React benefits by using Option2?
Vue.js seems to have this option via computed properties.
You use state (as in useState
that is) when you want to track something in your component (or share it between its children) between rerenders. In your case, you're getting this "state" from your parent component (the parent is the actual state holder). Every change in the parent state (paymentAmounts
in your situation) will reflect in your child component automatically.
As a general "rule", don't use state for data that can be calculated. Keep in mind that every change of a state tracked variable will force the component to re-render. Another bad usage example is this:
const Example = ({variable1}) => {
const [variable, setVariable] = useState(variable1);
...
}
A couple of additional notes:
useEffect
. As pointed out already, your child component will
always re-render and recalculate the average
when your parent's
state change.setAverage
wrong in your useEffect
hook. The setter
takes either a new value or a function that accepts the current one
and returns the new one.paymentAmounts / paymentAmounts.length
calculation. I suppose it is just a dummy
code, but if not, look into it. You're dividing the array itself (not the sum of its values) by its length.So, in short - Yes, you should be using a simple variable to calculate the average and ditch the useState
/useEffect
. Not only you're NOT giving up any benefits, you're actually making your code more performant, maintainable, readable and error-free.