Why Pure Functions?
Since Redux reducers are pure functions operating on immutable data, they always produce the same output given the same input, making them easy to test.
pure functions allows Redux to easily support many use cases that are generally not easily done with mutative state, such as:
- Time travel (Going back in time to a previous state)
- Logging (Track every single action to figure out what caused a mutation in the store)
- Easy bug reporting (Just send the list of actions dispatched, and replay them to get the exact same state)
- Optimized rendering (At least in frameworks that render virtual DOM as a function of state, such as React: due to immutability, you can easily tell if something has changed by comparing references, as opposed to recursively comparing the objects)
- Easily test your reducers, as pure functions can easily be unit tested
Why Combined Reducers are encouraged?
You can have a component that relies on
reducer-A and another component that relies on
reducer-B. This also improves performance as any single component will only be subscribing to whatever branch(es) of the tree concerns them.
Why action creator?
Why use a immutability library?
While the very nature of reducers and actions make them easy to test, without an immutability helper library, there’s nothing protecting you from mutating objects, meaning the tests for all your reducers have to be particularly robust.
Mutations are a lot harder to reason through. Without an immutability library, we lose all the benefits that Redux provides.
Middlewares in Redux
iddleware’ is the term used for functions that can intercept actions being dispatched. Once intercepted, it can do things like transform the action or dispatch an asynchronous action, much like middleware in other frameworks (such as Express.js).
Two very common middleware libraries are Redux Thunk and Redux-saga. Redux Thunk is written in an imperative style, while Redux-saga is written in a functional style.
Thunk vs Saga
Thunk is imperative and returns chainable functions.
Saga is declarative and uses
es6’s generator and is super easy to test.
- Presentational Componenets: Presentational components describe how things should look visually, depending solely on their props to render; they invoke callbacks from props to dispatch actions. They’re written by hand, completely pure, and are not tied to state management systems like Redux.
Presentational components are dumb component, which makes them easier to test and compose.
- Container Components: Container components, on the other hand, describe how things should function, are aware of Redux, dispatch Redux actions directly to perform mutations and are generally generated by React-Redux. They are often paired with a presentational component, providing its props.
*React emphasizes extensibility and re-usability through composition, which is when you wrap components in other components.*
React-Redux provides a helper function called
connect( .. )that creates a higher order component from a “dumb” React component that is aware of Redux.
Hydration refers to the process of filling an object with data. An object which has not yet been hydrated has been instantiated and represents an entity that does have data, but the data has not yet been loaded into the object. This is something that is done for performance reasons.
Dehydrating your application means extracting its state into an object. Rehydrating your app is using that same object to reinject state in your application