📚

SWRとイチャイチャする方法

2024/07/19に公開

/creation/app/README.md

useStateをつかいそうになったら

キャッシュしたほうがいいならSWR入ってるので使ってね。

[SWR公式]

const useLists = (lists) => {
  let [states, setStates] = useState(lists);
  useEffect(() => {
    if (states === undefined || states.length === 0) return;
    states = states.map((state) => new List({ data: state }));
  }, [states])
  if (lists === undefined) return { lists: [] };
  lists = new Lists({ states, setStates });
  return { lists };
};

SWRでこうなる:

const useLists = ({ user }, { onSuccess }) => {
  const SWR = useSWR(user ? `/users/${user.id}/lists` : null, { onSuccess });
  const { isMutating, trigger } = useSWRMutation(user ? `/users/${user.id}/lists` : null, (path: string, { arg }: any) => arg() );
  return {
    SWR,
    lists: SWR.data && new Lists({ data: SWR.data, isMutating, trigger })
  };
};

SWR: fetchって毎回挟む必要ないんだな。だけどロジックは欲しいんだな。だからクラスってやっぱ必要やねんな。って話

たとえば

要件: チャット部屋を作る

構造

- rooms
    - room
        - members
        - contents // チャットのメッセージボディを配列で持っている。今回の話にでてくる。

サンプルコード

※ room.getAnotherUserIdメソッド: チャット部屋の相手のidを返す


const ListItemRoom = ({ room }) => {
  const router = useRouter();
  const { mine } = useAppContext();
  room = new Room(room, { mine });
  const SWRuser = useSWR(mine ? `/users/${room.getAnotherUserId()}` : null);
  const SWRthumbnails = useSWR(mine ? `/users/${room.getAnotherUserId()}/thumbnails` : null);
  // const SWRfollowings = useSWR(mine ? `/users/${room.getAnotherUserId()}/followings` : null);
  const SWRlists = useSWR(mine ? `/users/${room.getAnotherUserId()}/lists` : null);
  
  if (SWRuser.isLoading)
    return
  if (SWRlists.isLoading)
    return;

  const user = new User(SWRuser.data);

  return (
    <Fragment>
      <Divider />
      <ListItem alignItems="flex-start" sx={{ px: 1, py: .5, pb: 2 }}>

解説

  • 子component: <LatestContent room={room} />
    • roomを引数にとるが、ロジックとしてはroom.idをもとにcontentsをfetchしてるだけ。

Discussion