0

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.

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, I actually came up with a similar solution in the meantime. I'm passing a hash of the objects into the component from the outside, which I set inside the state. Then in getDerivedStateFromProps I compare the new hash to the old one in the state. If they don't match, I reset the openItem.
But doesn't sending hash from outside adds extra responsibility to the consumer of the carousel?
yeah, youre right, better to compute this inside the component.
i did it like this because i was passing actual components as props, so i wasn't certain if hashing those would still give the same hashes when the data was the same.
0

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

1 Comment

But then I would still have to go into componentDidUpdate and set the state there, right? At least that's what I see in the docs: reactjs.org/docs/react-component.html#getsnapshotbeforeupdate

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.