In today post we will develop a simple shopping cart in reactjs by using usetheform, a react library for composing declarative forms and managing their state. Letβs start it.
Installation
To install the package run the following npm command:
npm i usetheform --save
Components
In order to build our simple shopping cart we are going to leverage some components provided by usetheform:
<Form />: renders all the fields and keeps the entire form state synchronized.
<Collection />: creates a nested piece of state within a Form and it can can be of type: object or array.
<Input />: renders all the inputs of type listed at: W3schools Input Types and accepts as props any HTML attribute listed at: HTML Input Attributes.
On top of them we are going to develop others two components:
CartItem Component
It uses <Input /> to represent: id, description, quantity and the price of the item added.
./CartItem.js
import React from "react";
import { Input, Collection } from "usetheform";
const preventNegativeQty = val => (val < 1 ? 1 : val);
export function CartItem({ qty, price, onRemoveItem, id, desc }) {
return (
<Collection object>
<Input type="hidden" name="id" value={id} />
<div className="field">
<label>Item</label>
<Input type="text" name="item" readOnly value={desc} />
</div>
<div className="field">
<label>Quantity</label>
<Input reducers={preventNegativeQty} type="number" name="qty" value={qty} />
</div>
<div className="field">
<label>Price β¬</label>
<Input type="text" name="price" value={price} disabled readOnly />
</div>
<div className="field">
<button type="button" onClick={() => onRemoveItem(id)}>
Remove
</button>
</div>
</Collection>
);
}
The CartItem component uses a Collection of type object which creates a piece of state within the form as following:
{ id: 1, item: "Item name", qty: 1, price: "3.3" }
Cart Component
It uses <Collection /> to hold the cart items.
./Cart.js
import React from "react";
import { Collection } from "usetheform";
import { CartItem } from "./CartItem";
export function Cart({ items, onRemoveItem }) {
return (
<Collection object name="cart">
<Collection array name="items">
{items.map(item => (
<CartItem {...item} onRemoveItem={onRemoveItem} key={item.id} />
))}
</Collection>
</Collection>
);
}
The Cart component uses two Collections one of type object named cart and a nested one named items which holds a list of CartItem components and creates a piece of state within the form as following:
{
cart: {
items: [{ id: 1, item: "Item name", qty: 1, price: "3.3" }, {....}]
}
}
App Component
./App.js
import React, { useState } from "react";
import Form from "usetheform";
import { Cart } from "./Cart";
export default function App() {
const [items, setCartItem] = useState([]);
const onRemoveItem = (idToRemove) =>
setCartItem((prev) => prev.filter(({ id }) => id !== idToRemove));
const onAddItem = () => {
const item = createRandomItem();
setCartItem((prev) => [...prev, item]);
};
const onChange= (state, isFormValid) => console.log('CHANGE', state, isFormValid);
const onSubmit= (state) => console.log('SUBMIT', state);
return (
<div className="App">
<Form onChange={onChange} onSubmit={onSubmit}>
<Cart items={items} onRemoveItem={onRemoveItem} />
<button type="submit">Submit</button>
</Form>
<br />
<button type="button" onClick={onAddItem}>
Add item to cart
</button>
</div>
);
}
let id = 0;
const createRandomItem = () => {
id = id + 1;
return {
id,
qty: 1,
desc: `Item number: ${id}`,
price: Number((Math.random() * 10 + 1).toFixed(2))
};
};
An Extended CodeSandbox Example:
Conclusion
Hope you enjoyed reading this post. If you did so, please checking out the usetheform repo, or even better contribute to usetheform. Thanks π.
iusehooks / usetheform
React library for composing declarative forms, manage their state, handling their validation and much more.
An easy way for building forms in React.
π‘ What is usetheform about?
Welcome!
π₯ Features
- Easy integration with other libraries. ππ» Play with React Select/Material UI - React Dropzone/MaterialUI Dropzone.
- Support Sync and Async validation at Form, Field and Collection level. ππ» Play with Sync and Async validation.
- Support Yup, Zod, Superstruct, Joi or custom. ππ» Play with YUP - ZOD - Superstruct - Joi validations.
- Follows HTML standard for validation. ππ» Play with HTML built-in form validation.
- Support reducers functions at Form, Field and Collection level. ππ» Play with Reducers.
- Easy toβ¦
Oldest comments (0)