Creating a Simple React Shopping Cart
Tags: react, javascript, forms, webdev
Published: 2020-12-10 14:14:02

---
title: Creating a Simple React Shopping Cart
published: true
description: A shopping cart example developed in reactjs using usetheform library
tags: react, javascript, forms, webdev 
cover_image: https://github.com/iusehooks/usetheform/raw/master/examples/img/shoppingcart.gif
---

In today post we will develop a simple shopping cart in reactjs by using [usetheform](https://github.com/iusehooks/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
```
* [NPM package](https://www.npmjs.com/package/usetheform)
* [GitHub project](https://github.com/iusehooks/usetheform)
* [Documentation](https://iusehooks.github.io/usetheform/)

### **Components**

In order to build our simple shopping cart we are going to leverage some components provided by [usetheform](https://iusehooks.github.io/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](https://www.w3schools.com/html/html_form_input_types.asp) and accepts as props any HTML attribute listed at: [HTML Input Attributes](https://www.w3schools.com/tags/tag_input.asp).

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`

```javascript
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:

```javascript
{ id: 1, item: "Item name", qty: 1, price: "3.3" }
```


#### Cart Component

It uses *\<Collection /\>* to hold the cart items.

`./Cart.js`

```javascript
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:

```javascript
{
  cart: { 
    items: [{ id: 1, item: "Item name", qty: 1, price: "3.3" }, {....}]
  }
}
```
#### App Component

`./App.js`

```javascript
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:

{% codesandbox shopping-cart-97y5k %} 

### **Conclusion**

Hope you enjoyed reading this post. If you did so, please checking out the usetheform repo, or even better contribute to [usetheform](https://github.com/iusehooks/usetheform). Thanks 🙏.

{% github https://github.com/iusehooks/usetheform %}