目前,我正在从事从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.
这是因为我对多个组件使用相同的密钥。
我希望能够在道具也发生变化的用户之间切换。有办法吗?
答案 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