如何在ComponentDidUpdate中比较与Redux连接的大型数据结构的属性

时间:2018-10-29 10:33:17

标签: javascript reactjs redux

我一直在使用React v16的新生命周期。当我们仅比较单个键时,它的效果很好。但是,当比较大型数据结构(如对象数组)时,深度比较将变得非常昂贵。

我有这样的用例,其中我有一个数组ob对象存储在redux中,

const readings =[
{
id: ...,
name: ...',
unit:...,
value: ...,
timestamp: ...,
active: true,
 },
 ...
]

每当任何对象的活动状态发生变化时,我都会调度一个操作以将所有减速器的连接状态更新为相同。

class Readings extends Component {
  state = {
    readings:[],
  };

  static getDerivedStateFromProps(nextProps, prevState) {
    if ( // comparsion of readings array with prevState) {
      return {
        readings: nextProps.readings,
      };
    }
    return null;
  }

  componentDidUpdate(prevProps) {
    if ( // comparsion of readings array with prevState) {
      // perform an operation here to manipulate new props and setState to re render the comp
      // this causes infinite loop
    }
  }

  render() {
   ...
  }
}

const mapStateToProps = state => ({
  readings: state.readings.readings,
});


export default connect(
  mapStateToProps,
)(Readings));

如何避免在componentDidUpdate中对setState进行无限循环,我不想对读数数组进行深入比较。是否有更好的解决方案来处理这种情况?

您的建议将受到高度赞赏。

2 个答案:

答案 0 :(得分:2)

  

理想情况下,您对减速器进行不可变的更改,并保持   减速器状态级别低。

因此,如果您的数组由许多对象组成,并且您需要根据某些属性更改进行分派,则应该使用传播运算符或使用某些不可变的库(例如immutablejs)来替换整个读数数组。然后,在您的componentDidupdate中,您可以输入类似以下内容:

componentDidUpdate(prevProps) {
   const {
     readings,
   } = this.props
   const {
     readings: prevReadings,
   } = prevProps
  if (readings !== prevReadings) {
      //dispatch something
  }
}

感谢反馈。

答案 1 :(得分:0)

  1. 确保要比较两个数组:
componentDidUpdate(prevProps){
  if(JSON.stringify(prevProps.todos) !== JSON.stringify(this.props.todos){...}
}
  1. 确保在深克隆之后更改传递的道具(父项中的状态):
let newtodos = JSON.parse(JSON.stringify(this.state.todos));
newtodos[0].text = 'changed text';
this.setState({ todos : newtodos });

(请注意,浅表克隆无效,因为那样直接更改对象即可)