Búsqueda de sitios web

reactjs - Hook Personalizado - devolver estado y establecer estado


Estoy tratando de usar un hook personalizado de manera similar a como se describe aquí: https://www.robinwieruch.de/react-hooks-fetch-data

Este es mi hook personalizado:

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];
    };

Estoy accediendo al hook como:

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

El error de TypeScript recibido es:

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

¿Alguien ve lo que estoy haciendo mal aquí?

Respuesta #1

Parece que Typescript no está infiriendo el tipo de retorno de la manera que deseas. También falla en ejemplos simples, como este:

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

Necesitamos darle un poco de ayuda a Typescript, así que declaramos explícitamente el tipo de retorno, lo que permitirá que las variables a b c tengan los tipos correctos:

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

Para tu código, querrás algo como esto:

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