CRUD Application in React.js with Redux and Hooks.
In this article, we will see hooks redux crud application with a react-bootstrap framework having multiple features following:
- Create React App
- Add, Update using modal
- Multiple checkboxes
- Unit-testing
- Styling with Sass
A new concept was introduced in React Hooks. Hooks are an alternative to classes. If you’ve used to React before, you’ll be familiar with functional components and class components.
Many of the features are available to class components— such as lifecycle methods and state which has not been available to functional components until now. Hooks supports all that functionality and more.
Here, we’ll create a CRUD app. It will have lists of books, and you’ll be able to add, update, or delete books. We’ll use State Hooks and Effect Hooks on functional components. If you miss anything along the way, check out the source of the completed project.
Create React App
Create React App is an officially supported way to create single-page React applications. It offers a modern build setup with no configuration.
npx create-react-app styled-hooks-redux-crud
cd styled-hooks-redux-crud
npm start
install required libraries
npm install redux react-redux react-bootstrap bootstrap react-toastify uuid react-icons node-sass@4.14.1
Initial Setup-
Let’s start off by clearing out all the files from the boilerplate that we don’t need. Delete everything from the /src
folder exceptindex.js
In index.js
, replace yours with below
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App/App";
ReactDOM.render(<h2>Hello</h2>, document.getElementById("root"));
Add below link inside the head of public/index.html
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous" />
create data.js
The first thing we’ll do is redux setup for the initial view of the page. Create a file named src\actions\crudActions.js
const LIST_ITEMS = 'LIST_ITEMS';
import { listArray } from '../utils/data';
export const getItems = () => {
return {
type: LIST_ITEMS,
payload: listArray
}
};
src\reducers\crudReducer.js
const LIST_ITEMS = 'LIST_ITEMS';
let initialState = {
lists: [], item: {}
};
export default function rootReducer(state = initialState, action) {
switch(action.type){
case LIST_ITEMS:
return {
...state,
lists: action.payload
};
default: return state;
}}
src\reducers\index.js
import { combineReducers } from "redux";
import crudReducer from "./crudReducer";
export default combineReducers({
lists: crudReducer
});
src\store.js
import { createStore } from "redux";
import reducer from "./reducers";const store = createStore(reducer);
export default store;
Setting up the View with fetched data-
The first thing we’ll do is make a table to display. now create a Home(src\components\home\Home.js , \home\home.scss) and Header component.
import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import {getItems} from "../../actions/crudActions";
import './home.scss';
export default function Home() {
const dispatch = useDispatch();
const { lists } = useSelector(state => state.lists);
useEffect(() => {
dispatch(getItems());
},[dispatch]);return (
<div> {lists && lists.map(list=>
<div key={list.id}>{list.title}</div> )}
</div>
)
}
src\components\header\Header.js and \header\header.scss
import React from "react";
import './header.scss'
export default function Header() {
return (
<div className="menu-header">
<div className="menu-header__menu-inner">
<div>
<div>REACT CRUD</div>
</div>
<button>Add</button>
</div>
</div>
)}
Now createApp.js
inside src\components\App\App.js and replace with
import React from "react";
import { Provider } from "react-redux";
//import "../../App.scss";
import store from "../../store";
import Home from "../home/Home";
export default function App() {
return (
<Provider store={store}>
<Home />
</Provider>
);
}
Now update in src\index.js from<h2>Hello</h2>
to<App />
ReactDOM.render(<App />, document.getElementById("root"));
Yay! you must see basic list rendering.
Create a component src\components\listItem\ListItem.js and \listItem\listItem.scss
import React from "react";
import { Table } from "react-bootstrap";
import { FaEdit, FaBook } from "react-icons/fa";
import './listItem.scss';export default function ListItem({ lists }) {
return (
<Table responsive>
<thead>
<tr>
<th><FaBook /></th>
<th>Title</th>
<th>Description</th>
<th><span>Action</span>
<span><input type="checkbox"/></span>
</th>
</tr>
</thead>
<tbody>
{lists && lists.map((list) => (
<tr key={list.id}>
<td><FaBook /></td>
<td>{list.title}</td>
<td>{list.description}</td>
<td> <FaEdit />
<input key={list.id} type="checkbox" />
</td>
</tr>
))}
</tbody>
</Table>
)}
Update your Home.js
Now we have the initial view… Yay!
Add, Update using modal & Multiple checkboxes
Now let’s update existing and create new files to make it work
create components- src\components\create\Create.js, src\components\update\Update.js, src\components\loader\Loader.js and replace from appropriate components-
replace all your components(Create.js, Header.js, Home.js, ListItem.js, Loader.js, Update.js), actions, utils, and reducers from —
src\actions\crudActions.js
src/utils/constant.js
src\reducers\crudReducer.js
multiple checkboxes — you can select multiple items to delete.
Unit Testing
Setup with Create React App
If you are new to React, we recommend using the Create React App. It is ready to use and ships with Jest! You will only need to add react-test-renderer
for rendering snapshots.
npm i react-test-renderer
Snapshot Testing
Snapshot tests are a very useful tool whenever you want to make sure your UI does not change unexpectedly.
A typical snapshot test case renders a UI component, takes a snapshot, then compares it to a reference snapshot file stored alongside the test. The test will fail if the two snapshots do not match: either the change is unexpected, or the reference snapshot needs to be updated to the new version of the UI component.
Example (Create.js component)—
create a test file src\components\create\test\Create.test.js
import React from 'react';
import renderer from 'react-test-renderer';
import Create from '../Create';
test('should render Create Component', () => {
let fakeProps = {
id: 1,
title: "abc",
description: "Dummy text",
completed: false
};
const tree = renderer
.create(<Create state={fakeProps} />)
.toJSON();
expect(tree).toMatchSnapshot();
});
run test cases
npm test
Test file can be named Create.test.js or Create.spec.js
Styling with Sass
Sass is a stylesheet language that’s compiled to CSS. It allows you to use variables, nested rules, mixins, functions, and more, all with a fully CSS-compatible syntax. Sass helps keep large stylesheets well-organized and makes it easy to share design within and across projects.
Sass can be installed by running this command in your terminal if not installed. Don’t need to run it again.
npm install node-sass
now create a Sass file the same way as you create CSS files, but Sass files have the file extension .scss
— src\components\home\home.scss
$white: #fff;@mixin phone($size) {
@media only screen and
(max-width: $size) {
@content;
}
}
.container{
padding: 30px 0px;
width: 70%;
margin: 0 auto;
.jumbotron {
padding: 0px 0px;
border-radius: 0px;
background-color: $white;
}
@include phone(480px) {
width: 100%;
margin: 0;
padding: 0;
.remove{
display: none;
}
}
}
Now create sass files inside every component folder(create/create.scss, header/header.scss, listItem/listItem.scss, loader/loader.scss, update/update.scss) and replace from styled-hooks-redux-crud/src/components/ styles files snippet.
Yay!, completed the application, Here is the demo of responsive (Desktop and mobile versions).
That’s all, If it has been useful to you, please share and spread the word. Thanks.