---
myst:
html_meta:
"description": "Add redux to our App for managing the state throughout the App."
"property=og:description": "Add redux to our App for managing the state throughout the App."
"property=og:title": "Use Redux to Store Data"
"keywords": "Plone, training, exercise, solution, React, Redux"
---
(redux-label)=
# Use Redux To Store Data
## Introduction
Currently we have the state of the FAQ list in the `App` component and pass all handlers and data down to the `FaqItem` component.
When your application will contain more subcomponents, this can become very complex.
To manage your application state, we will introduce Redux here.
Redux is a state management system which is composed of a store.
This store contains data, a set of reducers which handle (part of) this state and its changes, and actions which are used to trigger state changes.
A reducer is pure function which takes the previous state and an action, and returns a new state based on the data of the action.
The new state is then saved to the store.
Components can then read data from the store and render a view.
When a change needs to be made to the application state, the view will fire an action which will be handled by the reducer again, and so on.
This is a unidirectional flow.
## Installing
To install Redux, we will run the following command:
```shell
yarn add redux react-redux
```
## Actions
We will start by creating actions.
We will create a file {file}`actions/index.js` with the `addFaqItem` action:
```{code-block} jsx
:emphasize-lines: 1-5
:linenos:
export const addFaqItem = (question, answer) => ({
type: "ADD_FAQ_ITEM",
question,
answer
});
```
Write the `editFaqItem` and `deleteFaqItem` actions.
````{dropdown} Solution
:animate: fade-in-slide-down
:icon: question
```{code-block} jsx
:emphasize-lines: 1-6,8-11
:lineno-start: 7
:linenos:
export const editFaqItem = (index, question, answer) => ({
type: "EDIT_FAQ_ITEM",
index,
question,
answer
});
export const deleteFaqItem = index => ({
type: "DELETE_FAQ_ITEM",
index
});
```
````
## Reducers
Next we will create the reducer by creating the `reducers/faq.js` file.
As stated earlier, a reducer is a pure function which takes the previous state and an action, and returns the new state.
It will look like this:
```{code-block} jsx
:emphasize-lines: 1-3,5
:linenos:
const faq = (state = [], action) => {
// Do something
};
export default faq;
```
Finish the reducer so that it can handle the `ADD_FAQ_ITEM`, `EDIT_FAQ_ITEM`, and `DELETE_FAQ_ITEM` actions.
````{dropdown} Solution
:animate: fade-in-slide-down
:icon: question
```{code-block} jsx
:emphasize-lines: 2-25
:linenos:
const faq = (state = [], action) => {
let faq;
switch (action.type) {
case "ADD_FAQ_ITEM":
return [
...state,
{
question: action.question,
answer: action.answer
}
];
case "EDIT_FAQ_ITEM":
faq = [...state];
faq[action.index] = {
question: action.question,
answer: action.answer
};
return faq;
case "DELETE_FAQ_ITEM":
faq = [...state];
faq.splice(action.index, 1);
return faq;
default:
return state;
}
};
export default faq;
```
````
## Combine Multiple Reducers
When our application grows, we will have multiple reducers handling a specific part of the data.
We will combine all reducers into one index reducer, such that we can set all reducers in one store.
We will create the file {file}`reducers/index.js`.
```{code-block} jsx
:emphasize-lines: 1-2,4-6
:linenos:
import { combineReducers } from "redux";
import faq from "./faq";
export default combineReducers({
faq
});
```