首页 > 解决方案 > 从父级到子级的状态更改未反映到 React Hook 中的 TextField

问题描述

我将组件 (C) 作为道具传递给父组件 (A) 内的子组件 (B)。A 的状态也传递给 C 并映射到 C 的状态。但是当我相应地更新 A 的状态和 B 的状态时,C 的状态不会更新。

我的代码如下所示:(省略了导入语句)

const Parent = (props) => {
    .............(other state)
    const [info, setInfo] = React.useState(props.info);

    const handleDataChanged = (d) => { setInfo(d); }

    return (
        <div>
            ........(other stuffs)
            <MyModal
                ..........(other props)
                body={ <MyComp data={ info } updateData={ handleDataChanged } /> }
            />
        </div>
    );
}


const MyModal = (props) => {
    ..........(other state)
    const [content, setContent] = React.useState(props.body);

    React.useEffect(() => { setContent(props.body); }, [props]);

    return (
        <Modal ...>
            <div>{ content }</div>
        </Modal>
    );
}


const MyComp = (props) => {
    const [data, setData] = React.useState(props.data);

    React.useEffect(() => { setData(props.data); }, [props]);

    return (
        data && <TextField value={ data.name }
                           onChange={ e => {
                                      let d = data;
                                      d.name = e.target.value;
                                      props.updateData(d); }} />
    );
}

当我在 TextField 中输入内容时,我看到Parent'已info更改。useEffectof没有被MyModal解雇。而且datainMyComp没有更新。

更新:经过更多检查上面的代码和下面的解决方案,问题仍然存在,但我看到datainMyComp确实得到了更改Parent,但 TextField 没有反映它。

有人请告诉我如何更新data并将MyComp其反映到Parent. 非常感谢!

标签: reactjsreact-hooks

解决方案


实际上,您似乎正在尝试重新创建子 API https://reactjs.org/docs/react-api.html#reactchildren

如果你使用 props.children 来组合你的组件而不是上下传递 props 会容易得多。

const MyModal = (props) => {
    ...(other state)
    return (
        <Modal>
            <div>{ props.children }</div>
        </Modal>
    );
}

然后您可以直接在父级中处理功能,而无需将道具映射到状态(强烈建议不要这样做)......

const Parent = (props) => {
    ...(other state)
    const [info, setInfo] = React.useState(props.info);

    const handleDataChanged = d => setInfo(d);

    return (
        <div>
            ...(other stuffs)
            <MyModal {...props}>
             <MyComp data={ info } updateData={ handleDataChanged } /> 
           </MyModal>
        </div>
    );
}

这种方法的好处是开销要少得多。而不是将状态 A 传递给 C 并映射到 C 的状态,您可以从状态 A(父组件)执行所有操作。不需要映射,你有一个状态的真实来源,并且更容易思考和构建。

或者,如果您想坚持当前的方法,那么只需像这样直接删除React.useEffect(() => { setContent(props.body); }, [props]);MyModal映射道具

<Modal>
  <div>{ props.body }</div>
</Modal>

推荐阅读