setState的回调函数仅将最后一个组件的状态填充为渲染时父组件的状态

时间:2020-02-04 02:25:32

标签: reactjs react-hooks

我有一个回调函数,用于将子组件的状态传递给父组件的状态。

当所有子组件加载时,我希望它们执行回调函数并填充父组件的状态。

尽管似乎只有最后一个组件将其状态传递给父组件。


我的孩子部分:

import React, { useState, useEffect } from "react";

export default function Component(props) {
  const [state, setState] = useState(0);

  useEffect(() => {
    var index = props.index;
    var stateSchema = {};
    stateSchema[index] = state;
    props.updateState(stateSchema);
  }, [state]);

  function onLeftClick() {
    setState(state + 1);
  }

  return <p onClick={onLeftClick}>{state}</p>;
}

我的父组件:

import React, { useState, useEffect } from "react";
import Component from "./Component";

export default function ParentComponent() {
  const [state, setState] = useState({});

  function updateState(updatedState) {
    setState({
      ...state,
      ...updatedState
    });
  }

  useEffect(() => {
    console.log(state);
  }, [state]);

  return (
    <div>
      <Component index="a" updateState={updateState} />
      <Component index="b" updateState={updateState} />
      <Component index="c" updateState={updateState} />
      <Component index="d" updateState={updateState} />
      <Component index="e" updateState={updateState} />
    </div>
  );
}

通常我应该在控制台中看到

Object {e: 0, a: 0, b: 0, c: 0, d: 0}

但我明白了,

Object {}

Object {e: 0}

这是我的工作代码:https://codesandbox.io/s/jovial-resonance-f085n?fontsize=14&hidenavigation=1&theme=dark

任何建议,我都会感激。

1 个答案:

答案 0 :(得分:1)

setState操作是异步的,并且为了提高性能而进行了批量处理。在setState的文档中对此进行了解释。

setState()不会立即使this.state突变,而是创建一个 等待状态转换。调用此后访问this.state 方法可能会返回现有值。没有 保证setState调用的同步操作,并且调用可以 分批获得性能提升。

因此,在您的updateState函数中,调用它时,状态尚未更新。

function updateState(updatedState) {
    // state is {}
    setState({
      ...state,
      ...updatedState
    });
  }

要使其生效,请按如下所示更新代码:

function updateState(updatedState) {
    setState(prevState => ({
      ...prevState,
      ...updatedState
    }));
  }

有关此的更多信息:https://reactjs.org/docs/react-component.html#setstate