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>)
}
CodePudding user response:
The thing is your effect does not trigger because baseValue
is not changing in a mounted component. The first time it does. You need to update your effect to this:
useEffect(()=>{
const calculate = calculate(value);
setBaseValue(calculate);
},[value]);
CodePudding user response:
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
. Otherwise, you'll end up with an infinite loop since every time baseValue
changes you're updating it again.
useEffect(()=>{
const calculate = calculate(baseValue);
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.