Context と useReducer を使用して Next.js でショッピング カートを作成する方法

Context と useReducer を使用して Next.js でショッピング カートを作成する方法

ショッピング カートは、あらゆる e コマース サイトに不可欠な要素です。これにより、顧客は製品を保管および購入できます。

Next.js e コマース アプリでは、Context API と useReducer フックを使用してカートを作成できます。コンテキスト API は、コンポーネント間のカート データの共有を簡素化し、useReducer はカートの状態を処理します。

商品ページの作成

ページ フォルダーで、単一の製品をレンダリングする Product.jsx という名前の新しいファイルを作成します。

export default function Product({id, name, price}) {
  return (
    <div>
      <p>{name}</p>
      <p>{price}</p>
      <button>Add to Cart</button>
    </div>
  )
}

製品コンポーネントは、製品の ID、名前、および価格を受け入れて表示します。「カートに入れる」ボタンもあります。

製品がすでにカートに追加されている場合、ボタンは「カートから削除」ボタンに切り替わり、製品がカートにない場合、ページには「カートに追加」ボタンが表示されます。

この機能を実装するには、コンテキスト API と useReducer フックを使用して、カート内のアイテムを追跡する必要があります。

Context API を使用したショッピング カートの作成

コンテキスト API を使用すると、プロパティを親から子に手動で渡すことなく、さまざまなコンポーネント間でデータを共有できます。これらのコンポーネントは、ナビゲーション バー、商品詳細ページ、またはチェックアウト ページです。

context というフォルダーに cartContext.js という新しいファイルを作成し、コンテキストを作成します。

import { createContext } from "react";

export const CartContext = createContext({
    items: [],
});

CartContext は、デフォルト値として項目の配列を取ります。

次に、コンテキスト プロバイダーを作成します。コンテキスト プロバイダーを使用すると、コンテキストを使用するコンポーネントがコンテキストの変更をサブスクライブできます。

cartProvider という新しい関数に、次を追加します。

export const CartProvider = ({ children }) => {
  return <CartContext.Provider>{children}</CartContext.Provider>;
};

カート内のアイテムを追跡するには、useReducer フックを使用します。

useReducer フックは、より複雑な状態ロジックの管理に役立つ点を除いて、useState フックと同様に機能します。レデューサー関数と初期状態を受け入れます。現在の状態と、アクションをレデューサー関数に渡すディスパッチ関数を返します。

CartReducer という新しい関数を作成し、リデューサーを追加します。

const cartReducer = (state, action) => {
  const { type, payload } = action;

  switch (type) {
    case "ADD":
      return {
        ...state,
        items: payload.items,
      };

    case "REMOVE":
      return {
        ...state,
        items: payload.items,
      };

    default:
      throw new Error("No case for that type");
  }
};

レデューサー関数は、アクションの種類に応じて状態を更新する switch ステートメントで構成されます。カートレデューサー機能には、カートに追加する「ADD」アクションとカートから削除する「REMOVE」アクションがあります。

レデューサー関数を作成したら、それを useReducer フックで使用します。CartProvider 関数を作成することから始めます。これは、他のコンポーネントにコンテキストを提供する関数です。

export const CartProvider = ({children}) => {
  return <CartContext.Provider>{children}</CartContext.Provider>;
}

次に、useReducer フックを作成します。

export const CartProvider = ({ children }) => {
  const [state, dispatch] = useReducer(cartReducer, { items: [] });
  return <CartContext.Provider>{children}</CartContext.Provider>;
};

ディスパッチ関数はカートの状態の更新を担当するため、CartProvider 関数を変更して、カートの更新時に商品を useReducer フックにディスパッチする関数を含めます。

import { createContext, useReducer } from "react";

export const CartProvider = ({ children }) => {
  const [state, dispatch] = useReducer(cartReducer, initialState);

  const addToCart = (product) => {
    const updatedCart = [...state.items, product];

    dispatch({
      type: "ADD",
      payload: {
        items: updatedCart,
      },
    });
  };

  const removeFromCart = (id) => {
    const updatedCart = state.items.filter(
      (currentProduct) => currentProduct.id! == id
    );

    dispatch({
      type: "REMOVE",
      payload: {
        items: updatedCart,
      },
    });
  };

  return <CartContext.Provider>{children}</CartContext.Provider>;
};

addToCart 関数は、新しい製品を既存の製品に追加し、ディスパッチ関数のペイロード オブジェクトで更新された製品を返します。同様に、removeFromCart 関数は、アイテムを ID で除外し、更新されたリストを返します。

また、CartContext プロバイダーで value prop を返す必要があります。

export const CartProvider = ({ children }) => {
  const [state, dispatch] = useReducer(cartReducer, {
    items: [],
  });

  const addToCart = (product) => {};
  const removeFromCart = (id) => {};

  const value = {
    items: state.items,
    addToCart,
    removeFromCart,
  };

  return <CartContext.Provider value={value}>{children}</CartContext.Provider>;
}

value prop は useContext フックを介して消費されます。

カート コンテキストの使用

ここまでで、カート コンテキストを作成し、カートを更新する useReducer 関数を作成しました。次に、useContext フックを使用して、製品コンポーネントでカート コンテキストを使用します。

最上位のコンポーネントである index.js をコンテキスト プロバイダーでラップして、アプリケーション全体でコンテキスト値を使用できるようにすることから始めます。

import { CartProvider } from "../context/cartContext";

function MyApp({ Component, pageProps }) {
  return (
    <CartProvider>
      <Component {...pageProps} />
    </CartProvider>
  );
}


export default MyApp;

次に、useContext フックとカート コンテキスト プロバイダーを Product.js にインポートします。

import { useContext } from "react"
import { CartContext } from "../context/cartContext"

export default function Product() {
  const {items, addToCart, removeFromCart} = useContext(CartContext)


  return (
    <>
      <div>
        <p>{name}</p>
        <p>{price}</p>
        <button>Add to Cart</button>
      </div>
    </>
  )
}

ボタンの機能は、アイテムがすでにカートに入っているかどうかによって異なります。カートにアイテムが存在する場合、ボタンはそのアイテムをカートから削除し、アイテムがまだカートにない場合は追加する必要があります。これは、useEffect と useState を使用してアイテムの状態を追跡する必要があることを意味します。useEffect コードは、useState がアイテムの状態を更新している間、コンポーネントのレンダリング後にアイテムがカートにあるかどうかをチェックします。

const [exists, setExists] = useState(false);

useEffect(() => {
  const inCart = items.find((item) => item.id === id);


  if (inCart) {
      setExists(true);
  } else {
      setExists(false);
  }
}, [items, id]);

次に、条件付きレンダリングを使用して、存在する状態に基づいてボタンを表示します。

return (
  <div>
    <p>{name}</p>
    <p>{price}</p>
    {
     exists
     ? <button onClick={() => removeFromCart(id)}>Remove from Cart</button>
     : <button onClick={() => addToCart({id, name, price})}>Add to Cart</button>
   }
  </div>
)

onClick ハンドラー関数は、コンテキスト プロバイダーで定義された removeFromCart および addToCart 関数であることに注意してください。

カートに機能を追加する

コンテキスト API と useReducer フックを使用してショッピング カートを作成する方法を学習しました。

このガイドでは機能の追加と削除のみを取り上げましたが、同じ概念を使用して、カート アイテムの数量の調整などの機能を追加できます。重要なことは、コンテキスト API と、フックを使用してカートの詳細を更新する方法を理解することです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です