WEB

ワインデータを元にお気に入り機能を作ってみよう〜recoilとReactフックを使って〜

こんにちは。nap5です。

ワインデータを元にお気に入り機能を作ってみたので、紹介したいと思います。

今回はRecoilを使ったストア管理を元に実装しています。

はじめに、recoilを使ったストアファイルを作成します。

import {atom} from 'recoil';
import {recoilPersist} from 'recoil-persist';

const {persistAtom} = recoilPersist();
const favoriteState = atom({
  key: 'favoriteState',
  default: {
    favoriteWines: [],
  },
  effects_UNSTABLE: [persistAtom],
});

export default favoriteState;

次に、useFavoriteフックを作成します。フォーカスできる単一のアイテムが存在するページで使用する想定なので、引数にfocusedItemを受け取っています。

import {useMemo} from 'react';
import {useRecoilState} from 'recoil';
import favoriteState from '../stores/favoriteStore';

const useFavorite = ({focusedItem}) => {
  const [favorite, setFavorite] = useRecoilState(favoriteState);

  const toggleFavorite = () => {
    setFavorite((prevState) => {
      const isFaved = [...prevState.favoriteWines].some((favItem) => {
        return favItem.id === focusedItem.id;
      });
      if (!isFaved) {
        return {
          favoriteWines: [...prevState.favoriteWines].concat({
            ...focusedItem,
            favorited: true,
          }),
        };
      } else {
        return {
          favoriteWines: [...prevState.favoriteWines].filter((favItem) => {
            return favItem.id !== focusedItem.id;
          }),
        };
      }
    });
  };

  const favorited = useMemo(() => {
    if (favorite.favoriteWines.length === 0) {
      return false;
    }
    return favorite.favoriteWines.some((favItem) => {
      return favItem.id === focusedItem.id;
    });
  }, [favorite, focusedItem]);

  return {favorite, favorited, toggleFavorite};
};

export default useFavorite;

最後にページファイルないしはコンポーネントファイルで作成したフックを読み込んで使います。

import useFavorite from '../hooks/useFavorite';

const ProductGalleryItem = ({item}) => {
  const {favorite, favorited, toggleFavorite} = useFavorite({
    focusedItem: item,
  });
  ...
}

また、フォーカスできるアイテムが存在しないページではStateを直接読み込んで参照できるようにします。

import {useRecoilValue} from 'recoil';
import favoriteState from '../stores/favoriteStore';

const Favorite = () => {
  const {favoriteWines} = useRecoilValue(favoriteState);
  ...
}

デモサイトです。

ワインページなどでハートマーク押すとお気に入りページなどでカウントアップできていることが確認できます。

簡単ですが、以上です。