当父状态由子状态更改时,useEffect不会第一次获得调用

时间:2020-09-27 06:18:56

标签: javascript reactjs react-hooks use-effect

子组件

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>

    </>
  );
};

父组件

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。它使用陈旧(先前的值)值再次调用。 我想念什么?

3 个答案:

答案 0 :(得分:2)

onChange中,您需要这样拨打电话

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

因为调用setValue(e.target.value);时值不会立即更新,所以value将具有您在props.handleSliderChang(value)中传递的先前值
要了解setState的工作原理,请参见此answer

答案 1 :(得分:1)

问题出在onClick FlightRange的{​​{1}}回调上,请参见下面的代码注释

input

因此,要解决此问题,只需将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); }} 参数重构为props.handleSliderChange

e.target.value

答案 2 :(得分:0)

这是因为自从您在孩子中使用useState以来,孩子拥有了自己的生命周期。因此,无论您传递给孩子什么道具,孩子的状态都不会受到影响。

加上您在onChange中传递了错误的值

解决方案::直接在子项上直接使用props值(不存储在状态中):

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>

    </>
  );
};