如果在函数内声明,React 子组件不会更新



我正在构建一个多步骤的东西,但这些步骤是动态的,并且是基于来自params的一些条件构建的。

在构建它的过程中,我注意到一旦父组件中的状态更新,子组件就不会刷新,这是由于它们的声明/生成方式(在返回步骤数组的函数内部(

我一直在想是否有一个简单的方法来解决这个问题。如果我用上下文提供程序包装它,并在步骤中访问它,它可以很好地工作,但它增加了一些我试图避免的复杂性,尤其是对于稍后的单元测试,因为多步骤方法中会有很多步骤。此外,如果我在返回中移动数组创建,它会起作用,但随后我将失去对数组变量的访问权限,在该变量中,我需要长度来检查步数。

我构建了一个过于简单的例子,说明如果使用组件数组,则演示道具不更新的问题,而如果直接声明步骤,则效果良好:https://codesandbox.io/s/react-dynamic-child-issue-toukfg?file=/src/App.js:0-806

import React from "react"
const TargetGroupStep = ({ targetGroup, setTargetGroup }) => (
<div>
<div>props = {targetGroup}</div>
<button onClick={() => setTargetGroup("group1")}>Button 1</button>
<button onClick={() => setTargetGroup("group2")}>Button 2</button>
</div>
);
export default function App() {
const [targetGroup, setTargetGroup] = React.useState("");
const buildStepsFlow = () => [
<TargetGroupStep targetGroup={targetGroup} setTargetGroup={setTargetGroup}/>,
]
const [steps, setSteps] = React.useState(buildStepsFlow());
return (
<div className="App">
<div>Parent state: {targetGroup}</div>
{steps[0]}
<br/>
If declared:
<TargetGroupStep targetGroup={targetGroup} setTargetGroup={setTargetGroup}/>
</div>
);
}

不要将组件置于状态。相反,让纯数据处于状态,并仅在渲染过程中需要时将其转换为组件-这可以确保所有渲染的组件都具有最新的道具和状态。

由于您不调用setSteps,因此可以完全删除该状态—直接调用buildStepsFlow

const TargetGroupStep = ({ targetGroup, setTargetGroup }) => (
<div>
<div>props = {targetGroup}</div>
<button onClick={() => setTargetGroup("group1")}>Button 1</button>
<button onClick={() => setTargetGroup("group2")}>Button 2</button>
</div>
);

function App() {
const [targetGroup, setTargetGroup] = React.useState("");
const buildStepsFlow = () => [<TargetGroupStep targetGroup={targetGroup} setTargetGroup={setTargetGroup}/>];

return (
<div className="App">
<div>Parent state: {targetGroup}</div>
{buildStepsFlow()[0]}
<br/>
If declared:
<TargetGroupStep targetGroup={targetGroup} setTargetGroup={setTargetGroup}/>
</div>
);
}
ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>

如果您在实际代码中调用了setSteps,请更改其状态,使其存储的是普通数组和对象,并在App结束时返回时将它们映射到组件。

相关内容

  • 没有找到相关文章

最新更新