following example中,单击Item 2时,显示Second 1而不是Second 2.为什么?你会怎么解决这个问题?


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假设在没有任何相反信息的情况下,如果一个自定义组件出现在后续渲染的同一位置,则它与之前是同一个组件,因此重用以前的实例,而不是创建新实例.

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

不同的 node 类型

<Header>元素不太可能生成与<Content>元素类似的DOM.与其花时间try 匹配这两种 struct ,不如从头开始重新构建树.

作为推论,如果在两个连续的渲染中,有<Header>个元素位于同一位置,那么你会看到一个非常相似的 struct ,这是值得探索的.

自定义组件

我们决定这两个自定义组件是相同的.因为组件是有状态的,所以我们不能只使用新组件,就到此为止.React从新组件获取所有属性,并对前一个组件调用component[Will/Did]ReceiveProps().

之前的组件现在可以运行了.调用其render()方法,然后使用新结果和以前的结果重新启动diff算法.

如果给每个组件a unique key prop,React可以使用key更改来推断该组件实际上已被替换,并将从头创建一个新组件,从而为其提供完整的组件生命周期.


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

Reactjs相关问答推荐

如果Next JS中使用await,monaco-editor将继续加载

有正确的方法来设置我的金牛座应用程序的图标吗?

Npm运行构建`在Next.js 14中不起作用

在Reaction+Redux+RTKQuery中对API调用进行排序

有没有一种惯用的方式来接受特定的子元素?

FireBase Reaction Native-在呈现视图之前等待响应

Mantine DatePickerInput呈现错误

我如何在不被 destruct 的情况下将导航栏固定在顶部?

Symfony ux-react:使用react_component()时React组件不会渲染

如何管理可重用无线电输入的 React 状态?

解决在React测试库中的act()警告

无法设置 null 的属性(设置src)

当每个元素都可拖动时,移动设备上的滚动列表出现问题

导入样式化组件时未导入组件内容

如何使用 React Hook Form 将寄存器作为 props 发送到子组件来收集数据?

有没有办法根据 Rechart 中的 activeDot 更改值?

不能在我的代码中使用 .给我一个警告!有人知道解决方案吗?

react-markdown 不渲染 Markdown

React 检测哪些 props 在 useEffect 触发器上发生了变化

在状态中存储多个选定的选项