React.js和大表

时间:2015-09-11 19:34:52

标签: javascript reactjs

我需要绘制一张大表,不是很大,大约400x400的单元格。但React渲染速度太慢,并且每次单击该单元格时,都应该更新单元格并且此更新需要相同的时间。有什么建议如何加快它?或者React不适合这样的任务?

以下是示例(表的大小略有缩小): https://jsfiddle.net/69z2wepo/15731/

var ROWSC = 400;
var COLSC = 100;

var Hello = React.createClass({
    getInitialState: function () {
        return {
            t: { "1-1": 'c' }
        };
    },
    clicked: function (k) {
        var t = this.state.t;
        t[k] = t[k] ? 0 : 'c';
        this.setState({  t: t  });
    },
    render: function() {
        var items = [];
        for (var r = 0; r < ROWSC; r++) {
            var cols = [];
            for (var c = 0; c < COLSC; c++) {
                var k  = ''+r+'-'+c;
                cols.push(<td key={c} onClick={this.clicked.bind(this,k)} className={this.state.t[k]}>&nbsp;</td>);
            }
            items.push(<tr key={r}>{cols}</tr>);
        }
        return <table>
            {items}
            </table>
        </div>;
    }
});

React.render(<Hello name="World" />, document.getElementById('container'));

3 个答案:

答案 0 :(得分:2)

默认情况下,React会重新呈现所有内容,但在出现性能问题时, 可以使用shouldComponentUpdate函数来确定哪些部分 要在更新时排除的组件树。

在您的示例中,只有一行可以一次更新,所以 如果我们开始跟踪更新发生的行,我们只能确定 此行已更新。首先,我们必须引入一个新的组件来包装 表格行我们可以放置我们的钩子。

var Row = React.createClass({
    shouldComponentUpdate: function(nextProps) {
        return nextProps.mustUpdate;
    },
    render: function() {
        return <tr>{this.props.children}</tr>;
    }
});

然后我们可以像

一样使用它
items.push(
   <Row key={r}
        mustUpdate={this.state.lastUpdatedRow === r}>
        {cols}
   </Row>);

此外,重新渲染所有这些细胞似乎也是浪费,所以我们可以介绍一下 另一个包装表格单元格的组件。

var Cell = React.createClass({
    shouldComponentUpdate: function(nextProps) {
        return this.props.selected !== nextProps.selected;
    },
    render: function() {
        var props = this.props;
        return (
            <td onClick={props.onClick.bind(null, props.col, props.row)} 
                className={props.selected ? 'c' : ''}>&nbsp;
            </td>
        );
    }
});

这可以让您在更新时获得显着的性能提升。如果还没有 对于您的特定问题已经足够好了,可能是React不适合您的用例。 无论如何,这是优化React程序的本质,您将组件拆分为更小 组件并确保只有实际更改的部分更新。

答案 1 :(得分:0)

当我在控制台中查看您的结果时,我注意到每个jsfiddle运行时都会弹出以下内容:

You are using the in-browser JSX transformer. Be sure to precompile your JSX for production - http://facebook.github.io/react/docs/tooling-integration.html#jsx

我按照链接看到文档在使用浏览器内JSX转换器时警告性能影响:

The in-browser JSX transformer is fairly large and results in extraneous computation client-side that can be avoided. Do not use it in production

也许用JSX预编译进行另一个测试会让你更好地了解这是否是React的一个很好的用例。

答案 2 :(得分:0)

两件事:

确保预编译JSX以避免这种缓慢。 (在jsfiddle中,您将看到一个控制台警告“您正在使用浏览器内的JSX转换器。请务必预编译您的JSX以进行生产”。

作为单个组件实现,其自身具有单击设置状态,导致组件必须重新处理整个表(因为setState触发重建表DOM的render。您可以通过创建表示每个表格单元格的组件来避免这种情况。然后在clicked函数中,不要在Hello上调用setState,只需在单击的单元格上调用setState即可。这样只有改变的单元格才会重新渲染。

这对初始渲染没有帮助,但它会显着加快因点击而导致的UI更新。