TransWikia.com

useEffect is not getting call first time when parent state is changed by child state at

Stack Overflow Asked by sagar735 on December 13, 2020

Child component

export const FlightRange = (props) => {
  const [value, setValue] = useState(props.value);
  return (
    <>
      <input
        type='range'
        min={1000}
        max={50000}
        step="500"
        value={value}
        onChange={(e) => {
          setValue(e.target.value);
          props.handleSliderChange(value);
        }}
      />
      <span>{value}</span>

    </>
  );
};

parent component

useEffect(() => {
    const result = axios.get('http://localhost:8000/')
    .then((res) => res.json())

    .then((data) => {
      const flightData = data.filter((value) => {
        return (
          valuesplit(' ')[1] < priceSlider
        );
      });
    })
  }, [priceSlider]);

return(
    <Child value={priceSlider} handleSliderChange={(value)=> setPriceSlider(value)} />
 )

useEffect does not get called when the slider is changed the first time. It gets called a second time with the stale (previous value) value.
What am I missing?

3 Answers

in onChange you need to call like this

onChange={(e) => {
          setValue(e.target.value);
          props.handleSliderChange(e.target.value);
        }}

since value is not updated instantly when you call setValue(e.target.value); , value will have previous value that you are passing in props.handleSliderChang(value)
to know how setState works see this answer

Correct answer by shubham jha on December 13, 2020

It because the child is having it's own life cycle since you are using useState in child. so whatever props you pass to your child, the child's state won't affected.

plus you are passing incorrect value in onChange

Solution: just use the props value directly on child (do not store in state):

export const FlightRange = (props) => {
  const { value, handleSliderChange } = props;
  return (
    <>
      <input
        type='range'
        min={1000}
        max={50000}
        step="500"
        value={value}
        onChange={(e) => {
          handleSliderChange(e.target.value);
        }}
      />
      <span>{value}</span>

    </>
  );
};

Answered by aligatr on December 13, 2020

The issue is on the onClick callback of FlightRange input, see comments on code below

onChange = {(e) => {
  setValue(e.target.value); // this is async

  // therefore, the value you are passing here is not the same as e.target.value but simply the value before setting the state
  props.handleSliderChange(value);  
}}

So to fix this just refactor props.handleSliderChange argument to e.target.value

onChange = {(e) => {
  setValue(e.target.value);
  props.handleSliderChange(e.target.value);  
}}

Answered by 95faf8e76605e973 on December 13, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP