Unstated Next – Lightweight State Management Library For ReactJS | Part – 3 | Shopping Cart
Last Updated :
04 Dec, 2023
We have implemented a shopping cart using Unstated Next In this article we are gonna learn how to handle states of more than one component in a React application using Unstated Next.
Prerequisites:
Steps to Create the React Application And Installing Module:
Step 1: Create a new react app.
npx create-react-app shopping-cart
Step 2: Go to its directory by using the below command.
cd shopping-cart
Step 3: Create components folder for adding new components and store folder for creating global store using Unstated Next library.
mkdir src/components src/store
or
mkdir src/components src/store
Step 4: Install a package called Unstated Next:
npm i unstated-next
Step 5: to verify everything is working or not, run the below command to run your application.
npm start
Project Structure:
The updated dependencies in package.json file will look like:
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"unstated-next": "^1.1.0",
"web-vitals": "^2.1.4",
}
Approach:
- Creating Multiple Store
- In the src/store folder create 3 more stores for cart, users, and items. detailed explanation for creating store given in the previous articles refer that.
- Creating Multiple Components
- Next, we need to create 3 simple components for cart, users, and items inside the src/components folder and connect that to the App.js file.
- Moving Providers to provider.js file:
- This Step is very important because in the previous tutorial we added Provider directly into the App.js file. so every time we create a new store we need to that. this makes the App.js file very complex, to avoid this we add all providers to a single file and then import that into the App.js file.
- For that, we need to create a provider.js file inside src/store and then add the below code.
Example: Below is the implementation of the above approach.
Javascript
import "./App.css" ;
import Cart from "./components/Cart" ;
import Item from "./components/Item" ;
import User from "./components/User" ;
import Provider from "./store/provider" ;
function App() {
return (
<div className= "App" >
<Provider>
<Cart />
<User />
<Item />
</Provider>
</div>
);
}
export default App;
|
Javascript
import React, { useState } from "react" ;
import useUser from "../store/user" ;
function User() {
const { users, addUser } = useUser.useContainer();
const [localUser, setLocalUser] = useState( "" );
return (
<div
style={{
padding: "2vw" ,
display: "flex" ,
justifyContent: "left" ,
width: "40vw" ,
margin: "auto" ,
}}
>
<div
style={{
marginRight: "10px" ,
display: "flex" ,
}}
>
{users.length > 0 &&
users.map((user) => (
<p key={user} style={{ marginRight: 12 }}>
{user}
</p>
))}
</div>
<input
type={ "text" }
value={localUser}
onChange={(e) => setLocalUser(e.target.value)}
placeholder= "user name"
></input>
<button onClick={() => addUser(localUser)}>Add</button>
</div>
);
}
export default User;
|
Javascript
import React, { useState } from "react" ;
import useItem from "../store/item" ;
function Item() {
const { items, addItem } = useItem.useContainer();
const [localItem, setLocalItem] = useState( "" );
return (
<div
style={{
padding: "2vw" ,
display: "flex" ,
justifyContent: "left" ,
width: "40vw" ,
margin: "auto" ,
}}
>
<div
style={{
marginRight: "10px" ,
display: "flex" ,
}}
>
{items.length > 0 &&
items.map((item) => (
<p key={item} style={{ marginRight: 12 }}>
{item}
</p>
))}
</div>
<input
type={ "text" }
value={localItem}
onChange={(e) => setLocalItem(e.target.value)}
placeholder= "item name"
></input>
<button onClick={() => addItem(localItem)}>
Add
</button>
</div>
);
}
export default Item;
|
Javascript
store/provider.js
import React from "react" ;
import useUser from "./user" ;
import useCart from "./cart" ;
import useItem from "./item" ;
const Provider = (props) => {
return (
<useCart.Provider>
<useItem.Provider>
<useUser.Provider>
{props.children}
</useUser.Provider>
</useItem.Provider>
</useCart.Provider>
);
};
export default Provider;
|
Javascript
import React, { useState } from "react" ;
import "./cart.css" ;
import useCart from "../store/cart" ;
function Cart() {
let { items, addItem, deleteItem } = useCart.useContainer();
const [localItem, setLocalItem] = useState( "" );
console.log(localItem, items);
return (
<div>
<h1 className= "title" >Cart Items</h1>
<ol className= "items" >
{items.length > 0 ? (
items.map((item) => (
<div className= "item-set" >
<li className= "item" key={item}>
{item}{ " " }
</li>
<button className= "deleteButton"
onClick={() => deleteItem(item)}>
Delete
</button>
</div>
))
) : (
<p>Cart is Empty</p>
)}
</ol>
<input
type= "text"
id= "newItem"
placeholder= "Item name"
value={localItem}
onChange={(e) => setLocalItem(e.target.value)}
/>
<input
type= "button"
id= "submitButton"
value= "Add"
onClick={() => {
addItem(localItem);
setLocalItem( "" );
}}
/>
</div>
);
}
export default Cart;
|
Javascript
import { useState } from "react" ;
import { createContainer } from "unstated-next" ;
function useCart(initialState = []) {
let [items, setItems] = useState(initialState);
let addItem = (_item) => {
setItems([...items, _item]);
};
let deleteItem = (_item) => {
let newItem = items.filter((item) => item !== _item);
setItems(newItem);
};
return { items, addItem, deleteItem };
}
export default createContainer(useCart);
|
CSS
.title {
font-family : Verdana , Geneva, Tahoma , sans-serif ;
font-size : 3 rem;
background-color : rgb ( 172 , 172 , 172 );
margin : 10 vh 30 vw;
padding : 10px 22px ;
width : 40 vw;
border-radius: 5px ;
}
.items {
padding : 22px ;
width : 40 vw;
border-radius: 5px ;
margin : 10 vh 30 vw;
margin-top : -9 vh;
background-color : rgb ( 221 , 221 , 171 );
font-size : 1.5 rem;
list-style-type : none ;
}
.item-set {
display : flex;
justify- content : center ;
align-items: center ;
}
.item {
width : 10 vw;
padding : 1 vw;
}
.deleteButton {
width : 10 vw;
height : 8 vh;
font-size : 1.2 rem;
border-radius: 5px ;
border : none ;
background-color : rgb ( 226 , 148 , 148 );
}
.deleteButton:hover {
background-color : rgb ( 211 , 101 , 101 );
color : rgb ( 255 , 253 , 253 );
}
#newItem {
padding : 2 vh 8 vw;
outline : none ;
border : none ;
border-bottom : 2px solid rgb ( 172 , 170 , 170 );
}
#submitButton {
padding : 10px 40px ;
font-size : 1.2 rem;
border-radius: 5px ;
border : none ;
background-color : rgb ( 100 , 214 , 167 );
margin-left : 1 vw;
}
#submitButton:active {
background-color : rgb ( 43 , 129 , 93 );
color : wheat;
}
|
Step to Run Application: Run the application using the following command from the root directory of the project.
npm start
Output:
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...