visit
Last month I started making some implementations of Redux in some React projects. In the beginning, it took me a while to understand how to set up everything. Because it is a little complex to set up. But it will help a lot to store the data of an app.
Let's start talking about what is Redux. Well, Redux is a predictable state container for JavaScript apps. It makes easier to manage the state of your application. In lees worlds, it helps you manage the data you display and how you respond to user actions.
So in this article, a will explain how is the easy way to set up Redux in a React App.
So when we run in the terminal
npx create-react-app mynameapp
to create our React App.Then we need to install redux and react-redux which is going to make most of the work for us.
We run in terminal
npm i redux react-redux
The first step that we need to is to make some imports in our ./src/index.js
The createStore is going to help up to initialize our store
import { createStore } from 'redux';
The Provider is going to help us to pass the store to all the components in our app.
import { Provider } from 'react-redux';
Then we need to import all our reducers. The reducers specify how the application's state changes in response to actions sent to the store.
import allReducers from './reducers';
- this line will import the index.js that is inside the reducer folder.In the next line, we initialize our store passing all the reducer that we have.
const store = createStore(allReducers);
Then we use the Provider component that we import to pass the store to all the child components, wrapping the App component that is our principal component. And we pass the store as a prop.
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root'),
);
After we set up everything on our ./src/index.js we are going to create our reducers in the reducers folder.
we need to create one file per reducer that we have. In the reducer, we are going to explain what the action that reducer can receive and how it needs to process it.
For example, in the next reducer that I call filter, I'm going to store in the state a string and I will initialize with an empty string. Also, we will pass in the argument the action that is going to be processed.
Each action is an object with properties the type that is going to indicate to reducer with action needs to be executed and the payload that is any additional data that the reducer will need.
const filter = (state = '', action) => {
switch (action.type) {
case 'CHANGE_FILTER':
return action.payload;
default:
return state;
}
};
export default filter;
In this sample, we are expecting only one type of action. That is CHANGE_FILTER. so when the reducer receives that action we will change the state with the payload that we send. For example, if we send in the payload the string "hello world" that is going to be our new state.
One very important rule is that we can not mutate our state we always need to replace it.
Here is another example of a reducer but in this case, I store an array and initialize that array with two elements that are objects. Also, this reducer has two actions CREATE_BOOK to add a new book and REMOVE_BOOK to remove a book from the array.
const book1 = {
id: Math.floor(Math.random() * 100) + 1,
title: 'The Martian',
category: 'Sci-Fi',
};
const book2 = {
id: Math.floor(Math.random() * 100) + 1,
title: 'Harry Poter',
category: 'Kid',
};
const books = (state = [book1, book2], action) => {
switch (action.type) {
case 'CREATE_BOOK':
return [
...state, action.payload,
];
case 'REMOVE_BOOK':
return state.filter(book => book.id !== action.payload);
default:
return state;
}
};
export default books;
After we set up our reducers we need to combine them in one
so we need to specify that in ./src/reducers/index.js in this way. Inside combineReducers argument is an object with the different reducer that we have.
import { combineReducers } from 'redux';
import books from './books';
import filter from './filter';
const allReducers = combineReducers({
books,
filter,
});
export default allReducers;
Well, we already set up our reducer right now we need to create our actions. Remember that actions only describe what happened, but don't describe how the application's state changes.
So we create an action folder and inside that folder, we will create an index.js in this file we will add our different actions. For example:
export const createBook = value => ({
type: 'CREATE_BOOK',
payload: value,
});
export const removeBook = value => ({
type: 'REMOVE_BOOK',
payload: value,
});
export const changeFilter = value => ({
type: 'CHANGE_FILTER',
payload: value,
});
Each function returns an object with the two properties type and payload. The payload will be a value that we pass in the argument. In the first one is an object. The second one is an integer and in the third one is a string.
After we finish setting up our action we are ready to use our store in the components.
To read the information in our store we need to import useSelector from react-redux.
import { useSelector } from 'react-redux'
Then we are going to create a variable to save the state that we require so we can use it as we want with the next line.
const books = useSelector(state => state.books);
const filter = useSelector(state => state.filter);
Then if we want to change the state we need to import useDispatch from react-redux to be able to change our state.
Also, we will need to import the action to indicate what we want to do.
import {useDispatch} from 'react-redux'
import {createBook} from '../actions'
Then we need to use the next line to create a dispatch function.
const dispatch = useDispatch();
We are ready to change our state with the next function
dispatch(createBook(book));
In this case, we dispatch de createBook action with the book argument to add a new book to the array.
And this way we can easily implement redux with react.