Upgrade to Pro — share decks privately, control downloads, hide ads and more …

recoil

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for 8zca 8zca
January 05, 2021

 recoil

Avatar for 8zca

8zca

January 05, 2021
Tweet

More Decks by 8zca

Other Decks in Programming

Transcript

  1. 空のフロントエンド • 状態管理 ◦ Redux Tool Kit ◦ 素の Redux

    より簡単に書ける • API から取得したデータ ◦ swr 他にはreact-query、apollo-client 他には素のreact-redux、context api、 mobx、unstated
  2. atom 最小単位の state です。 useState と同じ使い方ができます(複数コンポーネントにまたがっ て write/read できます)。 atom

    が変わったら再描画されます。 import { atom } from 'recoil' export const userSearchState = atom<string>({ key: 'userSearchState', default: '' }) const setSearchValue = useSetRecoilState(userSearchState) const [searchValue, setSearchValue] = useRecoilState(userSearchState) const searchValue = useRecoilValue(userSearchState) 書き込みだけしたい 読み書き両方 読み込みだけしたい
  3. selector atom の状態をもとに何かを処理した結果を持つことができます。 selector を使っている場合、 atom の変更だけでは再描画されず selector が変わったときだ け再描画されます。

    export const userListSelectorState = selector<UserType[]>({ key: 'userListSelectorState', get: async ({ get }) => { const search = get(userSearchState) if (!search) return [] const res = await fetch(`/api/users?q=${search}`) return res.json() } }) get内でget関数を引数に受け取り、他の stateを 取得することができる。 この例では検索ワードを受け取り、 apiにリクエス トしている。 もちろん、component側から検索ワードを引数に selectorを呼び出してもよい。 ※setもありますが未検証
  4. selector を呼び出す例 const userList = useRecoilValueLoadable(userListSelectorState) switch(userList.state) { case 'loading':

    return <div>Loading..</div> case 'hasError': return <div>Error!!</div> case 'hasValue': if (userList.contents.length === 0) return <div>No results</div> return userList.contents.map((user) => <div key={user.id}>{user.name}</div>) } useRecoilValue で取り出すこともできます。 その場合は React suspence でローディングの処理がされます。 ただ、 SSR においては suspence が動かないので Loadable をかます必要が あります。
  5. react-reduxとの比較 • code split しやすい ◦ コンポーネントに必要な state だけ読み込める combine

    reducer reducer reducer selector atom atom selector component A component A redux recoil
  6. react-reduxとの比較 • 記述量が減る • action を dispatch しなくてもいい const dispatch

    = useDispatch() const users = useSelector((state: RootState) => state.users) useEffect(() => { dispatch(fetchUsers()) }, []) const users = useRecoilValueLoadable(userListSelectorState)
  7. react-reduxとの比較 • selector の get は memo 化してくれる ◦ https://recoil-sample.8zca.vercel.app/users

    ◦ Tom で検索、 2 回め同じ Tom で検索したらリクエストは走らずに結果が表示される
  8. まとめ • ええやん • 半日触った結果、非同期処理も含めて react-redux より簡単に扱えるのでプロダク ションで使ってもいいレベル ◦ zenn

    も recoil 使ってるしね ◦ 導入も簡単。型定義も install 不要 ◦ hooks 全開。 • コンポーネント側から見ると atom か selector かは識別してなさそうなので、 selector だ けで運用するというのもやりようによっては可能 ◦ アンチパターンな気がする ◦ atom と selector をちゃんと使い分けしましょう