这是我的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} />
之类的子组件,它都会在日期更改时重新呈现!
有人知道为什么当作为对象发送的道具发生更改时,React不重新渲染组件吗?
我总是可以解决问题,但想知道这是一个错误还是我错过了什么?
答案 0 :(得分:2)
您应该明确地将带有 consultation_id 的关键道具添加到子元素。在没有关键道具的情况下,React可能会出现重新渲染元素的问题!
答案 1 :(得分:1)
解决方案是将consultation={consultation}
更改为consultation={...consultation}.
,我仍然不确定为什么,但是可以!
答案 2 :(得分:0)
您指定的详细信息说,您更改了上级组件中同一对象的咨询日期,并且上级组件正在获取数据作为道具。 现在,如果您更改相同的咨询对象,则不会重新渲染组件。
consultation.date = /* some other date */;
它不会重新渲染组件。
但是,如果您更改对象的引用,例如:
newConsulationData = { ...consultation }
newConsultationData.date = /* some other date */;
它将正常工作。
在您的场景中,直接更改props数组对象并传递相同的数组可能会遇到麻烦,因此我建议您更改咨询数组的引用: 您需要
newConsulations = [ ...consultations ];
newConsultations[index of consultation].date = /* some other date */;
这应该可以解决您的问题。 在使用react时,如果要在更改时重新呈现组件,请尝试不要使对象变异。
答案 3 :(得分:0)
我认为这可能与数据类型有关。
第一种方法是将Object
传递给子组件,
<ChildComponent consultation={consultation} />
第二种方法是将String
传递给子组件。
<ChildComponent date={this.props.consultation.date} />
更改对象date
的属性consultation
时,对象的索引不变。我认为react正在通过其索引引用对象。对象返回的索引不是精确值。索引是对象在内存中存储的特定地址。但是,字符串,布尔值或数字将直接返回该值。
我认为react是按索引比较对象,并按值比较字符串。在第一种方法中,索引不会更新,因此不会进行重新渲染。
第三种方法使用扩展符号提取对象属性。
<ChildComponent consultation={...consultation} />
我认为react是在这种方法中引用属性本身,因为每个属性都被提取。它不再引用该对象,因此可以重新渲染。
(我在这里使用了一些I think
语句,这只是我的猜测。仍然需要官方文档来支持。)