最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to compare props in ComponentDidUpdate for large data structure connected with Redux - Stack Overflow

programmeradmin1浏览0评论

I've been working with new lifecycles of React v16. It works great when we pare only a single key. But when it es to pare a large data structures like an Arrays of objects, the deep parison will bee very costly.

I have use case like this in which I have an array ob objects stored in redux,

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

Whenever active state of any objects get changed I dispatch an action to update redux state to be same for all connected ponents with that reducer.

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

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

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

  render() {
   ...
  }
}

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


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

How can I avoid infinite loop on setState in ponentDidUpdate, I don't want to do deep parison of readings array. Is there a better solution to handle this case?

Your suggestions will be highly appreciated.

I've been working with new lifecycles of React v16. It works great when we pare only a single key. But when it es to pare a large data structures like an Arrays of objects, the deep parison will bee very costly.

I have use case like this in which I have an array ob objects stored in redux,

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

Whenever active state of any objects get changed I dispatch an action to update redux state to be same for all connected ponents with that reducer.

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

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

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

  render() {
   ...
  }
}

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


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

How can I avoid infinite loop on setState in ponentDidUpdate, I don't want to do deep parison of readings array. Is there a better solution to handle this case?

Your suggestions will be highly appreciated.

Share Improve this question asked Oct 29, 2018 at 10:33 Sakhi MansoorSakhi Mansoor 8,1225 gold badges23 silver badges38 bronze badges 2
  • 1 Just a thought - do you need to derive state here, why not just keep it in props? Also, what do you do with the readings? Perhaps you could restructure to remove the need for a deep parison. If you display something for each reading, why not have a <Reading /> ponent for each of them. This could be a PureComponent and each <Reading /> can shallow pare the object reference, with no need for a deep parison in the parent. – user195257 Commented Oct 29, 2018 at 11:50
  • yes you're right. Keeping only props solved the problem. Thank you – Sakhi Mansoor Commented Oct 29, 2018 at 12:13
Add a ment  | 

2 Answers 2

Reset to default 6

Ideally, you make immutable changes to your reducer and keep the reducer state level low.

So if your array consists of many objects and you need to dispatch based on some attribute change, you should replace the whole readings array using spread operator or using some immutable library e.g immutablejs. Then in your ponentDidupdate you can have something like :

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

Thanks feedbacks are wele.

First read another answer, If that didn't work for you, then:

  1. Make sure you're paring two arrays with :
ponentDidUpdate(prevProps){
  if(JSON.stringify(prevProps.todos) !== JSON.stringify(this.props.todos){...}
}
  1. Make sure you are changing the passed prop (state in parent) after deep cloning it:
let newtodos = JSON.parse(JSON.stringify(this.state.todos));
newtodos[0].text = 'changed text';
this.setState({ todos : newtodos });

(Note that Shallow clone doesn't work, since that way you change the objects directly)

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论