Moriz Büsing
Moriz Büsing

Reputation: 367

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. 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? 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. If I set the state in componentDidUpdate, that might cause an endless render loop. 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.

Upvotes: 0

Views: 589

Answers (2)

sudheer singh
sudheer singh

Reputation: 922

Store items in state and then use getDerivedStateFromProps like this :

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. You can use isEqual from lodash like this and replace equality check with :

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

*note that isEqual performs deep equality checks and may have performance implications.

Upvotes: 2

Shalini Sentiya
Shalini Sentiya

Reputation: 97

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, 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;
  }

Upvotes: 0

Related Questions