在React.js中触发子重新渲染 [英] Trigger child re-rendering in React.js
问题描述
Parent(我的示例中为 MyList
)组件通过Child( MyComponent
)组件呈现数组。 Parent决定更改数组中的属性,React触发子重新渲染的方式是什么?
The Parent (MyList
in 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?
我想出的只是 this.setState在调整数据后,在Parent中的({});
。这是一种触发更新的黑客还是反应方式?
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?
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'));
推荐答案
这里的问题是你要存储状态 this.props
而不是 this.state
。由于此组件正在变异项目
,项目
是状态,应存储在 this.state中
。 (这是关于道具与状态的好文章。)这解决了你的渲染问题,因为当你更新 items
时,你将调用 setState
,这将自动触发重新渲染。
The problem here is that you're storing state in this.props
instead of this.state
. Since this component is mutating items
, items
is 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 items
you'll call setState
, which will automatically trigger a re-render.
这是你的组件使用状态而不是道具的样子:
Here's what your component would look like using state instead of 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
prop重命名为 initialItems
,因为它清楚地表明 MyList
会改变它。这是文档推荐。
Note that I renamed the items
prop to initialItems
, because it makes it clear that MyList
will mutate it. This is recommended by the documentation.
您可以在此处查看更新的小提琴: https://jsfiddle.net/kxrf5329/
You can see the updated fiddle here: https://jsfiddle.net/kxrf5329/
这篇关于在React.js中触发子重新渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!