繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM