我正在渲染一个嵌套的评论树,我无法弄清楚如何从深度嵌套的评论之一更新评论容器中存在的树数据。我创建了一个代表该场景的基本 fiddle ,请查看 HERE 。每个节点中的按钮应该反转“likes”属性的值,该值应该来自父容器中的状态。寻找非 redux 解决方案。
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
tree: [
{
id: "cake",
likes: true,
kids: [
{
id: "banana",
likes: false,
kids: []
},
{
id: "rocket",
likes: false,
kids: [
{
id: "homework",
likes: true,
kids: [
{
id: "something",
likes: true,
kids: []
}
]
}
]
}
]
}
]
};
}
render() {
return (
<div>
{this.state.tree.map(value => <Kid value={value} />)}
</div>
);
}
}
class Kid extends React.Component {
render() {
return (
<div style={{margin: '20px', border: '5px dashed #DCEDC8'}}>
<span>id: {this.props.value.id}</span><br />
<span>likes: {this.props.value.likes ? 'yes' : 'no'}</span><br />
<button>invert</button>
{this.props.value.kids.length
? this.props.value.kids.map(value => <Kid value={value} />)
: null}
</div>
);
}
}
React.render(<Parent />, document.getElementById("container"));
<script src="https://facebook.github.io/react/js/jsfiddle-integration.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
最佳答案
对 Redux 状态的建议是保持其标准化,如下所示:
this.state = {
normalized: [
cake: {likes: true, kids: ["banana", "rocket"]}
banana: {likes: false, kids: []},
rocket: {likes: false, kids: ["homework"]},
homework: {likes: true, kids: ["something"]},
something: {likes: true, kids: []},
],
root: "cake",
};
然后,如果您有 id,则可以使用 this.state.normalized[id]
引用一个项目
例如,要遍历树并对每个节点应用函数,您可以这样做:
function traverse(node, func) {
func(node);
for (let i = 0, len = node.kids.length; i < len; i++) {
traverse(this.state.normalized[node.kids[i]]);
}
}
traverse(this.state.normalized[this.state.root]);
如果您不想编写自己的解决方案,Normalizr 对于标准化嵌套 API 响应非常有用。
如果你真的想在你的状态中保留一棵不可变的树,Immutable.js 擅长让你在一行中高效地改变树而不改变它。
关于javascript - 如何在不使用 Flux 的情况下将状态从深层节点传播到嵌套树的根?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43423833/