sagar735
sagar735

Reputation: 53

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

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?

Upvotes: 0

Views: 270

Answers (3)

shubham jha
shubham jha

Reputation: 1460

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

Upvotes: 2

aligatr
aligatr

Reputation: 113

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>

    </>
  );
};

Upvotes: 0

95faf8e76605e973
95faf8e76605e973

Reputation: 14191

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

Upvotes: 1

Related Questions