All Articles

React-Async with TypeScript

tldr;

This is the final example code with TypeScript, react-async and axios:

import { useAsync } from "react-async";

const dataFetching = async(props:any) => {
    const response = axios.get(`/data-url/${props.categoryId}`);
    return response.data;
}

const Component = (props: { categoryId: string }) => {
    const { data, error, isLoading } = useAsync({ promiseFn: dataFetching, categoryId: props.categoryId });

    if (loading) return (...)
    if (error) return (...)
    if (data) return (...)
}

Advanced explanation

The library react-async offers components and hooks for easier data fetching. Practically speaking this means, that your current workflow of defining and settings states for loading, error and success for a fetch call can be done with this library. Without react-async you would have to write up to 35 lines of code.

const dataFetching = async(successCallback, errorCallback) => {
    try{
        const response = axios.get("/data-url/");
        sucessCallback(response);
    }catch(e){
        errorCallback(e);
    }

}

const Component = () => {
    const [loading, setLoading] = React.useState(false);
    const [error, setError] = React.useState(undefined);
    const [data, setData] = React.useState(undefined);

    useEffect(() => {
        if (data === undefined && loading === false){
            setLoading(true);
            dataFetching(
                (data) => {
                    setLoading(false);
                    setData(data);
                },
                (e) => {
                    setLoading(false);
                    setError(data);
                },
            );
        }
    })

    if (loading) return (...)
    if (error) return (...)
    if (data) return (...)
}

Thanks to react-async you can save a lot of this code by using their hooks. So for the example from above you can save more than 20 lines.

import { useAsync } from "react-async";

const dataFetching = async() => {
    const response = axios.get("/data-url/");
    return response.data;
}

const Component = () => {
    const { data, error, isLoading } = useAsync({ promiseFn: dataFetching })

    if (loading) return (...)
    if (error) return (...)
    if (data) return (...)
}

I absolutely loved it from the start, because now i don’t need to write that massive boilerplate code anymore. But i also use TypeScript very heavily. And i ran into some problems when i wanted to use the components and also the hook if i want to specify some extra props. But thanks to the creators we could fix the problems in less than 24 hours and get a working version with TypeScript. If you want to know more about the issue, you can find it here on github.

But now it’s pretty straightforward to get it working with the hook and extra props. Just keep in mind, that you have to return a promise or declare the function as async and also accept props and that’s it.

Here is the same example with TypeScript.

import { useAsync } from "react-async";

const dataFetching = async(props:any) => {
    const response = axios.get(`/data-url/${props.categoryId}`);
    return response.data;
}

const Component = (props: { categoryId: string }) => {
    const { data, error, isLoading } = useAsync({ promiseFn: dataFetching, categoryId: props.categoryId });

    if (loading) return (...)
    if (error) return (...)
    if (data) return (...)
}