Reactjs 存储在父级状态的数组中的子级不会收到新道具
我创建了一个独立的小站点来演示我在React中遇到的这个问题。用包含的代码创建一个index.html文件,您就可以对我的问题进行有效的演示Reactjs 存储在父级状态的数组中的子级不会收到新道具,reactjs,Reactjs,我创建了一个独立的小站点来演示我在React中遇到的这个问题。用包含的代码创建一个index.html文件,您就可以对我的问题进行有效的演示 <html> <head> <meta charset="UTF-8"> <script crossorigin src="https://unpkg.com/react/umd/react.development.js"></script>
<html>
<head>
<meta charset="UTF-8">
<script crossorigin src="https://unpkg.com/react/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
class Child extends React.Component {
render() {
return(<p>Child {this.props.index} thinks toggle is {(this.props.toggleProp) ? "TRUE" : "FALSE"}</p>);
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
toggle: false,
children: []
}
}
buttonToggle() {
let newChildren = this.state.children;
newChildren.push(
<Child
key={this.state.children.length}
index={this.state.children.length}
toggleProp={this.state.toggle} />);
this.setState({
toggle: !this.state.toggle,
children: newChildren
});
}
render() {
return <div>
<button onClick={() => this.buttonToggle()}>Click me</button>
<p>Parent thinks toggle is {(this.state.toggle) ? "TRUE" : "FALSE"}</p>
<div>{this.state.children}</div>
</div>
;
}
}
ReactDOM.render(<Parent />, document.getElementById("root"));
</script>
</head>
<body>
<div id="root"></div>
</body>
</html>
据我所知,当您直接渲染子组件(如直接放入父组件的渲染方法)时,父组件的状态发生变化时,子组件将成功接收到道具更新,而不是提供对子组件数组的引用(如本例所示)。在这种情况下,每次单击按钮时,都会创建一个新的子对象,其中包含一个反映创建时父对象布尔值当前状态的道具。但是,当父级状态中的布尔值更改时,所有创建的子组件都不会收到道具更新。这就好像是复制了值而不是引用了值
这就是正在发生的事情吗?在我的实际应用程序中,我有一个动态创建的对象列表,因此我修改了一个包含所有子对象的数组,并根据每个用户操作从该列表中添加/删除项目,并且在父对象中有影响所有子对象的按钮—我作为道具传递的信息。于是我发现了这个问题。我希望这不是虫子。这里可以做什么?试试这段代码
import React from "react";
class Child extends React.Component {
render() {
return (
<p>
Child {this.props.index} thinks toggle is{" "}
{this.props.toggleProp ? "TRUE" : "FALSE"}
</p>
);
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
toggle: false,
children: []
};
}
buttonToggle() {
const newChildren = [...this.state.children];
newChildren.push({
key: this.state.children.length - 1,
index: this.state.children.length - 1
});
this.setState({
toggle: !this.state.toggle,
children: newChildren
});
}
render() {
return (
<div>
<button onClick={() => this.buttonToggle()}>Click me</button>
<p>Parent thinks toggle is {this.state.toggle ? "TRUE" : "FALSE"}</p>
<div>
{this.state.children.map(child => (
<Child
key={child.index}
index={child.index}
toggleProp={this.state.toggle}
/>
))}
</div>
</div>
);
}
}
export default Parent;
代码中的问题是将项推入子项的状态数组,它会保存您一直给它的当前状态。但你不会在新的州重新招标。上述代码将在每次组件更新时重新加载组件。并将最新更新的状态传递给道具
若你们不能使用像map这样的东西,那个么你们可以坚持使用“推但内”的渲染方法
例如
首先,状态未被引用,React通过重新提交同步状态中的值和UI上显示的值,而不是因为它们共享相同的引用 未使用最新值更新子组件是因为未重新渲染它。我猜原因是React只会尝试重新命名引用已更新的子对象。我找不到关于它的任何文件,但它与观察结果相符。在您的代码中,因为您正在执行newChildren.push…,所以旧的children引用保持不变,因此React不会重新命名它们 所以如果你遵循优素福贝克的答案,要么是地图一,要么是for循环一
{this.state.children.map(child => (
<Child
key={child.index}
index={child.index}
toggleProp={this.state.toggle}
/>
))}
它创建了一个新的子实例,甚至是旧的子实例!每次父组件渲染时,子组件都将按预期重新渲染
{this.state.children.map(child => (
<Child
key={child.index}
index={child.index}
toggleProp={this.state.toggle}
/>
))}