3 回答
TA贡献1848条经验 获得超10个赞
您需要使用带有回调函数的 setState 来进行数据处理并为您设置新状态。
这是您案例的转换版本:
onSortChange = index => {
const sortMap = {
default: 'up',
up: 'down',
down: 'default',
};
this.setState(({ rows, currentIndex, currentSort }) => {
const nextSort = currentIndex === index ? sortMap[currentSort] : 'default';
const newRows = [...rows];
switch (nextSort) {
case 'up':
newRows.sort((a, b) => (a.cells[index] <= b.cells[index] ? -1 : 1));
break;
case 'down':
newRows.sort((a, b) => (b.cells[index] <= a.cells[index] ? -1 : 1));
break;
default: break;
}
return {
rows: newRows,
currentSort: nextSort,
currentIndex: index,
};
});
}
TA贡献1934条经验 获得超2个赞
再见,你可以尝试这样的方法:
orderRows = (data, index, nextSort) => {
switch (nextSort) {
case 'up':
data.sort((a, b) => (a.cells[index] <= b.cells[index] ? -1 : 1));
break;
case 'down':
data.sort((a, b) => (b.cells[index] <= a.cells[index] ? -1 : 1));
break;
}
return data;
}
onSortChange = index => {
const sortMap = {
default: 'up',
up: 'down',
down: 'default',
};
const { currentSort, currentIndex } = this.state;
const nextSort = currentIndex === index ? sortMap[currentSort] : 'default';
this.setState((prevState) => ({
rows: this.orderRows(prevState.rows, index, nextSort),
currentSort: nextSort,
currentIndex: index,
}));
};
TA贡献1862条经验 获得超6个赞
将道具分配给状态并从那里使用它们是一种 React 反模式(您可以在此处阅读更多相关信息)。
当您尝试实现的场景需要时,推荐的方法是创建一个完全受控的组件,或者在这种情况下,一个部分受控的组件,其中不仅rows从道具中使用,而且对它们的任何转换也通过道具(在本例中为排序)。
下面的代码片段演示了手头问题的简化版本。我们创建一个Parent存储rows其状态的组件,并提供一个执行排序的方法。然后它呈现一个完全受控的Child组件,该组件不需要有自己的状态,而是接收行及其排序器函数作为 props。
该sortRows方法说明了如何使用setState回调,与提供状态对象相比,回调提供了在状态上产生更一致的结果的好处。
class Child extends React.PureComponent {
render() {
const { rows, sortRows } = this.props;
return (
<div>
<ul>{ rows.map((row, i) => (<li key={ i }>{ row }</li>)) }</ul>
<button onClick={ () => { sortRows(true) }}>Sort Ascending</button>
<button onClick={ () => { sortRows(false) }}>Sort Descending</button>
</div>
);
}
}
class Parent extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
rows: ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter']
};
}
sortRows = (isSortAscending) => {
this.setState((prevState) => ({
rows: prevState.rows.slice().sort((a, b) => {
if (a < b) return -(isSortAscending ? 1 : -1);
if (a > b) return (isSortAscending ? 1 : -1);
return 0;
})
}));
}
render() {
return <Child rows={ this.state.rows } sortRows={ this.sortRows } />;
}
}
ReactDOM.render(<Parent />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
添加回答
举报