Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

re-render a functional component on prop change

Tags:

reactjs

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>)

  }
like image 769
ruth hadish Avatar asked Jan 26 '26 20:01

ruth hadish


1 Answers

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.

  1. Is it passed in from a parent via props? If so, it probably isn’t state:
  2. Does it remain unchanged over time? If so, it probably isn’t state.
  3. 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.

like image 175
Brian Thompson Avatar answered Jan 29 '26 12:01

Brian Thompson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!