Child component accepts a prop and does calculations to show value. On first load, it does work but when parent does passes new value, nothing updates.
Parent:
function Parent(){
const [v, setV] = useState(0);
const addNewValue = () =>{
setV(generateValue({type:'mv', gId: 3})); // generateValue is a function that returns an integer on each call
}
return (<div>
<Child value={v}/>
<Button onClick={addNewValue}>Calculate</Button>
</div>)
}
Child.js
function Child({value}){
const [baseValue, setBaseValue] = useState(value);
useEffect(()=>{
const calculate = calculate(baseValue);
setBaseValue(calculate);
},[baseValue]);
return (<div>
<Text>{baseValue}</Text>
</div>)
}
The parameter passed to useState only gets used once on the first render, so you will never see any changes due to value updating. However, the Child component is still re-rendering
Your useEffect should just depend on value, since that's what it actually needs to operate on. Otherwise, you'll end up with an infinite loop since every time baseValue changes you're updating it again.
useEffect(()=>{
const calculate = calculate(value);
setBaseValue(calculate);
},[value]);
Also note that storing values from props in state is usually an anti-pattern.
The React docs provide a very helpful checklist of what should not be in state.
- Is it passed in from a parent via props? If so, it probably isn’t state:
- Does it remain unchanged over time? If so, it probably isn’t state.
- Can you compute it based on any other state or props in your component? If so, it isn’t state.
This may fall into #3 (without knowing your full use-case I can't say for sure). In which case you should not use local state in the child at all. If this is true, you should call calculate directly each render, or use memoization if the calculation is intensive.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With