React 不会重新渲染
React does not re-render
我有带排序功能 (List) 的 React class 和用于简单元素 (Elem) 的 React class。如果启动了排序功能,它会对状态数组中的元素进行排序并重新呈现列表,但保持不变,尽管状态数组已更改。代码:
var Elem = React.createClass({
getInitialState() {
var elem_name = this.props.name;
return {
name: elem_name
}
},
render() {
return <div>{this.state.name}</div>;
}
});
var List = React.createClass({
getInitialState() {
return {
received: false,
arr: null
}
},
receiving() {
this.setState({
received: true,
arr: [1, 2, 3, 4, 5]
});
},
sorting(type) {
var self = this;
return function() {
function sort_func() {
//sorting...
}
var main_arr = self.state.arr;
main_arr.sort(sort_func);
self.setState({
arr: main_arr
})
}
},
render() {
if(this.state.received) {
var all_elems = [];
this.state.arr.forEach(function(elem) {
all_elems.push(<Elem name={elem}>);
});
return <div>
<button onClick={this.sorting}>Sort</button>
{all_elem}
</div>
}
else {
this.receiving();
return <div>Empty</div>;
}
}
});
例如排序后的数组为[5, 4, 3, 2, 1]。首先HTML页是
<div>1</div><div>2</div>...<div>5</div>;
但是排序后 HTML 页面保持不变,尽管数组状态发生了变化。
我已经重构了你的代码,因为在你的版本中有几个错误
- 在
Elem
中你不需要使用 state
,
- 您可以在
getInitialState
中将初始数据添加到 arr
而不是使用 this.receiving();
并避免在 render
中使用 if
/else
方法
- 而不是使用
this.state.arr.forEach
更适合使用`.map
而不是 var self = this;
使用 arrow functions
var Elem = React.createClass({
render() {
return <div>{ this.props.name }</div>;
}
});
var List = React.createClass({
getInitialState() {
return {
received: false,
arr: [1, 2, 3, 4, 5]
}
},
sorting(type) {
this.setState({
received: !this.state.received,
arr: this.state.arr.sort((a, b) => {
return !this.state.received ? b - a : a - b;
})
})
},
render() {
var elements = this.state.arr.map((elem, index) => {
return <Elem name={elem} key={index} />
});
return <div>
<button onClick={this.sorting}>Sort</button>
{ elements }
</div>;
}
});
我有带排序功能 (List) 的 React class 和用于简单元素 (Elem) 的 React class。如果启动了排序功能,它会对状态数组中的元素进行排序并重新呈现列表,但保持不变,尽管状态数组已更改。代码:
var Elem = React.createClass({
getInitialState() {
var elem_name = this.props.name;
return {
name: elem_name
}
},
render() {
return <div>{this.state.name}</div>;
}
});
var List = React.createClass({
getInitialState() {
return {
received: false,
arr: null
}
},
receiving() {
this.setState({
received: true,
arr: [1, 2, 3, 4, 5]
});
},
sorting(type) {
var self = this;
return function() {
function sort_func() {
//sorting...
}
var main_arr = self.state.arr;
main_arr.sort(sort_func);
self.setState({
arr: main_arr
})
}
},
render() {
if(this.state.received) {
var all_elems = [];
this.state.arr.forEach(function(elem) {
all_elems.push(<Elem name={elem}>);
});
return <div>
<button onClick={this.sorting}>Sort</button>
{all_elem}
</div>
}
else {
this.receiving();
return <div>Empty</div>;
}
}
});
例如排序后的数组为[5, 4, 3, 2, 1]。首先HTML页是
<div>1</div><div>2</div>...<div>5</div>;
但是排序后 HTML 页面保持不变,尽管数组状态发生了变化。
我已经重构了你的代码,因为在你的版本中有几个错误
- 在
Elem
中你不需要使用state
, - 您可以在
getInitialState
中将初始数据添加到arr
而不是使用this.receiving();
并避免在render
中使用if
/else
方法 - 而不是使用
this.state.arr.forEach
更适合使用`.map 而不是
var self = this;
使用 arrow functionsvar Elem = React.createClass({ render() { return <div>{ this.props.name }</div>; } }); var List = React.createClass({ getInitialState() { return { received: false, arr: [1, 2, 3, 4, 5] } }, sorting(type) { this.setState({ received: !this.state.received, arr: this.state.arr.sort((a, b) => { return !this.state.received ? b - a : a - b; }) }) }, render() { var elements = this.state.arr.map((elem, index) => { return <Elem name={elem} key={index} /> }); return <div> <button onClick={this.sorting}>Sort</button> { elements } </div>; } });