Open14

Recoil でいい感じにデータフェッチしたい

bhbsbhbs

GET はいい感じになってるとして、POST とか DELETE は?

bhbsbhbs

ローカルステートを変更しつつサーバに副作用投げてくれるのかと思ったけど、
ただ投げてくれるだけなのか

bhbsbhbs

fetch とローカルステート返す async selector 作ってやれば上手くいく気がしてきた

bhbsbhbs
const localState = atomFamily<null | Beer[], string>({
  key: "atom",
  default: null,
});

const asyncSelector = selectorFamily({
  key: "test",
  get:
    (id: string) =>
    async ({ get }): Promise<Beer[]> => {
      const _localState = get(localState(id));
      if (_localState !== null) return _localState;

      return fetch(`https://api.sampleapis.com/beers/${id}`).then((res) =>
        res.json()
      );
    },
});

const useAsyncSelector = (id: string) => {
  const value = useRecoilValueLoadable(asyncSelector(id));

  const refresh = useRecoilCallback(
    ({ refresh, reset }) =>
      () => {
        reset(localState(id));
        refresh(asyncSelector(id));
      },
    []
  );

  const addBeer = useRecoilCallback(
    ({ snapshot, set }) =>
      async (beer: Beer) => {
        // kick POST
        const state = (await snapshot.getPromise(asyncSelector(id))) || [];
        set(localState(id), [beer, ...state]);
      },
    []
  );

  const deleteBeer = useRecoilCallback(
    ({ snapshot, set }) =>
      async (beerId: number) => {
        // kick DELETE
        const state = (await snapshot.getPromise(asyncSelector(id))) || [];
        set(
          localState(id),
          state.filter((beer) => beer.id !== beerId)
        );
      },
    []
  );

  return {
    value,
    refresh,
    addBeer,
    deleteBeer,
  };
};
bhbsbhbs

setter を reducer にしてしまう方が良いのか?

bhbsbhbs

selector の setter はそんな自由にやるものではなさそう

export interface ReadWriteSelectorFamilyOptions<T, P extends SerializableParam> {
  key: string;
  get: (param: P) => (opts: {
    get: GetRecoilValue,
    getCallback: GetCallback,
  }) => Promise<T> | Loadable<T> | WrappedValue<T> | RecoilValue<T> | T;
  set: (
      param: P,
  ) => (
      opts: { set: SetRecoilState; get: GetRecoilValue; reset: ResetRecoilState },
      newValue: T | DefaultValue,
  ) => void;
  // cachePolicyForParams_UNSTABLE?: CachePolicyWithoutEviction; TODO: removing while we discuss long term API
  cachePolicy_UNSTABLE?: CachePolicyWithoutEquality; // TODO: using the more restrictive CachePolicyWithoutEquality while we discuss long term API
  dangerouslyAllowMutability?: boolean;
 }
bhbsbhbs

recoil-sync というので URL と sync するらしい、DB との sync はないのか