Giter Site home page Giter Site logo

recoil-simple-cart's Introduction

Recoil tutorial: 02 - Code a simple cart 🎉

Agenda:

  1. Setup project
  2. Setup RecoilRoot
  3. Render product list
  4. Handle add to cart
  5. Render cart info

1. Setup project

npm i --save recoil

Recoil official docs: https://recoiljs.org/docs/introduction/getting-started

2. Setup RecoilRoot

Edit src/index.js to add RecoilRoot component, so that you can use recoil hooks anywhere in your app.

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { RecoilRoot } from 'recoil';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <RecoilRoot>
      <App />
    </RecoilRoot>
  </React.StrictMode>,
  document.getElementById('root')
);

3. Render product list

Define a product list state using atom

// features/cart/productState.js
import { atom } from "recoil";

export const productListState = atom({
  key: 'productList',
  default: [
    { id: 1, price: 150000, title: 'Áo thun nam' },
    { id: 2, price: 250000, title: 'Áo sơ mi nữ' },
    { id: 3, price: 300000, title: 'Áo khoắc thời trang' },
  ],
});

Render product list state in component ProductList

// features/cart/component/ProductList.jsx
function ProductList() {
  const productList = useRecoilValue(productListState);

  return (
    <div>
      <h2>Product List</h2>

      <ul className="product-list">
        {productList.map(product => (
          <li key={product.id}>
            {product.title}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default ProductList;

4. Handle add to cart

Define cart state using atom

// features/cart/cartState.js
import { atom } from 'recoil';

export const cartState = atom({
  key: 'cart',
  // each item in list has 3 keys: id, product and quantity
  default: [],
});

Implement addToCart() function that take current state and newItem and return a new state.

// features/cart/cartState.js
export const addToCart = (cart, item) => {
  const newCart = [...cart];
  const foundIndex = cart.findIndex(x => x.id === item.id);

  // Increase quantity if existing
  if (foundIndex >= 0) {
    newCart[foundIndex] = {
      ...cart[foundIndex],
      quantity: cart[foundIndex].quantity + 1,
    };
    return newCart;
  }

  // Add new item
  newCart.push({
    id: item.id,
    product: item,
    quantity: 1,
  });
  return newCart;
};

Add button Add to cart to product list

// features/cart/component/ProductList.jsx
function ProductList() {
  const productList = useRecoilValue(productListState);

  // 1. Add this handler
  const handleAddToCart = (product) => {}

  return (
    <div>
      <h2>Product List</h2>

      <ul className="product-list">
        {productList.map(product => (
          <li key={product.id}>
            {product.title}

            {/* 2. ADD THIS BUTTON */}
            <button
              style={{ marginLeft: '1rem' }}
              onClick={() => handleAddToCart(product)}
            >
              Add to cart
          </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

Implement add to cart handler

// features/cart/component/ProductList.jsx
function ProductList() {
  const productList = useRecoilValue(productListState);
  const [cart, setCart] = useRecoilState(cartState); // 1. Get recoil state

  const handleAddToCart = (product) => {
    const newCart = addToCart(cart, product); // 2. Use helper to create a new state
    setCart(newCart); // 3. Update recoil state
  }
  // return (...);
}

5. Render cart info

Render current cart items in CartInfo component

// features/cart/components/CartInfo.jsx
function CartInfo(props) {
  const cart = useRecoilValue(cartState);

  return (
    <div>
      <h2>Cart info:</h2>

      <ul className="cart-items">
        {cart.map(item => (
          <li key={item.id}>{item.product.title}: {item.quantity}</li>
        ))}
      </ul>
    </div>
  );
}

Define a selector that calculate cart total base on cart state

// features/cart/cartState.js
import { atom, selector } from 'recoil';

export const cartState = atom({
  key: 'cart',
  // each item in list has 3 keys: id, product and quantity
  default: [],
});

// NEW CODE HERE
export const cartTotal = selector({
  key: 'cartTotal',
  get: ({ get }) => {
    const cart = get(cartState);

    return cart.reduce((total, item) => {
      return total + (item.product.price * item.quantity);
    }, 0);
  }
});

Update CartInfo component to also render cart total

function CartInfo(props) {
  const cart = useRecoilValue(cartState);
  const total = useRecoilValue(cartTotal); // 1. Read selector value

  return (
    <div>
      <h2>Cart info:</h2>

      <ul className="cart-items">
        {cart.map(item => (
          <li key={item.id}>{item.product.title}: {item.quantity}</li>
        ))}
      </ul>

      {/* 2. Render it! Sweeeeet! 😍 */}
      <h4>Total: {total} VND</h4>
    </div>
  );
}



Cảm ơn các bạn đã xem video của mình!
Nhớ like, share và subscribe để cho bạn bè cùng xem nhen 😉

❤️ Ủng hộ mình làm videos thì đóng góp tại đây nhé:

Kết nối với mình:

recoil-simple-cart's People

Contributors

paulnguyen-mn avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.