1 8 Months of Redux March 4, 2017 Yuri Takhteyev CTO + 19 Ranglers
Redux at Rangle • We’ve been actively using Redux for a bit over 18 months. • This is a good opportunity to re fl ect on what we’ve De fi ne learned. Prepare Execute
John Chen Brendan Moore Rob Brander Ken Ono Michael Bennett Steve Chae Andrew Lo Alex Sapronov De fi ne Evan Schultz Daniel Figueiredo Seth Davenport Katie Egervari Prepare Contributors Adam Winick Mo Binni Mark Degani Nikolas LeBlanc Execute Michael Faust Thomas Marek Varun Vachhar
Overview
What We’ve Learned: Redux is Great! • Our developers love it. • We’ve been using it on pretty much all of our projects. De fi ne • The strongest alternative: your own Redux! Prepare Overview
What’s So Great? • Makes it easy to think about events. • Very simple.* De fi ne • Great tools, only got better with time. • Code is easy to test. Prepare Overview Execute
More Great Stu ff • Organizes your code. • Makes it easy to dive into a new code base and fi nd your way around it.* De fi ne • Encourages best practices such as pure functions. Prepare Overview Execute
Caveats • Learning curve may be steep. More on this below. • Performance can get tricky on large apps. De fi ne • The store can get out of hand. • Reducers can get nasty if you don’t keep them small. Prepare • You need to fi nd an appropriate solution for handling side e ff ects. Overview Execute
Groking Redux
Understanding the Key Concepts • Redux is simple, but not always easy to learn. • Understand reduction. Love Array.reduce . De fi ne • Implement your own Redux. • Do you understand this style of code? Groking Redux Prepare const.logger.=.store.=>.next.=>.action.=>.{ ..… Execute };
More Tips • Read the docs, then read them again. • Take time to understand the “weird” bits. De fi ne • Start with redux-thunk, but abandon it later. • Follow Dan, but remember Dan is human. Groking Redux Prepare Execute
Performance
Component Updates • Busy event streams can lead to constant component updates. • Container / dumb component pattern can De fi ne exacerbate this. • Be smart about what you connect and where. You Prepare Performance can connect lower in the component tree. • Use shouldComponentUpdate . Execute
The Store
Should It Go in the Store? • Should something go in the store or component state? Usually the store. • But be pragmatic. De fi ne Prepare The Store Execute
How to Layout the Store? • What should determine the shape of your store? • It shouldn’t be the API. (Plan to transform.) De fi ne • It shouldn’t be the views. (Plan to transform.) • Optimize for simple reducers. Prepare • Think of the store as your database. The Store Execute
Rules of Thumb for Your Store • Don’t store anything that can be calculated. • Keep it very fl at. De fi ne • Avoid arrays. Prefer objects, keyed by id when appropriate. Prepare The Store Execute
Enforcing Immutability • ImmutableJS is a common option, but it comes with a cost. • There are alternative approaches: Object.assign, De fi ne immutable-helper, seamless-immutable. Prepare The Store Execute
Use Selectors • Your store shouldn’t cater to your components. • Never store computed values. De fi ne • Remap data with selector functions. • User reselect to to create composable memoized selectors, to avoid recalculation. Prepare The Store Execute
Reducers
Combine Simple Reducers • Keep reducers small. • Combine small reducers into more complex ones. De fi ne • Use higher order reducers. Prepare Reducers Execute
Higher Order Reducers • A function that returns a reducer. • combineReducers is an example. De fi ne • chainReducers (from redux-transducers ), ignoreActions (form redux-ignore ). Prepare • Write your own! Reducers Execute
Example: A Reducer let.colors.=.(state,.action).=>.{ ..switch.(action.type).{ ....case.COLOR_ADDED: ......return.[...state,.action.payload]; De fi ne ....case.COLOR_REMOVED': ......return.state.filter(n.=> ..............n.id.!==.action.payload.id); Prepare ....default.state; ..} } Reducers Execute
Example: A Higher Order Reducer let.listReducer.=.(addAction,.removeAction).=>. ..(state,.action).=>.{ ....switch.(action.type).{ ......case.addAction: De fi ne ........return.[...state,.action.payload]; ......case.removeAction': ........return.state.filter( Prepare ................n.=>.n.id.!==.action.payload.id); ......default.state; ....} Reducers Execute ..} }. let.app.=.combineReducers({ ..colors:.listReducer(COLOR_ADDED,.COLOR_REMOVED), ...... }
Actions and Side-E ff ects
Keep Your Actions Simple • Keep your actions very simple. • Ideally, your action creators should have no logic. De fi ne • This means you’ll need a side e ff ects library. Prepare Side E ff ects Execute
Redux-Thunk • A good place to start. • Key limitation: you still have logic in your action creators. De fi ne • Explore that limitation. • You’ll understand how middleware works better Prepare also. Side E ff ects • Do plan for the cost of switching. Execute
Sagas and Observables • redux-sagas and redux-observable are the main two long term solutions. • ES6 generators ( function* ) vs observables ( rx-js ). De fi ne • Pick one and stick with it. Prepare Side E ff ects Execute
Testing Redux
Focus on Testing What Matters • Test reducers, one action per unit test. • Test selectors. De fi ne Prepare Execute Testing
Testing Action Creators • Test your action creators if they have logic. • But ask yourself, why do you have logic in your action creators? De fi ne Prepare Execute Testing
Testing Side E ff ects • Can be tricky, but should be done. • Depends on the library. De fi ne Prepare Execute Testing
@qaramazov 18 Months of Redux @rangleio March 4, 2017 Yuri Takhteyev CTO + collaborators
Recommend
More recommend