DEV Community

Cover image for Setting up Redux in React with Redux Toolkit
josesrodriguez610
josesrodriguez610

Posted on • Updated on

Setting up Redux in React with Redux Toolkit

Alright so imagine you have this code

import React, { useState } from "react";
import Layer2 from "./components/Layer2";


function App() {

  const [user, setUser] = useState('');


  return (
    <div>
      <h1>Hello my name is </h1>
      <input type="text" value={user} onChange={(e) => setUser(e.target.value)} />
      <br />
      {user}
      <Layer2 />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Very simple code:
You are writing in the input your name and it saves it to user and displays it in the page.
The onChange is setting up the value to your user state.

Alt Text

The user state is in App.js

What if we wanted to display it for some reason in Layer4?
What would you do?

You can pass it as a prop from App.js to Layer2 and then to Layer3 and then to Layer 4.

This is call Prop Drilling.

 
Prop drilling is when you want to get data from a parent component but you are way down your tree line leaving you with the only option to pass your prop through all the other components and the only reason you are using those components is to pass data.

Of course you can do that but when you start working on bigger projects it can get messy and that’s when we use Redux.

Redux will give you the option to access the state from anywhere.

Alt Text

Today we are going to set up Redux with redux toolkit which is a utility that
simplifies common use cases like store setup, creating reducers, immutable update logic, and more.

This library is very powerful because it lets you write "mutative" immutable update logic, and even create entire "slices" of state automatically.

It is very effective because it lets you focus on the core logic your app needs, so you can do more work with less code.

The Redux Toolkit 

This package is the standard way to write Redux logic. It was created to help address three problems about Redux:

  • Configuring the store is very complicated
  • Too many packages to make it work
  • requires too much boilerplate code

Let’s create redux for our existing project


npm install @reduxjs/toolkit

npm install react-redux
Enter fullscreen mode Exit fullscreen mode

Then let’s create two folders inside our src folder. A folder called app with a store.js and a features folder with a userSlice.js. All state gets separated by slices and because we are going to keep track of the user state we will put all our logic inside our userSlice.js

Alt Text

Now lets go to our index.js
Lets import our store and Provider from react-redux
And let’s wrap our App.js with Provider that comes from Redux

import React from "react";
import ReactDOM from "react-dom";
import App from "./App.js";
import store from './app/store';
import { Provider } from 'react-redux';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>
  , document.getElementById("root"));

Enter fullscreen mode Exit fullscreen mode

Provider will make the Redux store available to any nested component

Now let’s go to userSlice.js

Let’s import createSlice and let’s create a new slice.

import { createSlice } from '@reduxjs/toolkit';

export const userSlice = createSlice({

  });
Enter fullscreen mode Exit fullscreen mode

Let’s give it a name and an initial value

import { createSlice } from '@reduxjs/toolkit';

export const userSlice = createSlice({
  name: 'user',
  initialState: {
    user: null,
  },

});
Enter fullscreen mode Exit fullscreen mode

Now we have to add reducers. Reducers specify how the application’s state changed in response to actions sent to the store.

import { createSlice } from '@reduxjs/toolkit';

export const userSlice = createSlice({
  name: 'user',
  initialState: {
    user: null,
  },
  reducers: {
    setUser: (state, action) => {
      state.user = action.payload;
    }
  },
});
Enter fullscreen mode Exit fullscreen mode

Here we are setting up setUser to change the initialState user to an action sent to the store

Now we need to export a couple of things.

We have to export setUser, we have to make a function that access the store and we will call it selectUser and we will export userSlice reducer to use it in the store.

import { createSlice } from '@reduxjs/toolkit';

export const userSlice = createSlice({
  name: 'user',
  initialState: {
    user: null,
  },
  reducers: {
    setUser: (state, action) => {
      state.user = action.payload;
    }
  },
});

export const { setUser } = userSlice.actions;

export const selectUser = state => state.user.user;

export default userSlice.reducer;
Enter fullscreen mode Exit fullscreen mode

Now lets go to store.js and let’s import configureStore from @reduxjs/toolkit and let’s get the reducer from userSlice.js
And let’s add it to our store

import { configureStore } from '@reduxjs/toolkit';
import userReducer from '../features/userSlice';

export default configureStore({
  reducer: {
    user: userReducer,
  },
});
Enter fullscreen mode Exit fullscreen mode

Now we can use Redux in our project. For example let’s go to App.js and let’s save a user to our Redux state.

We are going to import setUser and useDispatch. Dispatch will help us send information to the store.
We’ll initialize useDispatch and we will change our onChange to accept a dispatch and the setUser function and this will add whatever we write in the input to the Redux store.

import React from "react";
import Layer2 from "./components/Layer2";
import { useDispatch } from "react-redux";
import { setUser } from "./features/userSlice";


function App() {

  const dispatch = useDispatch();

  const handleChange = (e) => {
    dispatch(setUser(e.target.value))
  }


  return (
    <div>
      <h1>Hello my name is </h1>
      <input type="text" onChange={handleChange} />
      <Layer2 />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

We can check it by going to our Redux devtools in the console

Alt Text

Now we can finally move our user information through our app.

Let’s go to Layer4 and let’s access our Redux Store

import React from 'react'

function Layer4() {
  return (
    <div>
      <h1>Layer 4</h1>
    </div>
  );
}

export default Layer4
Enter fullscreen mode Exit fullscreen mode

We are going to need to import useSelector from react-redux and selectUser from our userSlice.js which will help us access the store

We we’ll create a variable call user which will contain the user information saved in Redux

And then we are going to display the user

import React from 'react'
import { useSelector } from "react-redux";
import { selectUser } from "../features/userSlice"

function Layer4() {

  const user = useSelector(selectUser);

  return (
    <div>
      <h1>Layer 4</h1>
      <h1>{user}</h1>
    </div>
  );
}

export default Layer4
Enter fullscreen mode Exit fullscreen mode

Now if we type something in our input from App.js we will be able to access it in our Layer4.js component

Alt Text

That’s it, now you can move data around!

Conclusion

Redux works very well when you are building a big application because it takes away the headache of passing props around many components.

Top comments (2)

Collapse
 
oldskool123 profile image
Lennea

Awesome!!
I'm new to toolkit and been trying to setup same example as above but instead with two inputs. How would you approach handling multiple inputs with one slice/ reducer?

And is it better to set data to store on submit instead of on change?

Collapse
 
codeonjim profile image
CodeOnJIm

Thank you!! Toolkit can be quite confusing at first.