javascript - 在 React.js 中触发子项重新渲染

标签 javascript reactjs

父组件(在我的示例中为 MyList)组件通过子组件(MyComponent)呈现数组。 Parent 决定更改数组中的属性,React 触发 child 重新渲染的方式是什么?

我想出的只是 this.setState({}); 在调整数据后在 Parent 中。这是触发更新的 hack 方式还是 React 方式?

JS fiddle : https://jsfiddle.net/69z2wepo/7601/

var items = [
  {id: 1, highlighted: false, text: "item1"},
  {id: 2, highlighted: true, text: "item2"},
  {id: 3, highlighted: false, text: "item3"},
];

var MyComponent = React.createClass({
  render: function() {
    return <div className={this.props.highlighted ? 'light-it-up' : ''}>{this.props.text}</div>;
  }
});

var MyList = React.createClass({
  toggleHighlight: function() {
    this.props.items.forEach(function(v){
      v.highlighted = !v.highlighted;
    });

    // Children must re-render
    // IS THIS CORRECT?
    this.setState({});
  },

  render: function() {
    return <div>
      <button onClick={this.toggleHighlight}>Toggle highlight</button>
      {this.props.items.map(function(item) {
          return <MyComponent key={item.id} text={item.text} highlighted={item.highlighted}/>;
      })}
    </div>;
  }
});

React.render(<MyList items={items}/>, document.getElementById('container'));

最佳答案

这里的问题是您将状态存储在 this.props 而不是 this.state 中。由于此组件正在改变 items,因此 items 是状态并且应该存储在 this.state 中。 (这里是 good article on props vs. state。)这解决了您的渲染问题,因为当您更新 items 时,您将调用 setState,这将自动触发重新渲染。

下面是你的组件使用 state 而不是 props 时的样子:

var MyList = React.createClass({
    getInitialState: function() {
        return { items: this.props.initialItems };
    },

    toggleHighlight: function() {
        var newItems = this.state.items.map(function (item) {
            item.highlighted = !item.highlighted;
            return item;
        });

        this.setState({ items: newItems });
    },

    render: function() {
        return (
            <div>
                <button onClick={this.toggleHighlight}>Toggle highlight</button>
                { this.state.items.map(function(item) {
                    return <MyComponent key={item.id} text={item.text} 
                             highlighted={item.highlighted}/>;
                }) }
            </div>
        );    
    }
});

React.render( <MyList initialItems={initialItems}/>,
              document.getElementById('container') );

请注意,我将 items 属性重命名为 initialItems,因为它清楚地表明 MyList 会改变它。这是 recommended by the documentation .

你可以在这里看到更新的 fiddle :https://jsfiddle.net/kxrf5329/

关于javascript - 在 React.js 中触发子项重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30034265/

相关文章:

javascript - 当使用不同 Prop 渲染组件的多个实例时,关键帧动画不起作用?用于动画的宽度取决于 Prop 值

javascript - MVC 5 View - 设置 Javascript 变量

受 iPhone UITableView 启发的 Javascript 小部件?

javascript - 准备学习html5

javascript - 如何在 ReactJS 中正确搜索列表

javascript - React 与 dom 交互

javascript - 如何将匿名函数传递给 Jquery 的点击处理程序

javascript - AWS - 对预检请求的响应未通过访问控制检查 : No 'Access-Control-Allow-Origin' header is present on the requested resource

javascript - 如何在 ReactJS 中没有任何给定事件的情况下更新 UI

javascript - React.js - 如何停止 setInterval 并在单击后恢复它