Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Redux Made Easy with Rematch

You're reading from   Redux Made Easy with Rematch Reduce Redux boilerplate and apply best practices with Rematch

Arrow left icon
Product type Paperback
Published in Aug 2021
Publisher Packt
ISBN-13 9781801076210
Length 286 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Sergio Moreno Sergio Moreno
Author Profile Icon Sergio Moreno
Sergio Moreno
Arrow right icon
View More author details
Toc

Table of Contents (18) Chapters Close

Preface 1. Section 1: Rematch Essentials
2. Chapter 1: Why Redux? An Introduction to Redux Architecture FREE CHAPTER 3. Chapter 2: Why Rematch over Redux? An Introduction to Rematch Architecture 4. Chapter 3: Redux First Steps – Creating a Simple To-Do App 5. Chapter 4: From Redux to Rematch – Migrating a To-Do App to Rematch 6. Section 2: Building Real-World Web Apps with Rematch
7. Chapter 5: React with Rematch – The Best Couple – Part I 8. Chapter 6: React with Rematch – The Best Couple – Part II 9. Chapter 7: Introducing Testing to Rematch 10. Chapter 8: The Rematch Plugins Ecosystem 11. Section 3: Diving Deeper into Rematch
12. Chapter 9: Composable Plugins – Create Your First Plugin 13. Chapter 10: Rewrite a Full Code Base from JavaScript to TypeScript 14. Chapter 11: Rematch with React Native and Expo – A Real-World Mobile App 15. Chapter 12: Rematch Performance Improvements and Best Practices 16. Chapter 13: Conclusion 17. Other Books You May Enjoy

How does Redux work?

Flux is a generalized pattern of doing things, a reusable solution to a frequent problem in software architecture within a given situation. Redux is one of the frameworks that took this pattern and tweaked it to solve even more problems.

Redux and Flux both share the concern that you must concentrate your store update logic somewhere. In Flux, stores could be a good place to store the data and its logic, but in Redux, we use reducers because Redux only has a single store. This means that we only have one way to communicate with that source of truth, through actions that trigger reducers that update the store.

As we did with the Flux pattern, to help us compare the differences, let's see a diagram of the Redux architecture:

Figure 1.6 – Redux architecture

With Redux, the whole application state is placed within a centralized store that acts as the application's single source of truth. Also, the store becomes simpler because then it's only responsible for containing the state and is no longer in charge of determining how to adjust its state in response to actions – that logic is assigned to reducers.

Actions follow the same pattern in Flux as in Redux, which means we can now jump straight to reducers and stores.

Reducers

Reducers are just pure functions. Pure functions, by definition, are functions where the return value is always determined by its input values, which means that they are really predictable and testable. To clarify this, a pure function will never be a function with side effects. Side effects are usually AJAX requests, random numbers, mutations... because they introduce newer data that doesn't depend directly on its input values.

Reducers are simply functions that accept the current state as the first argument and the second argument as a given action. The output will be either the unmodified state or a new, edited copy of the state.

Another difference with Flux is that Redux assumes your state is immutable; that means you can't mutate your data. Reducers must always return the entire state (that means a new object reference), which is easy with the new object/array spread operator, a new proposal in JavaScript. This allows us to use the spread () operator to copy enumerable properties from one object to another in a simpler way.

Here's an example of a Redux reducer in code:

const todoAppReducer = (state = { tasks: [] }, action) => {
  switch (action.type) {
    case 'ADD_TODO_TASK':
      return {
        ...state,
        tasks: [
          ...state.tasks,
          action.payload
        ]
      }
    default: return state
  }
}

This reducer will read from an action argument with a payload, which is the new task that will be added to current state tasks. We use the spread operator to easily merge the current state with the new state.

Stores

Redux stores employ shallow equality checking, which simply entails checking that two different variables reference the same object. A shallow equality check that comes quickly to our minds is a simple a === b; therefore, they are immutable by default, which means you can't change the state directly. You must use reducers to make copies of existing objects/arrays, and modify the copies if needed, to finally return the new reference.

The main difference between Redux and Flux is that Redux only includes a single store per application instead of multiple stores, as Flux does. Having a single store makes persisting and updating the user interface simpler and, of course, simplifies the subscription logic.

This doesn't mean that every piece of state in your application must be placed in a Redux store. You should decide whether a piece of state belongs in Redux or your user interface components. For example, if we build a little component with some internal configuration that just belongs to that component, it isn't a good practice to introduce that state into Redux – just keep it simple using the local state.

We already mentioned that data must flow in only one direction, which perfectly describes the steps to update our application UI.

When our application is rendered for the first time, the following occurs:

  1. A store is created using a root reducer function.
  2. The store calls the root reducer once and saves the return value as its initial state.
  3. When the user interface is first rendered, our user interface will access our data inside the store and also subscribe to any future store updates to know whether the state has changed.

What about when we update something in the application? The application code must dispatch an action to the Redux store like so:

store.dispatch({ type: "counter/increment" })

When the store receives the emitted action, the following occurs:

  1. The store runs the reducer function again with the previous state and the current action and saves the return value as the new state.
  2. The store notifies all parts of the user interface that subscribed previously.
  3. Each component that has subscribed forces a re-render with the new data.

Unidirectional flow is the concept key that Redux offers against other state management solutions, it's predictable by default. Because you can't ever mutate the application state, all the changes in our state are done through reducers, which are invoked through actions, creating a predictable state, since the consequence of an action will result in a concrete state:

Figure 1.7 – Redux unidirectional data flow

Creating a state that is predictable means that by using Redux, we will know what every single action in our application will do and how the state will change when this action is received.

You have been reading a chapter from
Redux Made Easy with Rematch
Published in: Aug 2021
Publisher: Packt
ISBN-13: 9781801076210
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image