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>
);
}
```
**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](https://dev-to-uploads.s3.amazonaws.com/i/ttuvxr81j5z7jobr7szo.png)
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.
**<h2>This is call Prop Drilling.</h2>**
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](https://dev-to-uploads.s3.amazonaws.com/i/wsntd3v9ra99hth6npt9.png)
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
**<h2>Let’s create redux for our existing project</h2>**
````javascript
npm install @reduxjs/toolkit
npm install react-redux
```
{% endraw %}
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](https://dev-to-uploads.s3.amazonaws.com/i/2i5bhpkueg0a37qthjgt.png)
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
{% raw %}
````javascript
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"));
```
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.
````javascript
import { createSlice } from '@reduxjs/toolkit';
export const userSlice = createSlice({
});
```
{% endraw %}
Let’s give it a name and an initial value
{% raw %}
````javascript
import { createSlice } from '@reduxjs/toolkit';
export const userSlice = createSlice({
name: 'user',
initialState: {
user: null,
},
});
```
Now we have to add reducers. Reducers specify how the application’s state changed in response to actions sent to the store.
````javascript
import { createSlice } from '@reduxjs/toolkit';
export const userSlice = createSlice({
name: 'user',
initialState: {
user: null,
},
reducers: {
setUser: (state, action) => {
state.user = action.payload;
}
},
});
```
{% endraw %}
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.
{% raw %}
````javascript
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;
```
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
````javascript
import { configureStore } from '@reduxjs/toolkit';
import userReducer from '../features/userSlice';
export default configureStore({
reducer: {
user: userReducer,
},
});
```
{% endraw %}
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.
{% raw %}
````javascript
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;
```
We can check it by going to our Redux devtools in the console
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/uuc6qgwhm22hhgl5xc1c.png)
Now we can finally move our user information through our app.
Let’s go to Layer4 and let’s access our Redux Store
````javascript
import React from 'react'
function Layer4() {
return (
<div>
<h1>Layer 4</h1>
</div>
);
}
export default Layer4
```
{% endraw %}
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
{% raw %}
````javascript
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
```
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](https://dev-to-uploads.s3.amazonaws.com/i/di58p5l1juv7gsg2zpj7.png)
That’s it, now you can move data around!
**<h2>Conclusion</h2>**
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)
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?
Thank you!! Toolkit can be quite confusing at first.