React:为什么组件的构造函数只被调用一次? [英] React: Why component's constructor is called only once?

查看:158
本文介绍了React:为什么组件的构造函数只被调用一次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下示例中,当点击Item 2时,第二个1 代替 Second 2 显示.为什么?你会如何解决这个问题?

<小时>

var guid = 0;class Content 扩展了 React.Component {构造函数(){指导 += 1;this.id = guid;console.log('ctor', this.id);//只用 1 调用一次}使成为() {返回 (<div className="内容">{this.props.title} - {this.id}

);}}class MyApp 扩展了 React.Component {构造函数(){this.items = ['Item 1', 'Item 2'];this.state = {活动项目:this.items[0]};}onItemClick(项目){this.setState({活动项目:项目});}渲染菜单(){返回 (<div className="菜单"><div onClick={this.onItemClick.bind(this, 'Item 1')}>Item 1</div><div onClick={this.onItemClick.bind(this, 'Item 2')}>Item 2</div>

);}渲染内容(){if (this.state.activeItem === 'Item 1') {返回 (<内容标题=第一"/>);} 别的 {返回 (<内容标题=第二个"/>);}}使成为() {返回 (<div>{this.renderMenu()}{this.renderContent()}

);}}

解决方案

React 的 reconciliation algorithm 假设在没有任何相反信息的情况下,如果自定义组件在后续渲染中出现在同一位置,则它与之前的组件相同,因此会重用前一个实例而不是创建一个新实例.

如果你要实现 componentWillReceiveProps(nextProps),你会看到它被调用了.

<块引用>

不同的节点类型

元素不太可能生成与 类似的 DOM.React 不会花时间尝试匹配这两个结构,而是从头开始重新构建树.

作为一个推论,如果在两个连续渲染中的同一位置有一个

元素,您会期望看到一个非常相似的结构,值得探索.>

自定义组件

我们决定这两个自定义组件是相同的.由于组件是有状态的,我们不能仅仅使用新组件并称其为一天.React 从新组件中获取所有属性,并在前一个组件上调用 component[Will/Did]ReceiveProps().

之前的组件现在可以运行了.它的 render() 方法被调用,diff 算法以新的结果和之前的结果重新开始.

如果你给每个组件 一个唯一的 key 道具,React 可以使用 key 更改来推断该组件实际上已被替换,并会从头开始创建一个新组件,从而赋予它完整的组件生命周期.


 renderContent() {if (this.state.activeItem === 'Item 1') {返回 (<内容标题=第一"键=第一"/>);} 别的 {返回 (<内容标题=第二个"键=第二"/>);}}

In the following example, when Item 2 is clicked, Second 1 is shown instead of Second 2. Why? How would you fix that?


var guid = 0;

class Content extends React.Component {
  constructor() {
    guid += 1;
    this.id = guid;
    console.log('ctor', this.id); // called only once with 1
  }
  render() {
    return (
      <div className="content">
        {this.props.title} - {this.id}
      </div>
    );
  }
}

class MyApp extends React.Component {
  constructor() {
    this.items = ['Item 1', 'Item 2'];
    this.state = {
      activeItem: this.items[0]
    };
  }
  onItemClick(item) {
    this.setState({
      activeItem: item
    });
  }
  renderMenu() {
    return (
      <div className="menu">
        <div onClick={this.onItemClick.bind(this, 'Item 1')}>Item 1</div>
        <div onClick={this.onItemClick.bind(this, 'Item 2')}>Item 2</div>
      </div>
    );
  }
  renderContent() {
    if (this.state.activeItem === 'Item 1') {
      return (
        <Content title="First" />
      );
    } else {
      return (
        <Content title="Second" />
      );
    }
  }
  render() {
    return (
      <div>
        {this.renderMenu()}
        {this.renderContent()}
      </div>
    );
  }
}

解决方案

React's reconciliation algorithm assumes that without any information to the contrary, if a custom component appears in the same place on subsequent renders, it's the same component as before, so reuses the previous instance rather than creating a new one.

If you were to implement componentWillReceiveProps(nextProps), you would see that getting called instead.

Different Node Types

It is very unlikely that a <Header> element is going to generate a DOM that is going to look like what a <Content> would generate. Instead of spending time trying to match those two structures, React just re-builds the tree from scratch.

As a corollary, if there is a <Header> element at the same position in two consecutive renders, you would expect to see a very similar structure and it is worth exploring it.

Custom Components

We decided that the two custom components are the same. Since components are stateful, we cannot just use the new component and call it a day. React takes all the attributes from the new component and calls component[Will/Did]ReceiveProps() on the previous one.

The previous component is now operational. Its render() method is called and the diff algorithm restarts with the new result and the previous result.

If you give each component a unique key prop, React can use the key change to infer that the component has actually been substituted and will create a new one from scratch, giving it the full component lifecycle.


  renderContent() {
    if (this.state.activeItem === 'Item 1') {
      return (
        <Content title="First" key="first" />
      );
    } else {
      return (
        <Content title="Second" key="second" />
      );
    }
  }

这篇关于React:为什么组件的构造函数只被调用一次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