自定义挂钩-返回状态和设置状态

时间:2020-09-09 13:58:57

标签: reactjs typescript react-hooks

我正在尝试使用自定义钩子,类似于此处所述: https://www.robinwieruch.de/react-hooks-fetch-data

这是我的自定义钩子:

export const useProcesses = (id: string, token: string, enqueueSnackbar: NotificationFunction) => {
    const [processes, setProcesses] = useState<ProcessDTO[]>([]);
    const [isLoading, setIsLoading] = useState(false);
    const [isError, setIsError] = useState(false);

    useEffect(() => {
        const fetchProcesses = async () => {
            setIsError(false);
            setIsLoading(true);
            try {
                if (id !== undefined) {
                    const response = await new HttpService()
                        .withToken(token)
                        .get(createProcessesPathForIdEndpoint(id), enqueueSnackbar);

                    const data = response.data.data;
                    setProcesses(data);
                    return data;
                }
            } catch {
                setIsError(true);
            }
            setIsLoading(false);
        };

        fetchProcesses();
    }, [enqueueSnackbar, id, token]);
    return [{ Processes, isLoading, isError }, setProcesses];
    };

我以以下方式访问该钩子:

    const [{ processes, isLoading, isError }, setProcesses] = useProcesses(
    id,
    token,
    enqueueSnackbar,
);

收到的打字稿错误是:

Property 'Processes' does not exist on type 'Dispatch<SetStateAction<ProcessDTO[]>> | { Processes: ProcessDTO[]; isLoading: boolean; isError: boolean; }'.  TS2339

有人在这里看到我在做什么吗?

1 个答案:

答案 0 :(得分:1)

好像Typescript并没有按照您想要的方式来推断返回类型。对于像这样的简单示例,它也失败了:

const thingy = () => {
    return ['abc', 9, 'abcd']
}
const [a, b, c] = thingy() // a, b, and c are all of type 'string|number'

我们需要给Typescript一点帮助,所以我们明确声明了返回类型,这将使​​变量a b c具有正确的类型:

const thingy = (): [string, number, string] => {
    ...

对于您的代码,您需要这样的东西:

type UseProcessesResult = [
    {
        processes: ProcessDTO[],
        isLoading: boolean,
        isError: boolean,
    },
    Dispatch<SetStateAction<ProcessDTO[]>>,
]
export const useProcesses = (id: string, token: string, enqueueSnackbar: NotificationFunction): UseProcessesResult {
    ...