Get Started
In order to get started you need to create a new react.js
project using vite.js as shown below
npm create vite@ reduxcrud
npm i react-bootstrap bootstrap
npm i redux react-redux
crud/crudStore.js
1 2 3 4 |
import {createStore} from 'redux' import { crudReducer } from './crudReducer' export const crudStore = createStore(crudReducer) |
As you can see we are creating the store
for the global state using the createStore()
and then we are passing the reducer
function that we are importing at the top. Now we need to define this reducer function.
crud/crudReducer.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import { ADD_USER, REMOVE_USER, UPDATE_USER } from "./crudTypes"; const initialState = { users: [], }; export const crudReducer = (state = initialState, action) => { switch (action.type) { case ADD_USER: return { ...state, users: [...state.users, action.payload], }; case REMOVE_USER: return { ...state, users: state.users.filter((u) => u.id !== action.payload), }; case UPDATE_USER: let {id,name,age} = action.payload return { ...state, users: state.users.map((user) => user.id === id ? { ...user, name, age } : user ), }; default: { return state; } } }; |
As you can see in the above reducer function we have defined the various methods for the various
operations such as adding the user or removing
the user and also updating the user and then we have the default
case where we return the state
. Here also we declare the initialState
which contains the array of user objects.
crud/crudTypes.js
1 2 3 |
export const ADD_USER = "add_User" export const REMOVE_USER = "remove_User" export const UPDATE_USER = "update_User" |
As you can see we have defined all the constants
for performing the various operations that we are importing in other files of reducers
and actions
.
crud/crudAction.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import { ADD_USER, REMOVE_USER, UPDATE_USER } from "./crudTypes" export const addUser = (user) => { return { type:ADD_USER, payload:user } } export const removeUser = (id) => { console.log(id) return { type:REMOVE_USER, payload:id } } export const updateUser = (id,name,age) => { return { type:UPDATE_USER, payload:{ id, name, age } } } |
As you can see we have defined various methods for the various actions
that we perform inside the application. Here we are expecting the user to pass the type
and payload parameters.
App.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import './App.css' import Users from './Users' import { Provider } from 'react-redux' import { crudStore } from './crud/crudStore' function App() { return ( <Provider store={crudStore}> <Users/> </Provider> ) } export default App |
As you can see in the above file we are configuring the store
inside the Provider
tag so that every component can access the global
state that we have defined. And now we need to define the Users.jsx
component as shown below
Users.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
import React, {useRef, useState } from "react"; import "bootstrap/dist/css/bootstrap.min.css"; import { Container, Form, Button, Table } from "react-bootstrap"; import { useDispatch, useSelector } from "react-redux"; import { addUser, removeUser, updateUser } from "./crud/crudAction"; function Users() { let { users } = useSelector((state) => { return state }); let dispatch = useDispatch() const [update, setUpdate] = useState(false); const [currentId,setCurrentId] = useState(null) const [currentName,setCurrentName] = useState(null) const [currentAge,setCurrentAge] = useState(null) let [name, setName] = useState(null); let [age, setAge] = useState(null); let nameRef = useRef(null); let ageRef = useRef(null); let handleUsers = (e) => { e.preventDefault(); let id = Date.now(); let user = { id, name, age, }; dispatch(addUser(user)); nameRef.current.value = ""; ageRef.current.value = ""; }; let handleEdit = (user) => { setUpdate(true); setCurrentId(user.id) setCurrentName(user.name) setCurrentAge(user.age) nameRef.current.value = user.name ageRef.current.value = user.age }; let handleUpdate = (e) => { e.preventDefault() dispatch(updateUser(currentId,currentName,currentAge)) setCurrentId(null) setCurrentAge(null) setCurrentName(null) setName(null) setAge(null) setUpdate(false) nameRef.current.value = "" ageRef.current.value = "" } return ( <Container> <h1 className="text-center">React.js Redux CRUD</h1> {update ? ( <Form onSubmit={handleUpdate}> <Form.Group> <Form.Label>Name</Form.Label> <Form.Control type="text" onChange={(e) => setCurrentName(e.target.value)} ref={nameRef} placeholder="Enter name" required /> <Form.Label>Age</Form.Label> <Form.Control type="number" onChange={(e) => setCurrentAge(e.target.value)} ref={ageRef} placeholder="Enter age" required /> </Form.Group> <br /> <Button type="submit">Update User</Button> </Form> ) : ( <Form onSubmit={handleUsers}> <Form.Group> <Form.Label>Name</Form.Label> <Form.Control type="text" onChange={(e) => setName(e.target.value)} ref={nameRef} placeholder="Enter name" required /> <Form.Label>Age</Form.Label> <Form.Control type="number" onChange={(e) => setAge(e.target.value)} ref={ageRef} placeholder="Enter age" required /> </Form.Group> <br /> <Button type="submit">Add User</Button> </Form> )} <Table striped bordered hover> <thead> <tr> <th>ID</th> <th>Name</th> <th>Age</th> <th>Edit User</th> <th>Delete User</th> </tr> </thead> <tbody> {users && users.map((u) => ( <tr> <td>{u.id}</td> <td>{u.name}</td> <td>{u.age}</td> <td> <Button onClick={() => handleEdit(u)}>Edit User</Button> </td> <td> <Button onClick={() => dispatch(removeUser(u.id))}>Delete User</Button> </td> </tr> ))} </tbody> </Table> </Container> ); } export default Users; |
As you can see we are using the useSelector
hook to get the state or the data and then we are using the onDispatch
hook to dispatch the various actions.