gpt4 book ai didi

reactjs - useReducer 中返回参数的通用类型

转载 作者:行者123 更新时间:2023-12-02 10:37:12 26 4
gpt4 key购买 nike

我正在编写一个自定义 Hook 来从 API 获取一些数据。如果可能的话,我希望返回的数据是类型安全的。这可以用泛型来完成吗?

type Action = { type: 'PENDING' } | { type: 'SUCCESS'; payload: any } | { type: 'FAIL' };

interface State {
isLoading: boolean;
isError: boolean;
data: any;
}

const dataFetchReducer = (state: State, action: Action): State => {
switch (action.type) {
case 'PENDING':
return {
...state,
isLoading: true,
};
case 'SUCCESS': {
return {
...state,
isLoading: false,
isError: false,
data: action.payload,
};
}
case 'FAIL':
return {
...state,
isLoading: false,
isError: true,
};
default:
throw new Error('Action not supported');
}
};

const baseUrl = 'http://localhost:4000';

function useDataFetchFromAPI(initUrl: string, initData: any) {
const [url, setUrl] = useState(`${baseUrl}${initUrl}`);
const [state, dispatch] = useReducer(dataFetchReducer, {
isLoading: false,
isError: false,
data: initData,
});

// effect only runs if url changes
// see deps array (2nd argument)
useEffect(() => {
const fetchData = async () => {
dispatch({ type: 'PENDING' });
try {
const result = await axios(url);
dispatch({ type: 'SUCCESS', payload: result.data });
} catch (error) {
dispatch({ type: 'FAIL' });
}
};
fetchData();
}, [url]);
const executeFetch = (url: string) => {
setUrl(url);
};
return { ...state, executeFetch };
}

用法为useDataFetchFromAPI('url', []) .

我想你可以做类似 useDataFetchFromAPI < SomeType > () 的事情并通过它,但我不确定实现情况。

最佳答案

import axios, { AxiosPromise } from 'axios';
import { FC, useEffect, useReducer, useState } from 'react';

type Action<T> = { type: 'PENDING' } | { type: 'SUCCESS'; payload: T } | { type: 'FAIL' };

interface State<T> {
isLoading: boolean;
isError: boolean;
data: T;
}

const createDataFetchReducer = <T>() => (state: State<T>, action: Action<T>): State<T> => {
switch (action.type) {
case 'PENDING':
return {
...state,
isLoading: true,
};
case 'SUCCESS': {
return {
...state,
isLoading: false,
isError: false,
data: action.payload,
};
}
case 'FAIL':
return {
...state,
isLoading: false,
isError: true,
};
default:
throw new Error('Action not supported');
}
};

const baseUrl = 'http://localhost:4000';

function useDataFetchFromAPI<T>(initUrl: string, initData: T) {
const [url, setUrl] = useState(`${baseUrl}${initUrl}`);
const dataFetchReducer = createDataFetchReducer<T>();
const [state, dispatch] = useReducer(dataFetchReducer, {
isLoading: false,
isError: false,
data: initData,
});

// effect only runs if url changes
// see deps array (2nd argument)
useEffect(() => {
const fetchData = async () => {
dispatch({ type: 'PENDING' });
try {
const axiosPromise: AxiosPromise<T> = axios(url);
const result = await axiosPromise;
dispatch({ type: 'SUCCESS', payload: result.data });
} catch (error) {
dispatch({ type: 'FAIL' });
}
};
fetchData();
}, [url]);
const executeFetch = (url: string) => {
setUrl(url);
};
return { ...state, executeFetch };
}

const MyComponent: FC<{}> = props => {
type Response = { foo: number; }
const x = useDataFetchFromAPI<Response>('/foo', {
foo: 1
});
x.data.foo;

return null;
};

关于reactjs - useReducer 中返回参数的通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55396438/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com