Javascript 在 React.js 中触发子重新渲染
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/30034265/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Trigger child re-rendering in React.js
提问by Djam
The Parent (MyListin my example) component renders an array thru a Child (MyComponent) component. Parent decides to change properties in the array, what is React way of triggering child re-rendering?
Parent(MyList在我的示例中)组件通过 Child ( MyComponent) 组件呈现一个数组。父级决定改变数组中的属性,React 触发子级重新渲染的方式是什么?
All I came up with is this.setState({});in Parent after tweaking the data. Is this a hack or a React way of triggering an update?
this.setState({});在调整数据后,我想出的所有内容都在 Parent 中。这是 hack 还是 React 触发更新的方式?
JS Fiddle: https://jsfiddle.net/69z2wepo/7601/
JS小提琴: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'));
采纳答案by Jordan Running
The problem here is that you're storing state in this.propsinstead of this.state. Since this component is mutating items, itemsis state and should be stored in this.state. (Here's a good article on props vs. state.) This solves your rendering problem, because when you update itemsyou'll call setState, which will automatically trigger a re-render.
这里的问题是您将状态存储在this.props而不是this.state. 由于此组件正在发生变化items,items因此处于状态并应存储在this.state. (这是一篇关于 props 与 state的好文章。)这解决了您的渲染问题,因为当您更新时,items您将调用setState,这将自动触发重新渲染。
Here's what your component would look like using state instead of props:
下面是你的组件使用 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') );
Note that I renamed the itemsprop to initialItems, because it makes it clear that MyListwill mutate it. This is recommended by the documentation.
请注意,我将itemsprop重命名为initialItems,因为它清楚地表明MyList会对其进行变异。这是文档推荐的。
You can see the updated fiddle here: https://jsfiddle.net/kxrf5329/
你可以在这里看到更新的小提琴:https: //jsfiddle.net/kxrf5329/
回答by Jeremy D
You should trigger a re-rendering by calling setState()and giving the new props you want to propagate down.
If you really want to force an update you can also call forceUpdate().
您应该通过调用setState()并提供要向下传播的新道具来触发重新渲染。如果你真的想强制更新,你也可以调用forceUpdate().
If you look at the examples on this page, you can see that setStateis the method used to update and trigger a re-rendering. The documentationis also stating (ahaha!) that clearly.
如果您查看此页面上的示例,您会发现这setState是用于更新和触发重新渲染的方法。该文件还指出(ahaha!)明确。
In your case I would call forceUpdate.
在你的情况下,我会打电话给forceUpdate.
EDIT: As Jordan mentioned in the comment, it would be better to store items as part of your state. That way you wouldn't have to call forceUpdatebut you would really update the state of your component, thus a regular setStatewith the updated values would work better.
编辑:正如 Jordan 在评论中提到的,最好将物品作为您所在州的一部分进行存储。这样你就不必调用,forceUpdate但你真的会更新你的组件的状态,因此setState具有更新值的常规会更好地工作。

