I have a carousel that takes a state of {pages: [...], currentPage: 0}
. If I set currentPage = 1
I want the carousel to slide left. The same thing should happen if I increase the number again, and it should slide right I decrease it.
I can't work out how this should be done with immutable data. The animation shouldn't be represented in the state object (should it?), but storing a property on the React component removes its "pure" functional nature.
What's the best way to approach this problem?
Just show me an example
This doesn't use Immutable.js, but the
current
property is just a number, which is immutable in JS, so in some regards it's the same idea:http://jsbin.com/ligejacolo/edit?js,output
IMO the best option is ReactCSSTransitionGroup
+1 for the unnecessarily snarky reference to ReactCSSTransitionGroup in the comments, if you can use that.
After that, let the browser manage state via CSS transitions
I would store the
pages
andcurrentPage
as props, regardless of whether the values are Immutable.js instances (props are a stateful part of your UI, just like state, don't let the name fool you!). When they're stored as props, it provides a useful API to the users of your component.If you're using CSS transitions then at any given moment you should be able to render the markup and classes based on this information.
For example, given the (over-simplified markup):
And some CSS like:
The browser takes care of mid-transition changes to the properties.
Often times you'll need to know when the animation is done, which you can accomplish with a
transitionend
listener andisAnimating
flag (which I would store in the state, not the props). SetisAnimating
whencurrentPage
changes and clear it ontransitionend
.You'll also often need to know which direction you're transitioning, which you can accomplish with a
previousPage
prop.Finally, if you're just using JavaScript
Keep a reference to the current transition in the
state
(possibly the jQuery selection used to start the animation, if that's what you're using). When the transition is done, remove the reference. If thecurrentPage
changes mid-transition, call.stop()
on the selection (or whatever API you're using).