道具更改时,React组件不会重新渲染

时间:2018-12-21 10:50:23

标签: javascript reactjs

这是我的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不重新渲染组件吗?

我总是可以解决问题,但想知道这是一个错误还是我错过了什么?

4 个答案:

答案 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语句,这只是我的猜测。仍然需要官方文档来支持。)