【问题标题】:React: Modify Parent State While Child RendersReact:在子渲染时修改父状态
【发布时间】:2021-09-02 22:39:43
【问题描述】:

钩子通常比类好得多,所以我试图传递使用钩子在该父级的子级中设置父级状态的能力。具体来说,我正在做这样的事情:

class Parent extends Component {

    render = () => {
        return <>
           <Child useRegisterFoo={foo => {...;this.setState(foo);...;}} />
           { renderBasedOnRegister() }
           </>
    }
}

目标是能够像这样定义孩子:

const Child = ({useRegisterFoo}) => {
     useRegisterFoo(1);
     useRegisterFoo(2);
}

我会定义很多这样的孩子,因此有这样一个简单的useRegisterFoo 来注册孩子的特定属性会非常有用。

问题是,如果以这种方式完成,反应会抱怨,这是可以理解的,因为我在渲染父级时正在修改父级的状态。具体来说:

Warning: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.

解决这个问题有什么更好的方法?我的主要目标是让 API 从孩子的角度尽可能方便。

【问题讨论】:

    标签: reactjs react-hooks purely-functional


    【解决方案1】:

    您直接在函数体中调用回调。这是一个无意的副作用,不应该这样做。即使在函数组件中,您仍然需要处理组件生命周期。

    警告:在现有状态转换期间无法更新(例如 在render) 内。渲染方法应该是 props 的纯函数 和状态。

    函数组件的整个主体是“渲染”函数。使用useEffect 挂钩来调用这些传递的回调,或者有条件地将它们作为事件处理程序的一部分调用。

    例子:

    使用带有空依赖数组的useEffect钩子,仅在组件挂载时触发一次效果。

    const Child = ({useRegisterFoo}) => {
      useEffect(() => {
        useRegisterFoo(1);
        useRegisterFoo(2);
      }, []); // <-- empty dependency, effect triggered once on mount
      ...
    }
    

    【讨论】:

    • 谢谢。实际上,我确实将所有setState 回调包装在useEffect 中——除了一个,我把它放在useState(() =&gt; ...setState) 中,因为它返回了我需要的值。我不知道它们在生命周期方面的工作方式不同。我现在将它们分成返回值的部分,我将其放入setState,以及更新父状态的部分,我将其放入useEffect。奇迹般有效。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 2020-05-04
    • 2020-06-18
    • 1970-01-01
    相关资源
    最近更新 更多