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! π Usetheform is a React library for composing declarative forms and managing their state. It does not depend on any external library, such as Redux, or MobX, which makes it easy to adopt due to the lack of dependencies.
π₯ Features
- Easy integration with other libraries. ππ» Play with React Select/Material UI - React Dropzone/MaterialUI Dropzone.
- Supports Sync and Async validation at Form, Field and Collection level. ππ» Play with Sync and Async validation.
- Supports Yup, Zod, Superstruct, Joi or custom schema validations. ππ» Play with YUP - ZOD - Superstruct - Joi validations.
- Follows the HTML standard for validation. ππ» Play with HTML built-in form validation.
- Supports reducer functions at Form, Field and Collection levelβ¦
Top comments (0)