在子组件之间切换时如何更新道具

时间:2019-08-29 11:58:03

标签: reactjs components

目前,我正在从事从AngularJs到React过渡的项目,但是遇到了一个我无法解决的问题。问题如下:

我有一个显示所有用户的父组件。父组件是指多个子组件(编辑用户,用户顺序,用户活动等),但是当我在两个用户之间进行更改时,子组件中的道具并没有改变,并且仍然显示了前一个用户。 / p>

示例。

单击用户A-单击编辑用户(工作正常)。

单击用户B-单击编辑用户(显示用户A的道具)。

我看了看文档,但是找不到合适的解决方案。我浏览了React文档中的以下文章:https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-controlled-component

它说一个可能的解决方案是解决您组件的关键。密钥更新后,道具将更新。如果我只有1个子组件,则此解决方案将行得通。不幸的是,情况并非如此。

这是子组件的代码:

{isSelected ? <IndividualModalComponent onClose={() => setShowEditDialog(false)} isDialogOpen={showEditDial} key={selectedIndividual.id} individual={selectedIndividual}/> : null}
{isSelected ? <IndividualSecurityComponent onClose={() => setShowPermissionDialog(false)} isDialogOpen={showPermissionDial} key={selectedIndividual.id} individual={selectedIndividual}/> : null}
{isSelected ? <IndividualPasswordComponent onClose={() => setShowPasswordDialog(false)} isDialogOpen={showPasswordDial} key={selectedIndividual.id} individual={selectedIndividual}/> : null}
{isSelected ? <IndividualTwoFactorComponent onClose={() => setShowTwoFactorDialog(false)} isDialogOpen={showTwoFactorDial} key={selectedIndividual.id} individual={selectedIndividual}/> : null}
{isSelected ? <IndividualSessionComponent onClose={() => setShowSessionDialog(false)} isDialogOpen={showSessionDial} key={selectedIndividual.id} individual={selectedIndividual}/> : null}
{isSelected ? <IndividualOrderComponent onClose={() => setShowOrderDialog(false)} isDialogOpen={showOrderDial} key={selectedIndividual.id} individual={selectedIndividual}/> : null}

使用上面显示的代码时,出现以下错误:

backend.js:6 Warning: Encountered two children with the same key, `48097be2-84c2-4a29-acdc-87e57ba88428`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behaviour is unsupported and could change in a future version.

这是因为我对多个组件使用相同的密钥。

我希望能够在道具也发生变化的用户之间切换。有办法吗?

3 个答案:

答案 0 :(得分:4)

首先,将 selectedIndividual 置于状态,然后当您单击编辑用户时,更新 selectedIndividual 状态以匹配您所单击的用户在这种情况下,所有孩子的道具都应直接更新。

如果您将任何孩子的个体道具置于孩子的状态,则应在道具更改后进行更新。解决此问题的一种方法是实现componentDidUpdate。第二种方法是更新孩子的关键道具。第三种方法是实现getDerivedStateFromProps

要解决控制台中有关密钥的错误,建议您在每个子代中使用不同的前缀,例如:

<IndividualModalComponent key={`modal${selectedIndividual.id}`} {...otherProps} />
<IndividualSecurityComponent key={`security${selectedIndividual.id}`} {...otherProps} />

我希望这能回答您的问题。

答案 1 :(得分:2)

您可以做的事情类似

{isSelected && (
    <>
        <IndividualModalComponent onClose={() => setShowEditDialog(false)} isDialogOpen={showEditDial} key={selectedIndividual.id} individual={selectedIndividual}/>
        <IndividualSecurityComponent onClose={() => setShowPermissionDialog(false)} isDialogOpen={showPermissionDial} key={selectedIndividual.id} individual={selectedIndividual}/>
        <IndividualPasswordComponent onClose={() => setShowPasswordDialog(false)} isDialogOpen={showPasswordDial} key={selectedIndividual.id} individual={selectedIndividual}/>
        <IndividualTwoFactorComponent onClose={() => setShowTwoFactorDialog(false)} isDialogOpen={showTwoFactorDial} key={selectedIndividual.id} individual={selectedIndividual}/>
        <IndividualSessionComponent onClose={() => setShowSessionDialog(false)} isDialogOpen={showSessionDial} key={selectedIndividual.id} individual={selectedIndividual}/>
        <IndividualOrderComponent onClose={() => setShowOrderDialog(false)} isDialogOpen={showOrderDial} key={selectedIndividual.id} individual={selectedIndividual}/>
    </>
)}

答案 2 :(得分:0)

如果数据未更改,则子道具未更改。您需要为父级提供一个状态,该状态会在点击时发生变化,以重新呈现子级组件。 此沙箱显示了您尝试实现的相同概念:codesandbox