简体   繁体   English

道具更改时更新组件状态

[英]Update component state when props change

I have a carousel component that receives the carousel items as a prop. 我有一个轮播组件,可以接收轮播项目作为道具。 I'm storing the currently active carousel item in the state of the carousel component. 我将当前活动的轮播项目存储在轮播组件的状态下。 The carousel itself is a slider and controlled with a GSAP draggable. 轮播本身是一个滑块,并由可拖动的GSAP控制。 The number of carousel items might change, and then I want to reset the state so that the first item is active. 轮播项目的数量可能会更改,然后我想重置状态,以便第一个项目处于活动状态。 How can I achieve this with the current React version? 如何使用当前的React版本实现这一目标? I tried: 我试过了:

static getDerivedStateFromProps(props, state) {
  if (state.openItem > props.items.length) {
    return {
      openItem: 0,
    };
  }
  return null;
}

But this will only reset if the current item is larger than the total number of items. 但这只会在当前项目大于项目总数时重置。 I would like a way where I could compare the prevProps so that I can check if the total number of items have changed. 我想要一种可以比较prevProps的方式,以便可以检查项目总数是否已更改。 If I set the state in componentDidUpdate, that might cause an endless render loop. 如果在componentDidUpdate中设置状态,则可能会导致无限循环的渲染循环。 I don't want to pull out the state to the parent component, because that would make the parent require too much functionality for the carousel component to be reusable. 我不想将状态拉到父组件,因为那样会使父组件需要过多的功能才能使轮播组件可重用。

Store items in state and then use getDerivedStateFromProps like this : items存储在状态中,然后使用getDerivedStateFromProps这样:

static getDerivedStateFromProps(nextProps, prevState) {
  if (nextProps.items.length !== prevState.items.length) {
    return {
      openItem: 0,
      items: nextProps.items
    };
  }
  return null;
}

This is fine for the requirement but ideally you should figure out a way to check for content equality of the items and then fire the state change. 这是罚款的要求,但最好你应该想出一个办法来检查的内容平等items再火的状态变化。 You can use isEqual from lodash like this and replace equality check with : 您可以像这样从lodash使用isEqual并将相等检查替换为:

if (_.isEqual(nextProps.items.length, prevState.items.length))

*note that isEqual performs deep equality checks and may have performance implications. *请注意, isEqual执行深入的相等检查,并且可能会对性能产生影响。

You can use the getSnapshotBeforeUpdate() method for the compare the prevProps so that you can check if the total number of items have changed. 您可以使用getSnapshotBeforeUpdate()方法比较prevProps,以便检查项目总数是否已更改。

getSnapshotBeforeUpdate(prevProps, prevState) {
    // you can compare the previous prop value and previous state value as per you requirement
    if (prevProps.openItem.length > prevState.openItem.length) {
      // your code
    }
    return null;
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM