Introduction

Reducer
The reducer is a pure function that takes the previous state and an action, and returns the next state. (previousState, action) => nextState. It's called a reducer because it's the type of function you would pass to Array.prototype.reduce (reducer, ?initialValue) .
Dispatch
dispatch() is the method used to dispatch actions and trigger state changes to the store. react-redux is simply trying to give you convenient access to it. Note, however, that dispatch is not available on props if you do pass it in actions to your connect function.
Step By Step CRUD operation
- import React from 'react';
- import ReactDOM from 'react-dom';
- import App from './App';
- import { Provider } from 'react-redux';
- import { createStore, applyMiddleware } from 'redux';
- import thunk from "redux-thunk";
- import * as serviceWorker from './serviceWorker';
- import reducer from './Redux/reducer';
- const store = createStore(reducer, applyMiddleware(thunk));
- ReactDOM.render(
- <Provider store={store}>
- <App />
- </Provider>, document.getElementById('root'));
- // If you want your app to work offline and load faster, you can change
- // unregister() to register() below. Note this comes with some pitfalls.
- // Learn more about service workers: http://bit.ly/CRA-PWA
- serviceWorker.unregister();
- LIST OF EMPLOYEE
- ADD EMPLOYEE
- EDIT EMPLOYEE
- DELETE EMPLOYEE
LIST OF EMPLOYEES
- const initialstate = {
- employees: [
- { id: 1, employeeName: "Employee 1", employeeDepartment: ".NET Team" },
- { id: 2, employeeName: "Employee 2", employeeDepartment: "Mobile Team" },
- { id: 3, employeeName: "Employee 3", employeeDepartment: "Design Team" }
- ]
- };
- const reducer = (state = initialstate, action) => {
- switch (action.type) {
- case 'GET_EMPLOYEE':
- return {
- ...state
- };
- default:
- return state;
- }
- };
- export default reducer;
- export function getEmployee() {
- return dispatch => {
- return dispatch({
- type: 'GET_EMPLOYEE'
- });
- }
- };
- import React, { Component } from "react";
- import logo from "./logo.svg";
- import "./App.css";
- import PropTypes from 'prop-types';
- import { getEmployee } from './Redux/action';
- import { connect } from 'react-redux';
- const mapStateToProps = state => ({
- employees: state.employees
- });
- class App extends Component {
- constructor(props) {
- super(props);
- }
- static propTypes = {
- employees: PropTypes.array.isRequired,
- getEmployee: PropTypes.func.isRequired
- };
- componentDidMount() {
- this.props.getEmployee();
- }
- render() {
- return (
- <div className="App">
- <header className="App-header">
- <img src={logo} className="App-logo" alt="logo" />
- <h1 className="App-title">CRUD opeartions for Employee Module</h1>
- </header>
- <p className="App-intro">
- <div className="rightsection">
- <table>
- <thead>
- <tr>
- <th>ID</th>
- <th>Name</th>
- <th>Depatment Name</th>
- <th>Action(s)</th>
- </tr>
- </thead>
- <tbody>
- {this.props.employees && this.props.employees.map((data, index) => {
- return <tr key={(index + 1)}>
- <td>{(index + 1)}</td>
- <td>{data.employeeName}</td>
- <td>{data.employeeDepartment}</td>
- <td><button onClick={() => this.editDetails(data)}>EDIT</button> <button onClick={() => this.deleteEmployee(data.id)}>DELETE</button> </td>
- </tr>
- })}
- </tbody>
- </table>
- </div>
- </p>
- </div>
- );
- }
- }
- export default connect(mapStateToProps, { getEmployee })(App);

We need to add all action-creator in Action.Js and actual operations which need to manipulate data in Reducer.js.
- const initialstate = {
- employees: [
- { id: 1, employeeName: "Employee 1", employeeDepartment: ".NET Team" },
- { id: 2, employeeName: "Employee 2", employeeDepartment: "Mobile Team" },
- { id: 3, employeeName: "Employee 3", employeeDepartment: "Design Team" }
- ]
- };
- const reducer = (state = initialstate, action) => {
- switch (action.type) {
- case 'GET_EMPLOYEE':
- return {
- ...state
- };
- case 'ADD_EMPLOYEE':
- return {
- ...state,
- employees: state.employees.concat(action.payload)
- };
- case 'EDIT_EMPLOYEE':
- return {
- ...state,
- employees: state.employees.map(
- (content, i) => content.id === action.payload.id ? {...content, employeeName : action.payload.employeeName , employeeDepartment : action.payload.employeeDepartment }
- : content)
- };
- case 'DELETE_EMPLOYEE':
- return {
- ...state,
- employees: state.employees.filter(item => item.id !== action.payload)
- };
- default:
- return state;
- }
- };
- export default reducer;
- export function getEmployee() {
- return dispatch => {
- return dispatch({
- type: 'GET_EMPLOYEE'
- });
- }
- };
- export function addEmployee(data) {
- return dispatch => {
- return dispatch({
- type: 'ADD_EMPLOYEE',
- payload: data
- });
- }
- };
- export function editEmployee(data) {
- return dispatch => {
- return dispatch({
- type: 'EDIT_EMPLOYEE',
- payload: data
- });
- }
- };
- export function deleteEmployee(employeeId) {
- return dispatch => {
- return dispatch({
- type: 'DELETE_EMPLOYEE',
- payload: employeeId
- });
- }
- };
- import React, { Component } from "react";
- import logo from "./logo.svg";
- import "./App.css";
- import PropTypes from 'prop-types';
- import { getEmployee, addEmployee, editEmployee, deleteEmployee } from './Redux/action';
- import { connect } from 'react-redux';
- class App extends Component {
- constructor(props) {
- super(props);
- this.state = {
- id: 0,
- employeeName: "",
- employeeDepartment: ""
- };
- }
- static propTypes = {
- employees: PropTypes.array.isRequired,
- getEmployee: PropTypes.func.isRequired,
- addEmployee: PropTypes.func.isRequired,
- editEmployee: PropTypes.func.isRequired,
- deleteEmployee: PropTypes.func.isRequired
- };
- componentDidMount() {
- this.props.getEmployee();
- }
- submitData = () => {
- if (this.state.employeeName && this.state.employeeDepartment && !this.state.id) {
- const newEmployee = {
- id: Math.floor(Math.random() * (999 - 100 + 1) + 100),
- employeeName: this.state.employeeName,
- employeeDepartment: this.state.employeeDepartment,
- };
- this.props.addEmployee(newEmployee);
- } else if (this.state.employeeName && this.state.employeeDepartment && this.state.id) {
- const updatedDetails = {
- id: this.state.id,
- employeeName: this.state.employeeName,
- employeeDepartment: this.state.employeeDepartment,
- };
- this.props.editEmployee(updatedDetails);
- } else {
- alert('Enter Employee Details.');
- }
- this.clearData();
- }
- editDetails = (data) => {
- this.setState({
- id: data.id,
- employeeName: data.employeeName,
- employeeDepartment: data.employeeDepartment
- })
- }
- deleteEmployee = (id) => {
- this.clearData();
- if (window.confirm("Are you sure?")) {
- this.props.deleteEmployee(id);
- }
- }
- handleNameChange = (e) => {
- this.setState({
- employeeName: e.target.value
- });
- }
- handleDepartmentChange = (e) => {
- this.setState({
- employeeDepartment: e.target.value
- });
- }
- clearData = () => {
- this.setState({
- id: 0,
- employeeName: "",
- employeeDepartment: ""
- });
- }
- render() {
- return (
- <div className="App">
- <header className="App-header">
- <img src={logo} className="App-logo" alt="logo" />
- <h1 className="App-title">CRUD opeartions for Employee Module</h1>
- </header>
- <p className="App-intro">
- <div className="leftsection">
- Employee Name : <input onChange={this.handleNameChange} value={this.state.employeeName} type="text" placeholder="Employee Name" /> <br />
- Employee Department : <input onChange={this.handleDepartmentChange} value={this.state.employeeDepartment} type="text" placeholder="Employee Department" /><br />
- {this.state.id ? <button onClick={this.submitData}>UPDATE</button> : <button onClick={this.submitData}>ADD</button>} <button onClick={this.clearData}>CLEAR</button>
- </div>
- <div className="rightsection">
- <table>
- <thead>
- <tr>
- <th>ID</th>
- <th>Name</th>
- <th>Depatment Name</th>
- <th>Action(s)</th>
- </tr>
- </thead>
- <tbody>
- {this.props.employees && this.props.employees.map((data, index) => {
- return <tr key={(index + 1)}>
- <td>{(index + 1)}</td>
- <td>{data.employeeName}</td>
- <td>{data.employeeDepartment}</td>
- <td><button onClick={() => this.editDetails(data)}>EDIT</button> <button onClick={() => this.deleteEmployee(data.id)}>DELETE</button> </td>
- </tr>
- })}
- </tbody>
- </table>
- </div>
- </p>
- </div>
- );
- }
- }
- const mapStateToProps = state => ({
- employees: state.employees
- });
- export default connect(mapStateToProps, { getEmployee, addEmployee, editEmployee, deleteEmployee })(App);
Summary
I have made a simple example of CRUD operations using React-Redux. You should try this sample at least 2-3 times so that it helps you to clear out about the Redux concept.
I hope this helps you.

nivy venkyPosted May 2, 2021, 2:29 PM
Not working
Hasan YelaldiPosted Jan 5, 2021, 6:57 AM
Hello Ankit, why we need this block; static propTypes = { employees: PropTypes.array.isRequired, getEmployee: PropTypes.func.isRequired, addEmployee: PropTypes.func.isRequired, editEmployee: PropTypes.func.isRequired, deleteEmployee: PropTypes.func.isRequired };
martin sPosted Jun 9, 2020, 9:16 PM
How to get reacords (crud) from node js instead of JSON
martin sPosted Jun 9, 2020, 9:15 PM
Hello Ankit Very nice tutorial
Vijayan AravamudhanPosted May 24, 2020, 12:55 AM
Awesome!! Nice one.
Dipa MehtaPosted Mar 7, 2020, 7:52 AM
Nice article Ankit, as previous both.