見出し画像

Recoilを使ったカスタムReactフックを書く時のスニペットメモ

こんにちわ。nap5です。


Recoilを使ったカスタムReactフックを書く時のスニペットメモを紹介したいと思います。

ストア側


src/features/film/stores/neatPagination.ts

import { atom } from 'recoil'
import { z } from 'zod'

export const NeatPaginationSchema = z.object({
  pageNumber: z.number(),
})

export type NeatPagination = z.infer<typeof NeatPaginationSchema>

const neatPaginationState = atom<NeatPagination>({
  key: 'neatPagination',
  default: {
    pageNumber: 1,
  },
})

export { neatPaginationState }


フック側


src/features/film/hooks/useNeatPagination.ts

import { useCallback, useMemo } from 'react'

import { max } from 'ramda'
import { useRecoilValue, useSetRecoilState } from 'recoil'

import { neatPaginationState } from '@/features/film/stores/neatPagination'

const useNeatPagination = () => {
  const setNeatPagination = useSetRecoilState(neatPaginationState)

  const activeNeatPagination = useRecoilValue(neatPaginationState)

  console.log(`[useNeatPagination]`, activeNeatPagination)

  const nextPage = useCallback(() => {
    setNeatPagination((prevState) => {
      return {
        pageNumber: prevState.pageNumber + 1,
      }
    })
  }, [setNeatPagination])

  const prevPage = useCallback(() => {
    setNeatPagination((prevState) => {
      return {
        pageNumber: max(prevState.pageNumber - 1, 1),
      }
    })
  }, [setNeatPagination])

  return useMemo(() => {
    return {
      nextPage,
      prevPage,
      activeNeatPagination,
    }
  }, [nextPage, prevPage, activeNeatPagination])
}

export default useNeatPagination


コンポーネント側


src/features/film/components/NeatPagination.tsx

/** @jsxImportSource @emotion/react */

import { css } from '@emotion/react'
import { Box, Button, Typography } from '@mui/joy'

import Spacer from '@/components/ui/Spacer'
import useNeatPagination from '@/features/film/hooks/useNeatPagination'

const NeatPagination = () => {
  const { prevPage, nextPage, activeNeatPagination } = useNeatPagination()

  console.log(`[NeatPagination]`, activeNeatPagination)
  return (
    <Box component={'aside'} className={'mx-auto mt-24 w-full max-w-lg'}>
      <Box
        css={css`
          display: flex;
          justify-content: space-between;
          align-items: center;
        `}
      >
        <Typography
          component={'h1'}
          level='h1'
          css={css`
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 0.5rem;
          `}
        >
          Neat Pagination
        </Typography>
      </Box>
      <Spacer />
      <Box
        css={css`
          display: flex;
          align-items: center;
          gap: 0.5rem;
        `}
      >
        <Button variant='solid' color='neutral' onClick={prevPage}>
          Prev Page
        </Button>
        <Button variant='solid' color='neutral' onClick={nextPage}>
          Next Page
        </Button>
      </Box>
    </Box>
  )
}

export default NeatPagination


こうすることで、今回でいうところでのページ番号をフックをImportしたコンポーネントで参照できるようになってきます。


例えば、データ取得する際に参照したりとかは使い勝手がいいと思います。


実現したい機能に合わせて応用していくのがいいかもですね。


デモサイトです。


デモコードです。


簡単ですが、以上です。


この記事が気に入ったらサポートをしてみませんか?