【问题标题】:How does ReactJS knows what exactly to re-render?ReactJS 如何知道要重新渲染的确切内容?
【发布时间】:2014-08-24 18:58:39
【问题描述】:

所以,我正在阅读 ReactJS Getting Started guide。我遇到了我修改过的this component (JSFiddle)

如您所见,当您更改 SearchBar 组件时,它会更改父 FilterableProductTable 的状态。然后调用父#render方法,重新创建SearchBar,再次调用SearchBar#render方法。

/** @jsx React.DOM */

var ProductCategoryRow = React.createClass({
    render: function() {
        return (<tr><th colSpan="2">{this.props.category}</th></tr>);
    }
});

var ProductRow = React.createClass({
    render: function() {
        var name = this.props.product.stocked ?
            this.props.product.name :
            <span style={{color: 'red'}}>
                {this.props.product.name}
            </span>;
        return (
            <tr>
                <td>{name}</td>
                <td>{this.props.product.price}</td>
            </tr>
        );
    }
});

var ProductTable = React.createClass({
    render: function() {
        console.log(this.props);
        var rows = [];
        var lastCategory = null;
        this.props.products.forEach(function(product) {
            if (product.name.indexOf(this.props.filterText) === -1 || (!product.stocked && this.props.inStockOnly)) {
                return;
            }
            if (product.category !== lastCategory) {
                rows.push(<ProductCategoryRow category={product.category} key={product.category} />);
            }
            rows.push(<ProductRow product={product} key={product.name} />);
            lastCategory = product.category;
        }.bind(this));
        return (
            <table>
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Price</th>
                    </tr>
                </thead>
                <tbody>{rows}</tbody>
            </table>
        );
    }
});

var SearchBar = React.createClass({
    handleChange: function() {
        this.props.onUserInput(
            this.refs.filterTextInput.getDOMNode().value,
            this.refs.inStockOnlyInput.getDOMNode().checked
        );
    },
    render: function() {
        console.log('This SearchBar#render is being called every time the state changes!');
        return (
            <form>
                <input
                    type="text"
                    placeholder="Search..."
                    value={this.props.filterText}
                    ref="filterTextInput"
                    onChange={this.handleChange}
                /><span data-something={this.props.filterText}>Edit this text manually with the DOM inspector. Type something on the text box. Look that the data-something property is re-rendered, but this text is kept the same</span>
                <p>
                    <input
                        type="checkbox"
                        value={this.props.inStockOnly}
                        ref="inStockOnlyInput"
                        onChange={this.handleChange}
                    />
                    Only show products in stock
                </p>
            </form>
        );
    }
});

var FilterableProductTable = React.createClass({
    getInitialState: function() {
        return {
            filterText: '',
            inStockOnly: false
        };
    },

    handleUserInput: function(filterText, inStockOnly) {
        this.setState({
            filterText: filterText,
            inStockOnly: inStockOnly
        });
    },

    render: function() {
        return (
            <div>
                <SearchBar
                    filterText={this.state.filterText}
                    inStockOnly={this.state.inStockOnly}
                    onUserInput={this.handleUserInput}
                />
                <ProductTable
                    products={this.props.products}
                    filterText={this.state.filterText}
                    inStockOnly={this.state.inStockOnly}
                />
            </div>
        );
    }
});


var PRODUCTS = [
  {category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'},
  {category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'},
  {category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'},
  {category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'},
  {category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'},
  {category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'}
];

React.renderComponent(<FilterableProductTable products={PRODUCTS} />, document.body);

但是。如果我通过浏览器检查器手动编辑 SearchBar 组件的 DOM,当我在文本框中键入内容时,会呈现 SearchBar(您可以看到 DOM 上的 data-something 属性更改),但手动修改的 DOM 不会t 改变,所以这意味着它实际上并没有渲染所有东西,只是改变了的东西。

那么,它是如何做到的呢?它在幕后进行脏检查吗? HTML 上的差异?

【问题讨论】:

    标签: rendering reactjs


    【解决方案1】:

    我找到了答案。 ReactJS 使用Diff algorithm with the virtual DOM,它显然足够快速和智能。它还允许您在组件上设置 shouldComponentUpdate 方法,告诉它它不应该在某些条件下重新渲染。

    【讨论】:

      猜你喜欢
      • 2017-07-21
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      • 1970-01-01
      • 2023-04-11
      • 2016-09-09
      • 2020-06-20
      相关资源
      最近更新 更多