0

我有一个充当可排序表的 React 组件。表头和表行是容器的子项,容器正在处理表的状态。单击标题时,数据会重新排序,就像在这个语义 UI 反应示例中一样。

handleSort = (clickedColumn) => {
const { column, orders, direction } = this.state

if (column !== clickedColumn) {
  this.setState({
    column: clickedColumn,
    orders: customSort(orders, clickedColumn),
    direction: 'ascending',
  })
} else {
this.setState({
  orders: orders.reverse(),
  direction: direction === 'ascending' ? 'descending' : 'ascending',
})}

第一次单击列标题时,第一个闭包运行,并this.setState更改容器的状态,并触发子项接收新的道具并相应地更新。如果我重新单击列标题以反转数据的顺序,则第二个闭包运行,并this.setState更新容器的状态。因此,子组件会OverviewTableHeader更新,但OverviewTableRows不会。

render() {
const { designers, orders, column, direction } = this.state
if (orders === "loading"){
  return <Loading />
} 
const tableRows = <OverviewTableRows  
                     designers={designers} 
                     orders={this.state.orders}
                     />
debugger
return (
  <div className="overview">
    <Table selectable fixed sortable>
      <OverviewTableHeader sort={this.handleSort} column={column} direction={direction}/>
      {tableRows}
    </Table>
  </div>
  ) 
}

这是一个实际操作的视频。

在视频中,您可以看到OverviewTableRows触发器componentWillReceivePropsshouldComponentUpdate第一次setState在父级中触发,但不是第二次。

如果需要,我可以添加我的所有代码。这是一个错误吗?任何帮助是极大的赞赏!

4

2 回答 2

1

我通过在反转数组并使用它来更新状态之前制作数组的副本来解决这个问题。

handleSort = (clickedColumn) => {
const { column, orders, direction } = this.state

if (column !== clickedColumn) {
  this.setState({
    column: clickedColumn,
    orders: customSort(orders, clickedColumn),
    direction: 'ascending',
  })
} else {
  const reversedOrders = orders.slice().reverse();
this.setState({
  orders: reversedOrders,
  direction: direction === 'ascending' ? 'descending' : 'ascending',
})}

我猜数组的身份orders很重要。我猜这与 React 的功能特性有关。我希望这对某人有帮助!如果有人对为什么会这样有很好的解释,我很想听听。

于 2017-10-03T15:32:52.037 回答
0

这是一个很好的报价,可以解释发生了什么。

通过直接操作 this.state 你绕过了 React 的状态管理,这可能是潜在的危险,因为之后调用 setState() 可能会替换你所做的突变。

取自这篇文章

由于orders是一个可变对象和 的成员state,因此您在调用时直接更改状态orders.reverse(即使此重新排序是在setState调用中完成的)。

所以,是的,您创建副本的解决方案orders将解决此问题,因为您不再this.state直接进行更改。

于 2017-10-03T16:00:16.293 回答