React:数组长度更改不会触发子组件中的重新渲染
React: Array length changes not triggering re-render in child component
在 React 中,我有一个主题列表,每个主题都有一个嵌套的集合列表。主题呈现集合的长度和集合。有时我需要将一组从一个主题移到另一个主题。正确移动后,我可以让设置重新渲染,但设置的长度不会在视觉上发生变化。我相信这是改变状态的问题,但我相信我在对它进行任何更改之前用 this.state.Topics.slice() 复制了我的主题数组。
TopicList.js
ChangeSetsTopic(event)
{
var sourceTopic;
var topics = this.state.Topics.slice();
sourceTopic = topics.find(obj => {return obj.Topic == event.source.droppableId});
var change_set;
for (var i = sourceTopic["Sets"].length - 1; i >= 0; --i) {
if (sourceTopic["Sets"][i].SetID == event.draggableId) {
change_set = sourceTopic["Sets"].splice(i,1)[0];
}
}
var destinationTopic = topics.find(obj => {return obj.Topic == event.destination.droppableId});
destinationTopic["Sets"].push(change_set);
for (var i = 0 ; i < topics.length ; i++) {
if (topics[i].Topic == sourceTopic.Topic) {
topics[i] = sourceTopic;
}
else if (topics[i].Topic == destinationTopic.Topic) {
topics[i] = destinationTopic;
}
}
this.setState({"Topics" : topics });
}
render(){
return( {this.state.Topics.map(( topic , key ) => (
<Topic key={topic.Topic} Sets={topic.Sets} TopicName={topic.Topic}/>
))}
);}
Topic.js
componentDidUpdate(prevProps) {
if(prevProps.Sets.length.toString() != this.props.Sets.toString() )
{
this.setState({"Sets" : this.props.Sets })
}
}
render(){
return( ... <div>this.state.Sets.length.toString()</div> ...)
}
React 不知道通过调用 destinationTopic["Sets"].push(change_set);
会改变另一个组件的状态。建议您的组件尽可能无状态,并且您的数据来自单一来源,然后沿着您的链传播。我建议查看 Flux architecture, as this will help you better understand how data flows through React without internal state. One implementation of Flux is Redux
如果您按照自己的方式设置变异状态,那么我建议您查看 Mobx,因为您所拥有的可以使用 Mobx 存储开箱即用。
祝你好运
Topics
数组改变,React 可以看到它更新了,但是它看不到数组中的单个项目更新,项目是对象,React 通过引用比较对象,而不是通过内容,所以它不能在那里查看更改。
例如destinationTopic
是一个对象。
在 React 中,我有一个主题列表,每个主题都有一个嵌套的集合列表。主题呈现集合的长度和集合。有时我需要将一组从一个主题移到另一个主题。正确移动后,我可以让设置重新渲染,但设置的长度不会在视觉上发生变化。我相信这是改变状态的问题,但我相信我在对它进行任何更改之前用 this.state.Topics.slice() 复制了我的主题数组。
TopicList.js
ChangeSetsTopic(event)
{
var sourceTopic;
var topics = this.state.Topics.slice();
sourceTopic = topics.find(obj => {return obj.Topic == event.source.droppableId});
var change_set;
for (var i = sourceTopic["Sets"].length - 1; i >= 0; --i) {
if (sourceTopic["Sets"][i].SetID == event.draggableId) {
change_set = sourceTopic["Sets"].splice(i,1)[0];
}
}
var destinationTopic = topics.find(obj => {return obj.Topic == event.destination.droppableId});
destinationTopic["Sets"].push(change_set);
for (var i = 0 ; i < topics.length ; i++) {
if (topics[i].Topic == sourceTopic.Topic) {
topics[i] = sourceTopic;
}
else if (topics[i].Topic == destinationTopic.Topic) {
topics[i] = destinationTopic;
}
}
this.setState({"Topics" : topics });
}
render(){
return( {this.state.Topics.map(( topic , key ) => (
<Topic key={topic.Topic} Sets={topic.Sets} TopicName={topic.Topic}/>
))}
);}
Topic.js
componentDidUpdate(prevProps) {
if(prevProps.Sets.length.toString() != this.props.Sets.toString() )
{
this.setState({"Sets" : this.props.Sets })
}
}
render(){
return( ... <div>this.state.Sets.length.toString()</div> ...)
}
React 不知道通过调用 destinationTopic["Sets"].push(change_set);
会改变另一个组件的状态。建议您的组件尽可能无状态,并且您的数据来自单一来源,然后沿着您的链传播。我建议查看 Flux architecture, as this will help you better understand how data flows through React without internal state. One implementation of Flux is Redux
如果您按照自己的方式设置变异状态,那么我建议您查看 Mobx,因为您所拥有的可以使用 Mobx 存储开箱即用。
祝你好运
Topics
数组改变,React 可以看到它更新了,但是它看不到数组中的单个项目更新,项目是对象,React 通过引用比较对象,而不是通过内容,所以它不能在那里查看更改。
例如destinationTopic
是一个对象。