[英]React component not rerendering when props changes
这是我的 2 个 React 组件——父和子
class ParentComponent extends Component{
render(){
/* consultations comes from redux store
and looks like { consultation_id:123, date:10/12/2013 } */
return(
_.map(this.props.consultations,(consultation)=>{
return{
<ChildComponent consultation={consultation} />
}
})
);
}
}
class ChildComponent extends Component{
render(){
return(
<div>this.props.consultation.date</div>
);
}
}
我的问题是我有某些修改咨询对象的操作。 例如:父组件中的props.consultation.date发生了变化,但是子组件不会重新渲染以显示最新的咨询日期。
但是,我注意到,如果我将咨询对象中的每个项目发送到像<ChildComponent date={this.props.consultation.date} />
这样的子组件,它会在日期更改时<ChildComponent date={this.props.consultation.date} />
!
知道为什么当作为对象发送的道具发生变化时,React 不会重新渲染组件吗?
我总是可以解决这个问题,但想知道这是一个错误还是我遗漏了什么?
您应该明确地将带有consultation_id的key prop 添加到子元素中。 React 在没有 key prop 的情况下重新渲染元素可能会出现问题!
解决办法是将consultation={consultation}
改为consultation={...consultation}.
我仍然不确定为什么,但它有效!
当您映射一组项目时,您需要向每个项目传递一个唯一的key
属性。 这表示对哪个元素是哪个做出反应。
...
_.map(this.props.consultations, consultation => {
return (
<ChildComponent
key={consultation.id}
consultation={consultation}
/>
)
})
您指定的详细信息表示您更改了父组件中相同对象的日期~咨询,并且您的父组件正在获取数据作为道具。 现在,如果您改变相同的咨询对象,它不会使组件重新渲染。
consultation.date = /* some other date */;
它不会重新渲染组件。
但是,如果您更改对象的引用,例如:
newConsulationData = { ...consultation }
newConsultationData.date = /* some other date */;
它会工作得很好。
在您的场景中,当您直接改变 props 数组对象并传递相同的数组时,您可能会遇到问题,因此我建议您更改咨询数组的引用:您需要
newConsulations = [ ...consultations ];
newConsultations[index of consultation].date = /* some other date */;
这应该可以解决您的问题。 在使用 react 时,如果您想在更改上重新渲染组件,请尽量不要改变对象。
我认为这可能与数据类型有关。
第一种方法是将Object
传递给子组件,
<ChildComponent consultation={consultation} />
第二种方法是将String
传递给子组件。
<ChildComponent date={this.props.consultation.date} />
当对象consultation
的属性date
改变时,对象的索引不会改变。 我认为 react 是通过索引引用一个对象。 对象返回一个索引而不是确切的值。 索引是对象在内存中存储的具体地址。 但是字符串或布尔值或数字直接返回值。
我认为 react 是按索引比较对象,并按值比较字符串。 在第一种方法中,索引不会更新,因此不会发生重新渲染。
第三种方法使用扩展符号提取对象属性。
<ChildComponent consultation={...consultation} />
我认为 react 在这种方法中引用了属性本身,因为每个属性都被提取出来。 它不再引用对象,因此重新渲染工作。
(我这里用了一些I think
说法,因为这只是我的猜测。还需要官方文件来支持。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.