数据请求-基于reducer自定义hook

2023-06-27  本文已影响0人  海豚先生的博客
// 使用useReducer 管理复杂的state
const dataFetchReducer = (state, action) => {
  switch (action.type) {
    case 'FETCH_INIT':
      return {
        ...state,
        isLoading: true,
        isError: false
      };
    case 'FETCH_SUCCESS':
      return {
        ...state,
        isLoading: false,
        isError: false,
        data: action.payload,
      };
    case 'FETCH_FAILURE':
      return {
        ...state,
        isLoading: false,
        isError: true,
      };
    default:
      throw new Error();
  }
};
// 自定义数据请求hook
const useDataApi = (initialUrl, initialData) => {
  const [url, setUrl] = useState(initialUrl);
  // useReducer的第二个参数为state的初始值
  const [state, dispatch] = useReducer(dataFetchReducer, {
    isLoading: false,
    isError: false,
    data: initialData,
  });

  useEffect(() => {
    let didCancel = false;
    const fetchData = async () => {
      // 设置state为初始值
      dispatch({ type: 'FETCH_INIT' });

      try {
        const result = await axios(url);

        if (!didCancel) {
          // 数据请求成功,变更state值
          dispatch({ type: 'FETCH_SUCCESS', payload: result.data });
        }
      } catch (error) {
        if (!didCancel) {
          // 数据请求失败,变更state值,state变更的值已在reducer中定义
          dispatch({ type: 'FETCH_FAILURE' });
        }
      }
    };

    fetchData();
    // 组件卸载时停止数据请求
    return () => {
      didCancel = true;
    };
  // 查询字符串变化时重新请求数据
  }, [url]);

  return [state, setUrl];
};
// 在组件中使用自定义hook,state绑定数据展示视图,查询触发setUrl
const [state, setUrl] = useDataApi(initialUrl, initialData)

参考自:https://www.robinwieruch.de/react-hooks-fetch-data/
上一篇 下一篇

猜你喜欢

热点阅读