Effect CommunityEC
Effect Community•2y ago•
35 replies
BinaryArtifex

Seeking Feedback on Refactoring and Abstracting TypeScript Fetch Implementation

Id like to refactor this slightly if i can get to the bottom of my issue in the thread above, however is anyone able to provide some feedback on this implementation so far? ideally all those states could be consolidated into a reducer but this is also a slightly contrived example to prevent too much verbosity...ideally id come up with a way abstracting out the meat of this to reuse elsewhere

export function useFetchSite(args: { id: number }) {
  const [initializing, setInitializing] = useState(true);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string>();
  const [data, setData] = useState<SiteDetails>();

  const fetchData = useCallback((id: number) => {
    return Effect.gen(function* ($) {
      const service = yield* $(SiteService);

      yield* $(
        Effect.all([
          Effect.sync(() => setInitializing(true)),
          Effect.sync(() => setLoading(true)),
          Effect.sync(() => setError(undefined)),
        ]),
      );

      yield* $(
        service.getById({ id }),
        Effect.tapBoth({
          onSuccess: (data) =>
            Effect.all([
              Effect.sync(() => setData(data)),
              Effect.sync(() => setInitializing(false)),
              Effect.sync(() => setLoading(false)),
              Effect.sync(() => setError(undefined)),
            ]),
          onFailure: (err) =>
            Effect.all([
              Effect.sync(() => setData(undefined)),
              Effect.sync(() => setInitializing(false)),
              Effect.sync(() => setLoading(false)),
              Effect.sync(() => setError(err.message)),
            ]),
        }),
      );
    }).pipe(AppRuntime.runPromise);
  }, []);

  const retry = useCallback(() => setInitializing(true), []);

  useEffect(() => {
    if (initializing) {
      fetchData(args.id);
    }
  }, [args.id, fetchData, initializing]);

  return { loading, error, data, retry };
}
Was this page helpful?