In fact, I’m tired of touting useRequest and useSWR (useNetworking). Even though they all look the same. What’s the most important thing for an asynchronous operation, is the address you’re requesting? Is it your condition for reposting? Cache? This, in my opinion, should not be controlled by the Hook API, but by the external request model. The Hook API should have a single responsibility — a single schedule, abstract logic, and provide change dependencies.

So, I don’t know what needs these useNetworking can solve. They try to combine the scheduling of network requests with React, but I don’t see any benefit other than complexity, let alone allowing users to design complex components. They should treat the request as a module outside of React, rather than forcing it into combination, which is why I designed useAsync.

Furthermore, I can say that the developers who design these apis consider useCallback to be a bad smell and a mental burden on users, so they try to avoid using it. However, useCallback itself does not have the mental burden of users. Users are smart.

Actually, useAync should be a type of useCallback, but we need to pass in a function that returns a Promise. This is how the API should be designed.

interface AsyncData<T> {
	data: T;
	isLoading: boolean;
	error: any;
} 

const useAsync: <T>(fn: () => Promise<T>, deps: any[]) = > AsyncData<T>;
Copy the code

It is sometimes unclear why libraries design hook apis without passing in dependencies. In fact, the Hook API automatically detects dependencies by configuring eslint-kerosene-deps.)

Then, go straight to the code.

const useAsync: <T>(fn: () => Promise<T>, deps: any[]) = > AsyncData<T> = (fn, deps) = > {
  const [data, setData] = React.useState();
  const [isLoading, setIsLoading] = React.useState(false);
  const [error, setError] = React.useState();

  const callback = React.useCallback(fn, deps);

  useEffect(() = > {
    // To solve the problem of network latency
    // When the network initiates the request,
    // The timing of the callback may be different,
    // So the order of setData also needs to be guaranteed,
    // Ensure that the data retrieved is the data for the callback of the most recently initiated request.
    let destroyed = false;
    
    (async () => {
      setIsLoading(true);
      try {
        const res = await callback();
        if (destroyed) {
          return;
        }
        setData(res);
      } catch (e) {
        if (destroyed) {
          return;
        }
        setError(e);
      }
      if (destroyed) {
        return;
      }
      setIsLoading(false); }) ();return () = > (destroyed = true);
  }, [callback]);

  return {
    data,
    isLoading,
    error,
  };
};
Copy the code

The above code has been used in production environments.

conclusion

This API covers all cases. React Hook network requests and React Hook are two different scheduling methods. Forcibly coupling them together can only be counterproductive. Instead of using useRequest and useSWR to control so-called caching, resending, or canceling, it is appropriate that you handle your own network requests.