Why shouldn't you use Redux

First steps with Redux Why Redux?

When you learn React, you will almost always hear people say how great Redux is and that you should try it out. The React ecosystem is growing rapidly, and there are so many libraries out there that you can connect to React, such as: B. Flow, Redux, Middlewares, Mobx etc.

Learning to use React is easy, but getting used to the entire React ecosystem takes time. This tutorial is an introduction to one of the essential components of the React ecosystem Redux.

Basic non-Redux terminology

Here are some of the most common terminology that you may not be familiar with, but that are not specific to Redux. You can go through this section and come back here if / if something doesn't make sense.

Pure function

A pure function is just a normal function with two additional restrictions that it must meet:

  1. The function should always return the same output for a series of inputs.
  2. It doesn't produce any side effects.

For example, here is a pure function that returns the sum of two numbers.

/ * Pure addition function * / const add = (x, y) => return x + y; console.log (add (2,3)) // 5

Pure functions provide predictable output and are deterministic. A function becomes impure if it does something other than calculating the return value.

For example, the Add function below uses a global status to calculate its output. In addition, the function also logs the value on the console, which is considered a side effect.

const y = 10; const impureAdd = (x) => console.log ('The inputs are $ x and $ y'); return x + y;

Observable side effects

"Observable side effects" is a fancy term for the interaction of a function with the outside world. When a function tries to write a value to a variable outside of the function or to call an external method, you can use these things as side effects.

However, if a pure function calls another pure function, the function can be treated as pure. Here are some of the most common side effects:

  • Make API calls
  • Logging on the console or printing data
  • Data mutate
  • DOM manipulation
  • Get the current time

Container and presentation components

Splitting the component architecture into two is useful when working with React applications. You can roughly divide them into two categories: container components and presentation components. They are also known as smart and stupid components.

The container component is concerned with how things work, while the presentation components are concerned with how things look. To better understand the concepts, I covered that in another tutorial: Containers vs. Presentation Components in Response.

Mutable vs. Immutable Objects

A mutable object can be defined as follows:

Amutable objectis an object whose state can be changed after it has been created.

Immutability is the exact opposite - an immutable object is an object, its state can not changed after it has been created. In JavaScript, strings and numbers cannot be changed, but objects and arrays cannot. The example shows the difference better.

/ * Strings and numbers are immutable * / let a = 10; let b = a; b = 3; console.log ('a = $ a and b = $ b'); // a = 10 and b = 3 / * Objects and arrays are not * / / * Let's start with objects * / let user = Name: "Bob", Age: 22, Job: "None" active_user = user; active_user.name = "Tim"; // Both objects have the same value console.log (active_user); // "name": "Tim", "age": 22, "job": "None" console.log (user); // "name": "Tim", "age": 22, "job": "None" / * Now for arrays * / let usersId = [1,2,3,4,5] let usersIdDup = usersId; usersIdDup.pop (); console.log (usersIdDup); // [1,2,3,4] console.log (usersId); // [1,2,3,4]

To make objects immutable, use the method to create a new method or the new spread operator.

let user = name: "Bob", age: 22, job: "None" active_user = Object.assign (, user, name: "Tim") console.log (user); // "name": "Bob", "age": 22, "job": "None" console.log (active_user); // "name": "Tim", "age": 22, "job": "None"

What is Redux?

The official site defines Redux as follows:

Redux is a predictable status container for JavaScript applications.

While this describes Redux accurately, it is easy to get lost the first time you see the bigger picture of Redux. It has so many moving parts that they have to fit together. But once you do it, I promise you will love Redux.

Redux is a state management library that you can connect to any JavaScript library, not just React. However, it works very well with React due to the functional nature of React. To better understand this, let's take a look at the condition.

As you can see, the state of a component determines what is rendered and how it behaves. The application has an initial state and any user interaction triggers an action that updates the state. When the status is updated, the page will be rendered again.

With React, each component has a local state that can be accessed from the component, or you can pass them to child components as props. We usually use the state to store:

  1. UI status and transition dates. This includes a list of UI elements for the navigation menu or form entries in a controlled component.
  2. Application status such as data retrieved from a server, login status of the user, etc.

Storing application data in the state of a component is fine when you have a basic React application with few components.

Component hierarchy of a basic application

Most real-world apps, however, have many more features and components. When the number of levels in the component hierarchy increases, managing status becomes problematic.

Sketch of a medium-sized application

Why should you use Redux?

Here is a very likely scenario that you might come across while working with React.

  1. You're building a medium-sized application, and your components are neatly broken down into smart and dumb components.
  2. The intelligent components handle the state and pass it on to the silent components. You take care of API calls, fetch the data from the data source, process the data and then set the status. The stupid components get the props and return the UI rendering.
  3. When you are writing a new component, it is not always clear where to place the status. The status can be part of a container that is directly superior to the presentation component. Better still, you could move the status up in the hierarchy so that the status is accessible to multiple presentation components.
  4. As the app grows, you can see the state is scattered all over the place. If a component needs to access state that it cannot immediately access, try raising the state to the component's closest ancestor.
  5. After constant refactoring and purging, most holding positions are at the top of the component hierarchy.
  6. Ultimately, you decide it's a good idea to have a component at the top manage status globally and then pass it all down. Any other component can subscribe to the props it needs and ignore the rest.

I've personally seen this with React, and many other developers will agree. React is a view library, and it is not React's job to specifically manage status. What we are looking for is the principle of separation of concerns.

