Before going to the topic "Redux Change of State" we should look at the question "What is Redux?".
"A Predictable State Container for JS Apps"
In other words, Redux is a pattern-based library that is used to manage and update the application state. For managing and updating the application state Redux used events known as "action".
Redux has some properties which make it popular some of them are described below:
- Redux has the predictable property means it can run in different environments like the client, server, and native.
- Redux Centralized the application state from which you can easily perform actions like undo, redo, state persistence, and many more.
- Redux also has the property of debugging. In other words, Redux has Redux Devtools which make applications easily debuggable like when, where, why, and how your application state is changed.
- Also Redux has the property of flexibility means it can work on any type of UI layer.
Let's take an example to understand redux easily. Let's imagine an application like a food app where we can manage the recipe using the Redux Store. For managing the recipe in the application we have some basic methods which help us to do so like:
We have a single store to manage the whole state of the application. Also, actions method to make necessary changes, we want to do. Reducers are like safety guards that know how to mutate state based on the requested action. And at least middleware is used to handle the task performed in the application.
REDUX OVERVIEW
As earlier as time spend the application grows at a large level. At this time management of the state and debugging the state is a very huge task for the application. It is also a challenge to manage the state and find where and when the state of the application is changed. Sometimes when the client calls some API or do changes to some data it turns some updates on the state of the application. So, for this, we need a model or management system which tracks the state of the application. For this Redux has been used because Redux is the state predictable container. For providing this service Redux used many components which are described below:
1. Redux Store: In Redux, the Redux store is the main component(first fundamental principle) of the Redux. Because all the things maintain the in the application by the Redux store. Redux store is a single store that stores the all state of the application and data. Any change which is happened in the Redux store is reflected in the whole application. So for making the necessary changes in the state we do the following steps:
Step 1: Store The Application State
The working of the store is:
- First of all, the Redux store gets information about the application state.
- Then it stores the change that happens in the state.
- After this store changes the necessary changes in the state of the application.
CHANGE OF STATE
The function described in the Redux State which helps us in state management are given below:
- getState() is the function used for getting information about the current state of the application.
- For updating the state Redux is use dispatch(action). This is the one function used for making updates in the application.
- After this Store listens to the changes in the state. For this Redux used subscribe (listener) which sees the changes and updated state.
Now we are able to store the current state of the application. Next, we have to update the state for the next changes occurred in the state of the application.
Step 2: Updating the state of the application. For making the necessary changes or we can say for making the updates in the state of the application, we use an action. Action is the main component of Redux because it has a special property known as type property which helps Redux to know about the changes that going to happen in the state of the application. So for this, we can say that Action has a descriptive property type.
For example, let have to design the bookstore application. Then user wants to add a book to the store. For we use the action function for making changes in the store. Action call the type property as given below:
{ type: "ADD_BOOK" }
For this, we use the store.dispatch() function. That function is used by the library for accepting the action to perform in the state. This is the 2nd principle of the Redux fundamentals.
Now by all of this, we are able to make the update in the state of the application. Now we use the function for making the actually update by using these actions.
Step 3: Make changes by reducers. For making the changes in the state of applications, we use the pure function. These functions used the current state as a parameter and action to do changes. And after this return the updated state of the application. These functions are known as Reducers. These are the function which doesn't manipulate the state of the application while they make changes in the new object. From this, we are able to manage them or keep track of the changes in the state of the application. The main work of the reducers is that collect some values, reduce them to an updated state and then return it.
So after all, we are able to make changes to the application. And also keep track of every state with the help of Store, Reducers, And Actions.
Let's discuss the redux change of state with an example:
Example: In this section, we are going to discuss an example of a redux change of state. The required steps are described below: Here we are going to design a react-redux app that is used to perform the to-do task. So, for that we have to perform the following steps:
Step 1: For creating the new react app we have to perform the following code in the terminal:
npx create-react-app todo
Step 2: Now, after creating and performing the above code in the terminal we have a folder named by todo. After this again go to the terminal and type:
cd todo
By this, we can say that terminal is now pointing to the todo folder files.
structure of the redux todo app
Step 3: Here we are going to create the package .json file which is mainly used for defining the dependencies that we are going to use in the project. That's why we are creating this file.
package.json:
{
"name": "todos",
"version": "0.0.1",
"private": true,
"devDependencies": {
"react-scripts": "^4.0.3"
},
"dependencies": {
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.0",
"redux": "^4.0.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"eject": "react-scripts eject",
"test": "react-scripts test --env=node"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
After defining the dependencies, we have to install them by typing the following code in the terminal:
Note: This is suggested that working on the project we use the terminal, for starting the server or the second one for installing the necessary dependencies.
npm install
Step 4: Creating Necessary files. After all the above steps we have the following files in our todo folder:
- node_modules
- public
- src
- package-lock.json
- package.json
Now, delete all the files present in the public and src files. So, after performing these things we are going to create the following files:
In the public folder create the file index.html. index.html the file is basically a file that is used to fetch all the data required for the app. It is the main page of the application.
index.html
HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content=
"width=device-width, initial-scale=1">
<title>Redux Todo List</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Now, we are going to create the following folder and files:
- actions
- components
- containers
- reducers
- index.js
index.js file: It is the file that is used to fetch the data of all the files like a store, reducers, action, etc. Or we can say that it is the store of the react-redux application. All containers need to access it for fetching the data for further processing like updating, changing, and many more things.
JavaScript
import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './components/App'
import rootReducer from './reducers'
const store = createStore(rootReducer)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
In the actions folder, we use the property known as "type" which is used for informing about the data that is sent to the store. We are going to create the following files:
index.js file: In this file, an action is created that we are wanted to create and it also provides its id(unique number or identity). And here also define the visibility filter active of the current action.
JavaScript
let nextTodoId = 0
export const addTodo = text => ({
type: 'ADD_TODO',
id: nextTodoId++,
text
})
export const setVisibilityFilter = filter => ({
type: 'SET_VISIBILITY_FILTER',
filter
})
export const toggleTodo = id => ({
type: 'TOGGLE_TODO',
id
})
export const VisibilityFilters = {
SHOW_ALL: 'SHOW_ALL',
SHOW_COMPLETED: 'SHOW_COMPLETED',
SHOW_ACTIVE: 'SHOW_ACTIVE'
}
index.spec.js:
JavaScript
import * as actions from './index'
describe('todo actions', () => {
it('addTodo should create ADD_TODO action', () => {
expect(actions.addTodo('Use Redux')).toEqual({
type: 'ADD_TODO',
id: 0,
text: 'Use Redux'
})
})
it('setVisibilityFilter should create
SET_VISIBILITY_FILTER action', () => {
expect(actions.setVisibilityFilter('active')).toEqual({
type: 'SET_VISIBILITY_FILTER',
filter: 'active'
})
})
it('toggleTodo should create TOGGLE_TODO action', () => {
expect(actions.toggleTodo(1)).toEqual({
type: 'TOGGLE_TODO',
id: 1
})
})
})
Step 5: After this, we are going to create the following files in the components folder:
- App.js
- Footer.js
- Link.js
- Todo.js
- TodoList.js
The component folder is a presentation of the react-redux application which means it is the component folder we define such files which are concerned about the look of the application like style, layout, and many more. It is only used for receiving the data and rendering it via props.
App.js file: It is the main or we can say that the root component that is received needs to be rendered on the application UI.
JavaScript
import React from 'react'
import Footer from './Footer'
import AddTodo from '../containers/AddTodo'
import VisibleTodoList from '../containers/VisibleTodoList'
const App = () => (
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
</div>
)
export default App
Footer.js file: In this file or it decided where the changes should be visible in the application made by the user.
JavaScript
import React from 'react'
import FilterLink from '../containers/FilterLink'
import { VisibilityFilters } from '../actions'
const Footer = () => (
<div>
<span>Show: </span>
<FilterLink filter={VisibilityFilters.SHOW_ALL}>
All
</FilterLink>
<FilterLink filter={VisibilityFilters.SHOW_ACTIVE}>
Active
</FilterLink>
<FilterLink filter={VisibilityFilters.SHOW_COMPLETED}>
Completed
</FilterLink>
</div>
)
export default Footer
Link.js file: It is used for using the callback function which is decided the action current state, for example, active, completed, etc.
JavaScript
import React from 'react'
import PropTypes from 'prop-types'
const Link = ({ active, children, onClick }) => (
<button
onClick={onClick}
disabled={active}
style={{
marginLeft: '4px',
}}
>
{children}
</button>
)
Link.propTypes = {
active: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired,
onClick: PropTypes.func.isRequired
}
export default Link
Todo.js file: It is used to represent the todo(single) item.
JavaScript
import React from 'react'
import PropTypes from 'prop-types'
const Todo = ({ onClick, completed, text }) => (
<li
onClick={onClick}
style={{
textDecoration: completed ? 'line-through' : 'none'
}}
>
{text}
</li>
)
Todo.propTypes = {
onClick: PropTypes.func.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}
export default Todo
TodoList.js file: It is used to show the todos available in the current state. that is in the form of {id , text , completed}
JavaScript
import React from 'react'
import PropTypes from 'prop-types'
import Todo from './Todo'
const TodoList = ({ todos, toggleTodo }) => (
<ul>
{todos.map(todo =>
<Todo
key={todo.id}
{...todo}
onClick={() => toggleTodo(todo.id)}
/>
)}
</ul>
)
TodoList.propTypes = {
todos: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.number.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}).isRequired).isRequired,
toggleTodo: PropTypes.func.isRequired
}
export default TodoList
Now, we are going to create the following files in the containers folder:
- AddTodo.js
- FilterLink.js
- VisibleTodoList.js
In the container component, as we learned above that it is always concerned about the things working means how the data is fetching to other files or how updates are happening. It provides the data to components or we can say that layout data to the component that are rendered in the UI. It also used redux state functionality to read and dispatch the redux action for updating the data in the current UI components.
AddTodo.js file: It contains the to-do text which user wants to add to the to-do list through an ADD(Submit) button.
JavaScript
import React from 'react'
import { connect } from 'react-redux'
import { addTodo } from '../actions'
const AddTodo = ({ dispatch }) => {
let input
return (
<div>
<form onSubmit={e => {
e.preventDefault()
if (!input.value.trim()) {
return
}
dispatch(addTodo(input.value))
input.value = ''
}}>
<input ref={node => input = node} />
<button type="submit">
Add Todo
</button>
</form>
</div>
)
}
export default connect()(AddTodo)
FilerLink.js file: It is used to set the visibility filter that needs to be set on the current state of the to-do item.
JavaScript
import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'
const mapStateToProps = (state, ownProps) => ({
active: ownProps.filter === state.visibilityFilter
})
const mapDispatchToProps = (dispatch, ownProps) => ({
onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Link)
VisibleTodoList.js file: It filters the item and rendered it on the application page.
JavaScript
import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'
import { VisibilityFilters } from '../actions'
const getVisibleTodos = (todos, filter) => {
switch (filter) {
case VisibilityFilters.SHOW_ALL:
return todos
case VisibilityFilters.SHOW_COMPLETED:
return todos.filter(t => t.completed)
case VisibilityFilters.SHOW_ACTIVE:
return todos.filter(t => !t.completed)
default:
throw new Error('Unknown filter: ' + filter)
}
}
const mapStateToProps = state => ({
todos: getVisibleTodos(state.todos, state.visibilityFilter)
})
const mapDispatchToProps = dispatch => ({
toggleTodo: id => dispatch(toggleTodo(id))
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
Step 6: Now, are going to create the following files in the reducers folder:
- index.js
- todos.js
- todos.spec.js
- visibilityFilter.js
As we learn above, actions are only used to make changes in the app, and reducers it used to render that changes in the application. Hence, a reducer is a function that takes two parameters 'Action' and 'State'. It reads the data sent by the action and updates it in the 'store' vie redux functionality.
index.js file:
JavaScript
import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'
export default combineReducers({
todos,
visibilityFilter
})
todos.js file:
JavaScript
const todos = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
]
case 'TOGGLE_TODO':
return state.map(todo =>
(todo.id === action.id)
? { ...todo, completed: !todo.completed }
: todo
)
default:
return state
}
}
export default todos
todos.spec.js file:
JavaScript
import todos from './todos'
describe('todos reducer', () => {
it('should handle initial state', () => {
expect(
todos(undefined, {})
).toEqual([])
})
it('should handle ADD_TODO', () => {
expect(
todos([], {
type: 'ADD_TODO',
text: 'Run the tests',
id: 0
})
).toEqual([
{
text: 'Run the tests',
completed: false,
id: 0
}
])
expect(
todos([
{
text: 'Run the tests',
completed: false,
id: 0
}
], {
type: 'ADD_TODO',
text: 'Use Redux',
id: 1
})
).toEqual([
{
text: 'Run the tests',
completed: false,
id: 0
}, {
text: 'Use Redux',
completed: false,
id: 1
}
])
expect(
todos([
{
text: 'Run the tests',
completed: false,
id: 0
}, {
text: 'Use Redux',
completed: false,
id: 1
}
], {
type: 'ADD_TODO',
text: 'Fix the tests',
id: 2
})
).toEqual([
{
text: 'Run the tests',
completed: false,
id: 0
}, {
text: 'Use Redux',
completed: false,
id: 1
}, {
text: 'Fix the tests',
completed: false,
id: 2
}
])
})
it('should handle TOGGLE_TODO', () => {
expect(
todos([
{
text: 'Run the tests',
completed: false,
id: 1
}, {
text: 'Use Redux',
completed: false,
id: 0
}
], {
type: 'TOGGLE_TODO',
id: 1
})
).toEqual([
{
text: 'Run the tests',
completed: true,
id: 1
}, {
text: 'Use Redux',
completed: false,
id: 0
}
])
})
})
visibilityFilter.js file:
JavaScript
import { VisibilityFilters } from '../actions'
const visibilityFilter = (state = VisibilityFilters.SHOW_ALL, action) => {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter
default:
return state
}
}
export default visibilityFilter
Step to run the application: After performing the above steps, we completed our redux management app. To, start the app we should type in the terminal.
npm start
Output:
OUTPUT OF THE TODO APP
Similar Reads
React Tutorial React is a powerful JavaScript library for building fast, scalable front-end applications. Created by Facebook, it's known for its component-based structure, single-page applications (SPAs), and virtual DOM,enabling efficient UI updates and a seamless user experience.Note: The latest stable version
7 min read
React Fundamentals
React IntroductionReactJS is a component-based JavaScript library used to build dynamic and interactive user interfaces. It simplifies the creation of single-page applications (SPAs) with a focus on performance and maintainability.React.jsWhy Use React?Before React, web development faced issues like slow DOM updates
8 min read
React Environment SetupTo run any React application, we need to first setup a ReactJS Development Environment. In this article, we will show you a step-by-step guide to installing and configuring a working React development environment.Pre-requisite:We must have Nodejs installed on our PC. So, the very first step will be
3 min read
React JS ReactDOMReactDom is a core react package that provides methods to interact with the Document Object Model or DOM. This package allows developers to access and modify the DOM. Let's see in brief what is the need to have the package. Table of ContentWhat is ReactDOM ?How to use ReactDOM ?Why ReactDOM is used
3 min read
React JSXJSX stands for JavaScript XML, and it is a special syntax used in React to simplify building user interfaces. JSX allows you to write HTML-like code directly inside JavaScript, enabling you to create UI components more efficiently. Although JSX looks like regular HTML, itâs actually a syntax extensi
6 min read
ReactJS Rendering ElementsIn this article we will learn about rendering elements in ReactJS, updating the rendered elements and will also discuss about how efficiently the elements are rendered.What are React Elements?React elements are the smallest building blocks of a React application. They are different from DOM elements
3 min read
React ListsReact Lists are used to display a collection of similar data items like an array of objects and menu items. It allows us to dynamically render the array elements and display repetitive data.Rendering List in ReactTo render a list in React, we will use the JavaScript array map() function. We will ite
5 min read
React FormsForms are an essential part of any application used for collecting user data, processing payments, or handling authentication. React Forms are the components used to collect and manage the user inputs. These components include the input elements like text field, check box, date input, dropdowns etc.
5 min read
ReactJS KeysA key serves as a unique identifier in React, helping to track which items in a list have changed, been updated, or removed. It is particularly useful when dynamically creating components or when users modify the list. In this article, we'll explore ReactJS keys, understand their importance, how the
5 min read
Components in React
React ComponentsIn React, React components are independent, reusable building blocks in a React application that define what gets displayed on the UI. They accept inputs called props and return React elements describing the UI.In this article, we will explore the basics of React components, props, state, and render
4 min read
ReactJS Functional ComponentsIn ReactJS, functional components are a core part of building user interfaces. They are simple, lightweight, and powerful tools for rendering UI and handling logic. Functional components can accept props as input and return JSX that describes what the component should render.What are Reactjs Functio
5 min read
React Class ComponentsClass components are ES6 classes that extend React.Component. They allow state management and lifecycle methods for complex UI logic.Used for stateful components before Hooks.Support lifecycle methods for mounting, updating, and unmounting.The render() method in React class components returns JSX el
4 min read
ReactJS Pure ComponentsReactJS Pure Components are similar to regular class components but with a key optimization. They skip re-renders when the props and state remain the same. While class components are still supported in React, it's generally recommended to use functional components with hooks in new code for better p
4 min read
ReactJS Container and Presentational Pattern in ComponentsIn this article we will categorise the react components in two types depending on the pattern in which they are written in application and will learn briefly about these two categories. We will also discuss about alternatives to this pattern. Presentational and Container ComponentsThe type of compon
2 min read
ReactJS PropTypesIn ReactJS PropTypes are the property that is mainly shared between the parent components to the child components. It is used to solve the type validation problem. Since in the latest version of the React 19, PropeTypes has been removed. What is ReactJS PropTypes?PropTypes is a tool in React that he
5 min read
React Lifecycle In React, the lifecycle refers to the various stages a component goes through. These stages allow developers to run specific code at key moments, such as when the component is created, updated, or removed. By understanding the React lifecycle, you can better manage resources, side effects, and perfo
7 min read
React Hooks
Routing in React
Advanced React Concepts
React Projects