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

recoil

8zca
January 05, 2021

 recoil

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 をちゃんと使い分けしましょう