React useAsync 钩子

Beginner

This tutorial is from open-source community. Access the source code

简介

在本实验中,我们将学习如何在 React 中使用 useAsync 钩子来处理异步调用。这个自定义钩子允许我们定义一个处理函数,然后在使用 useReducer 钩子更新组件状态的同时异步运行它。在本实验结束时,你将能够在 React 应用程序中创建用于处理异步数据的可重用代码。

React useAsync 钩子

虚拟机中已提供 index.htmlscript.js。一般来说,你只需要在 script.jsstyle.css 中添加代码。

这段代码创建了一个处理异步调用的自定义钩子。它接受一个处理函数 fn,并返回一个包含 state 属性(valueerrorloading)以及一个异步 run 函数的对象。run 函数运行提供的回调函数 fn,同时根据需要使用 dispatch 来更新 state

const useAsync = (fn) => {
  const initialState = { loading: false, error: null, value: null };

  const stateReducer = (state, action) => {
    switch (action.type) {
      case "start":
        return { loading: true, error: null, value: null };
      case "finish":
        return { loading: false, error: null, value: action.value };
      case "error":
        return { loading: false, error: action.error, value: null };
      default:
        return state;
    }
  };

  const [state, dispatch] = React.useReducer(stateReducer, initialState);

  const run = async (args = null) => {
    try {
      dispatch({ type: "start" });
      const value = await fn(args);
      dispatch({ type: "finish", value });
    } catch (error) {
      dispatch({ type: "error", error });
    }
  };

  return { ...state, run };
};

const RandomImage = (props) => {
  const imgFetch = useAsync((url) =>
    fetch(url).then((response) => response.json())
  );

  return (
    <div>
      <button
        onClick={() => imgFetch.run("https://dog.ceo/api/breeds/image/random")}
        disabled={imgFetch.loading}
      >
        加载图片
      </button>
      <br />
      {imgFetch.loading && <div>加载中...</div>}
      {imgFetch.error && <div>错误 {imgFetch.error}</div>}
      {imgFetch.value && (
        <img
          src={imgFetch.value.message}
          alt="头像"
          width={400}
          height="auto"
        />
      )}
    </div>
  );
};

ReactDOM.createRoot(document.getElementById("root")).render(<RandomImage />);

请点击右下角的“启动实时服务器”以在端口 8080 上运行网络服务。然后,你可以刷新“Web 8080”标签页来预览网页。

总结

恭喜你!你已经完成了 React useAsync 钩子实验。你可以在 LabEx 中练习更多实验来提升你的技能。