Home > Web Front-end > JS Tutorial > Getting Started With Redux: Why Redux?

Getting Started With Redux: Why Redux?

Jennifer Aniston
Release: 2025-03-13 11:44:09
Original
882 people have browsed it

When you're learning React, you will almost always hear people say how great Redux is and that you should give it a try. The React ecosystem is growing at a swift pace, and there are so many libraries that you can hook up with React, such as flow, redux, middlewares, mobx, etc. 

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

Basic Non-Redux Terminology

Here are some of the commonly used terminologies that you may not be familiar with, but they are not specific to Redux per se. You can skim through this section and come back here when/if something doesn't make sense.  

Pure Function

A pure function is just a normal function with two additional constraints that it has to satisfy: 

  1. Given a set of inputs, the function should always return the same output. 
  2. It produces no side effects.

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

/* Pure add function */<br>const add = (x,y) => {<br>  return x y;<br>}<br> <br>console.log(add(2,3)) //5<br><br>
Copy after login

Pure functions give a predictable output and are deterministic. A function becomes impure when it performs anything other than calculating its return value. 

For instance, the add function below uses a global state to calculate its output. In addition, the function also logs the value to the console, which is considered to be a side effect. 

const y = 10;<br><br>const impureAdd = (x) => {<br>  console.log(`The inputs are ${x} and ${y}`);<br>  return x y;<br>}<br>
Copy after login

Observable Side Effects

"Observable side effects" is a fancy term for interactions made by a function with the outside world. If a function tries to write a value into a variable that exists outside the function or tries to call an external method, then you can safely call these things side effects. 

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

  • making API calls
  • logging to console or printing data
  • mutating data
  • DOM manipulation
  • retrieving the current time

Container and Presentational Components

Splitting the component architecture into two is useful while working with React applications. You can broadly classify them into two categories: container components and presentational components. They are also popularly known as smart and dumb components. 

The container component is concerned with how things work, whereas presentational components are concerned with how things look. To understand the concepts better, I've covered that in another tutorial: Container vs. Presentational Components in React.

Mutable vs. Immutable Objects

A mutable object can be defined as follows:

mutable object is an object whose state can be modified after it is created.

Immutability is the exact opposite—an immutable object is an object whose state cannot be modified after it is created. In JavaScript, strings and numbers are immutable, but objects and arrays are not. The example demonstrates the difference better. 

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

To make objects immutable, use the Store.getState()—To access the current state tree of your application. 

  • Store.subscribe(listener)—To listen to any change in the state. It will be called every time an action is dispatched.
  • Let's create a store. Redux has a configureStore method to create a new store. You need to pass it a reducer, although we don't know what that is. So I will just create a function called reducer. You may optionally specify a second argument that sets the initial state of the store. 

    src/index.js

    import { configureStore } from "redux";<br>// This is the reducer<br>const reducer = () => {<br>/*Something goes here */<br>}<br><br>//initialState is optional.<br>//For this demo, I am using a counter, but usually state is an object<br>const initialState = 0<br>const store = configureStore(reducer, initialState);<br>
    Copy after login

    Now we're going to listen to any changes in the store, and then console.log() the current state of the store.

    store.subscribe( () => {<br>    console.log("State has changed"    store.getState());<br>})<br>
    Copy after login

    So how do we update the store? Redux has something called actions that make this happen.

    Action/Action Creators

    Actions are also plain JavaScript objects that send information from your application to the store. If you have a very simple counter with an increment button, pressing it will result in an action being triggered that looks like this:

    {<br>  type: "INCREMENT",<br>  payload: 1<br>}<br>
    Copy after login

    They are the only source of information to the store. The state of the store changes only in response to an action. Each action should have a type property that describes what the action object intends to do. Other than that, the structure of the action is completely up to you. However, keep your action small because an action represents the minimum amount of information required to transform the application state. 

    For instance, in the example above, the type property is set to "INCREMENT", and an additional payload property is included. You could rename the payload property to something more meaningful or, in our case, omit it entirely.  You can dispatch an action to the store like this.

    store.dispatch({type: "INCREMENT", payload: 1});<br>
    Copy after login

    While coding Redux, you won't normally use actions directly. Instead, you will be calling functions that return actions, and these functions are popularly known as action creators. Here is the action creator for the increment action that we discussed earlier.

    const incrementCount = (count) => {<br>  return {<br>    type: "INCREMENT",<br>    payload: count<br>  }<br>}<br>
    Copy after login

    So, to update the state of the counter, you will need to dispatch the incrementCount action like this:

    store.dispatch(incrementCount(1));<br>store.dispatch(incrementCount(1));<br>store.dispatch(incrementCount(1));<br>
    Copy after login

    If you head to the browser console, you will see that it's working, partially. We get undefined because we haven't yet defined the reducer.

    Getting Started With Redux: Why Redux?

    So now we have covered actions and the store. However, we need a mechanism to convert the information provided by the action and transform the state of the store. Reducers serve this purpose.

    Reducers

    An action describes the problem, and the reducer is responsible for solving the problem. In the earlier example, the incrementCount method returned an action that supplied information about the type of change that we wanted to make to the state. The reducer uses this information to actually update the state. There's a big point highlighted in the docs that you should always remember while using Redux:

    Given the same arguments, a Reducer should calculate the next state and return it. No surprises. No side effects. No API calls. No mutations. Just a calculation.

    What this means is that a reducer should be a pure function. Given a set of inputs, it should always return the same output. Beyond that, it shouldn't do anything more. Also, a reducer is not the place for side effects such as making AJAX calls or fetching data from the API. 

    Let's fill in the reducer for our counter.

    // This is the reducer<br><br>const reducer = (state = initialState, action) => {<br>    switch (action.type) {<br>	    case "INCREMENT":<br>	      return state   action.payload<br>	    default:<br>	      return state<br>  }<br>}<br>
    Copy after login

    The reducer accepts two arguments—state and action—and it returns a new state.

    (previousState, action) => newState<br>
    Copy after login

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

    Let's add a case for DECREMENT, without which the counter is incomplete.

    // This is the reducer<br><br>const reducer = (state = initialState, action) => {<br>    switch (action.type) {<br>        case "INCREMENT":<br>	      return state   action.payload<br>        case "DECREMENT":<br>          return state - action.payload<br>	    default:<br>	      return state<br>  }<br>}<br>
    Copy after login

    Here's the action creator.

    const decrementCount = (count) => {<br>  return {<br>    type: "DECREMENT",<br>    payload: count<br>  }<br>}<br>
    Copy after login

    Finally, dispatch it to the store.

    store.dispatch(incrementCount(4)); //4<br>store.dispatch(decrementCount(2)); //2<br>
    Copy after login

    That's it!

    Summary

    This tutorial was meant to be a starting point for managing state with Redux. We've covered everything essential needed to understand the basic Redux concepts such as the store, actions, and reducers. Towards the end of the tutorial, we also created a working redux demo counter. Although it wasn't much, we learned how all the pieces of the puzzle fit together. 

    Over the last couple of years, React has grown in popularity. In fact, we have a number of items in the marketplace that are available for purchase, review, implementation, and so on. If you’re looking for additional resources around React, don’t hesitate to check them out.

    In the next tutorial, we will make use of the things we've learned here to create a React application using Redux. Stay tuned until then. Share your thoughts in the comments. 

    The above is the detailed content of Getting Started With Redux: Why Redux?. For more information, please follow other related articles on the PHP Chinese website!

    Statement of this Website
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
    Latest Articles by Author
    Popular Tutorials
    More>
    Latest Downloads
    More>
    Web Effects
    Website Source Code
    Website Materials
    Front End Template