当前位置: 首页 > 知识库问答 >
问题:

防止所有子级重新呈现setState的每个调用

吕和风
2023-03-14

例如,当呈现表中的长元素列表时,对setstate的任何调用,无论是否更改表用于枚举的数据,都会导致重新呈现每个子对象。

class App extends React.Component {
  constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
    const rows = Array.from({ length: 200 }, (v, k) => k + 1).map(i => ({
      id: i,
      field1: "hello",
      field2: "cruel",
      field3: "world"
    }));

    this.state = {
      selectedIds: [],
      rows
    };
  }

  onChange(e) {
    const name = e.target.name;
    const checked = e.target.checked;
    const selectedIds = [...this.state.selectedIds];
    if (!checked) {
      const index = selectedIds.findIndex(x => x === name);
      selectedIds.splice(index, 1);
    } else {
      selectedIds.push(name);
    }
    this.setState(state => ({ selectedIds }));
  }

  render() {
    const { rows, selectedIds } = this.state;
    return (
      <div className="App">
        <h5>{selectedIds.length} Rows Selected</h5>
        <table>
          <thead>
            <tr>
              <td>Select</td>
            </tr>
            <tr>
              <td>Field 1</td>
            </tr>
            <tr>
              <td>Field 2</td>
            </tr>
            <tr>
              <td>Field 3</td>
            </tr>
          </thead>
          <tbody>
            {rows.map(row => {
              console.log(row);
              return (
                <tr key={row.id}>
                  <td>
                    <input
                      type="checkbox"
                      onChange={this.onChange}
                      name={row.id}
                    />
                  </td>
                  <td>
                    <div>{row.field1}</div>
                  </td>
                  <td>
                    <div>{row.field2}</div>
                  </td>
                  <td>
                    <div>{row.field3}</div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    );
  }
}

但是如果是这样的话,当那个链接里的元素数增加到说4000的时候,为什么点击的时候会有这么多的减速呢?当使用稍微复杂一些的自定义React组件时,只使用200个项目时,会注意到显着的减速。

共有1个答案

高飞翮
2023-03-14

要解决这个问题,您需要为行项创建一个附加组件。这样,它将有一个单独的render函数,而不是rerender本身,因为行组件没有改变,只有表组件。

{rows.map(row => {
    return (
        <RowItem row={row} onChange={this.onChange}>
    );      
}}

您的新组件将如下所示:

class RowItem extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
        <tr key={this.props.row.id}>
          <td>
            <input
              type="checkbox"
              onChange={this.props.onChange}
              name={this.props.row.id}
            />
          </td>
          <td>
            <div>{this.props.row.field1}</div>
          </td>
          <td>
            <div>{this.props.row.field2}</div>
          </td>
          <td>
            <div>{this.props.row.field3}</div>
          </td>
        </tr>
    );
  }  
}
 类似资料:
  • 我有一些多个状态和函数来设置使用useState钩子的状态。 在每个setstate组件上重新渲染。我只想重新渲染完全完成的setstate函数。 例如: 应用程序内。js ); 在每个函数1和函数2上setA和setB返回语句重新呈现元素。我不想在每个setA,setB,setC等重新渲染。一旦函数1或函数2完全完成,只需要重新渲染组件。我对钩子不熟悉,有人能帮忙吗?

  • 我有一个页面,有一个子组件用于浏览按钮,在父组件上,通过回调我用浏览文件设置状态。

  • 我从这里修改了以下组件定义,如下所示。但是,与示例不同的是,每次在组件上移动鼠标时,组件都会重新呈现。 重新渲染非常引人注目: 有人知道为什么会这样吗?

  • 我正在学习React钩子,这意味着我将不得不从类转移到函数组件。以前,在类中,我可以拥有与状态无关的类变量,我可以在不重新呈现组件的情况下更新这些变量。现在我试图用钩子重新创建一个组件作为函数组件,我遇到了这样一个问题:我不能(就我所知)为该函数创建变量,因此存储数据的唯一方法是通过钩子。然而,这意味着每当该状态更新时,我的组件将重新呈现。 我已经在下面的示例中说明了这一点,我试图将类组件重新创建

  • 我猜这可能与从父级打开有关,但我有其他组件,它们内部的状态发生变化,所以我有点困惑,为什么这个组件不尊重它的新状态。 谢谢