Get to know React Redux

Tram Ho


Redux is a predictable state container for JavaScript applications.

It helps you write applications that run stably, run in different environments (client, server, and native) and are easy to test. On top of that, it provides a great developer experience, such as editing code directly in conjunction with the time traveling debugger.

You can use Redux with React or any other library. It is very small (2kB, including dependencies), but has a large ecosystem of addons.

What does Redux solve?

Even a single page application can grow out of control without clear boundaries between every layer of the application. This is especially true in React.

You can get this by keeping the state in the original React component (or in the context) as long as the application is still small. After that, things will become difficult especially when you add more behaviors to the application. At some point you may want to achieve a consistent way of tracking state changes. Not only that, frontend components should not know about business logic.

Unfortunately, a ton of logic is stuffed into today’s frontend components. Is there an alternative to this complexity?

Redux can accurately solve those problems. It may not be obvious in the first place, but Redux helps provide each frontend component with the exact state needed.

Even better, Redux can keep the business logic inside its layer (middleware), along with the code to fetch the data.

Should I use Redux?

Redux is a valuable tool for managing your state, but you should also consider whether it is appropriate for your problem. Don’t use Redux just because someone says you should – take some time to understand the potential benefits and tradeoffs of using it.

Here are some suggestions on what it means to use Redux:

  • You have a fair amount of data that changes over time.
  • You need a single source for your state.
  • You find that keeping all your states in a top-level component is no longer enough.

However, it is important to understand that using Redux comes with tradeoffs. It is not designed to be the shortest or fastest writing code. It aims to help answer the question “When does certain state changes and where does the data come from?”, With predictable behavior. It does so by asking you to follow specific constraints in your application: storing the application state in simple data, describing changes in simple objects, and handling changes. switch with functions that apply invariant updates. These constraints require effort from the developer, but also open up some additional possibilities (such as storage and store synchronization).

Get acquainted with Redux

In the next section, we will begin to build a proof of concept to introduce:

  • Redux basic principles
  • Redux with React

Redux store

The store in Redux is a kind of magic and holds all the state of the application. It is unique in any Redux application.

Let’s create a store to get started with Redux. Move into your React development environment and install Redux:

Create a directory for the store: mkdir -p src/js/store

Next create a new file, src / js / store / index.js and create the store:

As you can see, the store is the result of calling createStore, a function from the Redux library. createStore takes a reducer as the first argument and in this case we pass rootReducer.

You can also switch the initial state to createStore, which is useful for server-side rendering and state preloading, but for now we don’t care about that. The most important concept to understand here is that the state in Redux comes from reducers. Repeat: reducers create your application state.

Redux reducers

What is a Reducer? A Redux reducer is just an IavaScript function. It has two parameters: the current state and the action.

In a typical React component, the local state may be changed locally. In Redux you are not allowed to do that. Redux’s third principles state that the state is immutable and cannot be changed in place.

In other words, reducer must remain the same. The pure function is a function that returns the same output for a given input.

In the example below, we will create a simple reducer, taking the initial action state as a parameter. Create a directory for the reducer: mkdir -p src/js/reducers

Create a new file, src / js / reducers / index.js:

Notice how the original state is passed as the default parameter. But the reducer has now done nothing more than return the original state.

Redux action and name constants

Actions are payloads of information that sends data from your application to your store. They are the only source of information for stores. You send them to the store using store.dispatch ().

Redux reducer is undoubtedly the most important concept in Redux. The Reducer creates the state of an application. But how does a reducer know when to create the next state?

The second rule of Redux says the only way to change this state is by sending a signal to the store. This signal is an action. So sending an action means sending a signal to the store.

Redux actions are none other than JavaScript objects:

As you can see it’s a JavaScript object that has two properties: type and payload.

The type control state will change and it is always required by Redux. Instead, the payload attribute describes what will change and can be ignored if you don’t have new data to store in the store.

As a best practice in Redux, we package every action in a function, so that object creation is abstracted.

Create a directory for actions: mkdir -p src/js/actions

Then create a new file, src / js / actions / index.js:

You may have noticed that the type attribute is a string. Strings are prone to misspellings and duplicates, and for this reason, it’s better to declare actions as constants. Create a new directory: mkdir -p src/js/constants

Then create a new file, src / js / constants / action-type.js:

Now reopen src / js / actions / index.js and update the action to use action types:

Refactoring the reducer

How does the reducer know when to create the next state? The key here is the Redux store. When an action is sent, the store will forward a message to the reducer.

At this point, the reducer views the type attribute of this action. Then depending on the type of action, the reducer creates the next state, eventually merging the action payload into the new state.

We have previously created a reducer without doing anything. Please fix it! Open src / js / reduce / index.js and update the reducer with an if statement to check the action type:

There is also a line of code that pushes the action payload to the original state. Seems like the right thing to do. But it is wrong! The Reducer breaks the main Redux principle: immutability.

Array.prototype.push is an impure function: it modifies the original array. But there is more to it. We are also changing the initial state in place.

We need a fix. First we can return a new state with Object.assign, ie a new JavaScript object. In this way, we keep the original state unchanged. We can then use Array.prototype.concat instead of Array.prototype.push to keep the original array:

Now the original state is left in the first condition and the resulting state is only a copy of the original state. Remember the two main points to avoid changes in Redux:

  • Use concat (), slice () or spread operator for arrays.
  • Use Object.assign () or the object spread.

Redux store method

You might be surprised to know that Redux itself is a small library (2KB) and only the three most important are:

  • getState to read the current state of the application.
  • dispatch to send an action.
  • subscribe to hear about state changes.

Now we will check in the browser console. In order to do this we have to export as global variables in the store and action we created earlier. Create a new file named src / js / index.js and place the code here:

Now also open src / index.js, clean up its content and update it as follows:

Now run: npm start

There are no articles. In fact, we haven’t updated the original state yet. To make things interesting, we can listen for state updates with subscriptions.

The subscribe method that accepts a callback will trigger whenever an action is sent. Sending an action means telling the store that we want to change the state.

Register the callback with:

To change the state in Redux, we need to send an action. To send an action, we will call the dispatch method. We now have an action: addArticle to add a new entry to the state. Please send the action with:

Immediately after running the above code, you will see “Look ghost, Redux !!”. To verify that the changed state runs again:


Share the news now

Source : Viblo