javascript - ReactJS 可检查列表问题

标签 javascript performance reactjs

我正在尝试创建包含一个长列表(约 500 个项目)的 React 组件,每个项目旁边都有复选框。它应该切换每个项目的检查状态并切换列表中所有项目的检查状态。据我所知,我实现了该组件。但我的解决方案性能较低,并且在切换复选框时存在一些时间滞后。当我将其集成到页面中时,它的工作速度比这个 jsFiddle 示例慢。

jsFiddle

我做错了什么?我应该选择其他方式来处理项目数据吗?

var Hello = React.createClass({
  getInitialState: function () {
    var db = [];
    for (var i = 0, l = 100; i < l; i++) {
      db.push({
        name: Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5),
        value: i
      });
    }
    return {
      db: db
    };
  },
  checkAll: function (ev) {
    var items = this.state.db.slice();
    items.forEach(function (v) {
      v.checked = ev.target.checked;
    });
    this.setState({db: items});

  },
  handleCheck: function (ev) {
    debugger;
    var id = ev.target.dataset.id;
    var items = this.state.db.slice();
    var item = items.filter(function (v) {
      return v.value == id;
    })[0];
    item.checked = ev.target.checked;
    console.log(items.filter(function (v) {
      return v.checked;
    }));
    this.state({db: items});

  },
  render: function () {
    return <div>
      <table>
        <thead>
        <tr>
          <th>Name</th>
          <th>Value</th>
          <th>
            <input type="checkbox" onChange={this.handleCheck} id="check-all"/>
            <label htmlFor="check-all">Check all</label>
          </th>
        </tr>
        </thead>
        <tbody> {
          this.state.db.map(function (v, i) {
            return (
                <tr key={i}>
                  <td>{v.name}</td>
                  <td>{v.value}</td>
                  <td>
                    <input id={'item-'+i} type="checkbox"
                           data-id={i}
                           onChange={this.handleCheck}
                           checked={v.checked}/>
                    <label htmlFor={'item-'+i}>Check this</label>
                  </td>
                </tr>
            );
          }.bind(this))
        }
        </tbody>
      </table>
    </div>;
  }
});

解决方案

我的表格中有许多具有复杂层次结构的单元格。当我切换复选框值时,所有单元格都会重新渲染,包括那些值未更改的单元格,这会导致巨大的时间延迟。我使用 shouldComponentUpdate 回调将组件拆分为一些小组件,效果很好。感谢大家的帮助!

最佳答案

我对您的代码做了一些改进:https://jsfiddle.net/Lfbodh90/1/

我改变了什么:

在事件处理程序中,您可以通过索引获取项目,从而大大加快查找时间:

handleCheck: function (id) {
  var items = this.state.db;
  var item = items[id]
  item.checked = ev.target.checked;
  this.setState({db: items});
}

另一件事:创建复选框时,可以直接传递索引参数,使用bind:

<input id={'item-'+i} type="checkbox"
                      onChange={this.handleCheck.bind(this, i)}
                      checked={v.checked}/>
<label htmlFor={'item-'+i}>Check this</label>

我还删除了给定示例中不需要的 slice 调用。

我增加了上面 JSFiddle 上的项目数量只是为了测试。现在,当您选中/取消选中特定复选框时,速度非常快。

希望这有帮助

关于javascript - ReactJS 可检查列表问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32199366/

相关文章:

javascript - 如何在 JavaScript 中检测 macOS Big Sur 和/或 Monterey?

javascript - 我如何使用angularjs在ng-repeat中附加表数据值

c# - 如何在 C# 中处理非规范化 float ?

javascript - 将 process.env 变量从 Node 传递或使用到 reactjs

javascript - 替换 html 标签内的单词

javascript - 目录未创建

javascript - 我们如何使用 React Hooks 实现 componentWillUnmount?

python - 大于阈值的元素的 numpy.argmin

javascript - JavaScript 中的 IndexOf 方法是否比遍历数组更有效?

node.js - 我不知道在更新用户信息的情况下如何决定REST API上的API路径