Redux helps you separate the application state from React. Redux creates a global memory that is at the top level of your application and forwards the status to all other components. In contrast to Flux, Redux does not have multiple memory objects. All of the state of the application resides in this memory object, and you may be able to replace the view tier with another library with memory intact.

The components are rerendered each time the store is updated, and this has little impact on performance. This is good news, and it has a lot of benefits. You can treat all of your React components as dumb and React can only focus on the view side.

Now that we know why Redux is useful, let's dive into the Redux architecture.

The Redux architecture

As you learn Redux, there are some basic concepts that you will need to get used to. The picture below describes the Redux architecture and how everything is interconnected.

Redux in a nutshell

If you're used to Flux, some of the elements look familiar. If not, that's fine too, because we'll cover everything from the bottom up. First, make sure you have redux installed:

Install npm redux

Use Create-React-App or your preferred webpack configuration to set up the development server. Since Redux is an independent state management, we will not connect React yet. So remove the contents of index.js and we'll play around with Redux for the rest of this tutorial.

business

The store is a large JavaScript object that contains many key-value pairs that represent the current state of the application. In contrast to the state object in React, which is distributed over various components, we only have one memory. The store provides the application status and each time the status is updated, the view is rendered again.

however, You can never mutate or change the store. Instead, you create new versions of the deal.

(previous state, action) => new state

For this reason, you can travel through time through all states from the time the app was started in your browser.

The store has three methods of communicating with the rest of the architecture. You are:

  • Store.getState () - access to the current status tree of your application.
  • Store.dispatch (action) - To trigger a state change based on an action. More about the actions below.
  • Store.subscribe (listener) - To listen to changes in status. It is called every time an action is triggered.

Let's create a shop. Redux has a method of creating a new business. You have to hand in a reducer, although we don't know what it is. So I'm going to create a function called a reducer. You can optionally supply a second argument that determines the initial state of the memory.

src / index.js

import createStore from "redux"; // This is the reducer const Reducer = () => / * Something goes here * / // Initial state is optional. // I'm using a counter for this demo, but usually state is an object const initialState = 0 const store = createStore (reducer, initialState);

Now we're going to listen to any changes in the store and then the current state of the store.

store.subscribe (() => console.log ("Status has changed" + store.getState ());)

How do we update the store? Redux has so-called actions that make this possible.

Promotion / promotion creator

Actions are also simple JavaScript objects that send information from your application to the store. If you have a very simple counter with an increment key, pressing that will trigger an action that looks like this:

Type: "INCREMENT", payload: 1

You are the only source of information for business. The state of the memory only changes in response to an action. Each action should have a type property that describes what the action object is up to. Otherwise, the structure of the promotion is entirely up to you. Keep your action small, however, because an action is the minimum amount of information required to transform the application state.

For example, in the example above, the type property is set to "INCREMENT" and an additional Payload property is included. You can rename the Payload property to something more useful or, in our case, leave it out entirely. This is how you can send an action to the store.

store.dispatch (type: "INCREMENT", payload: 1);

When coding Redux, no actions are normally used directly. Instead, you call functions that return actions. These functions are commonly known as action creators. Here is the action creator for the previously described incrementing action.

const incrementCount = (count) => return type: "INCREMENT", payload: count

To update the status of the counter, you need to do the following:

store.dispatch (incrementCount (1)); store.dispatch (incrementCount (1)); store.dispatch (incrementCount (1));

If you go to the browser console, you will find that it works partially. We get undefined because we haven't defined the reducer yet.

Now we've got promotions and the store covered. However, we need a mechanism to convert the information provided by the action and transform the state of the memory. Reducers serve this purpose.

Reducers

An action describes the problem and the reducing agent is responsible for solving the problem. In the previous example, the method returned an action that provided information about the type of change we wanted to make to the status. The reducer uses this information to actually update the status. There is one big point highlighted in the documents that you should always remember when using Redux:

With the same arguments, a reducer should calculate the next state and return it. No surprises. No side effects. No API calls No mutations Only one calculation.

This means that a reducer should be a pure function. A series of inputs should always return the same output. Beyond that, it shouldn't do anything anymore. Also, a reducer is not the place for side effects such as: B. AJAX calls or getting data from the API.

Let's fill out the reducer for our counter.

// This is the reducer const Reducer = (state = initialState, action) => switch (action.type) case "INCREMENT": return state + action.payload default: return state

The reducer accepts two arguments - state and action - and returns a new status.

(previous state, action) => new state

The state accepts a default value, which is only used when the value of the status is undefined. Otherwise, the actual value of the status is retained. We use the switch statement to select the correct action. Refresh the browser and everything works as expected.

Let's add a case for without the counter being incomplete.

// This is the reducer const reducer = (state = initialState, action) => switch (action.type) case "INCREMENT": return state + action.payload case "DECREMENT": return state - action.payload default: return status

Here is the action creator.

const decrementCount = (count) => return type: "DECREMENT", payload: count

Finally ship it to the store.

store.dispatch (incrementCount (4)); // 4 store.dispatch (decrementCount (2)); // 2

That's it!

Summary

This tutorial should serve as a starting point for managing statuses with Redux. We have described everything you need to understand the basic Redux concepts such as store, promotions and reductions. Towards the end of the tutorial, we also created a working Redux demo counter. While it wasn't much, we learned how all of the pieces of the puzzle fit together.

In the past few years, React has grown in popularity. In fact, there are a number of items on the marketplace that are available for purchase, review, implementation, and so on. If you're looking for more resources related to React don't hesitate to find out.

In the next tutorial, we will use the knowledge gathered here to create a React application with Redux. Stay tuned until then. Share your thoughts in the comments.