Search code examples
javascriptreactjspropertiesreact-hooksdynamically-generated

A good practice for renaming properties of a react hook?


I use a react library ex. react-query. This library provides a hook useQuery ex.

const {data, isLoading} = useQuery(['users'], userService.getUsers);

My problem is that if I want to use two useQuery hooks, in order to avoid having duplicated named variables:

data, isLoading

I have to do something like this:

const users = useQuery(['users'], userService.getUsers);
const products = useQuery(['products'], userService.getProducts);

...
// then use
users.data, users.isLoading
// and
products.data, products.isLoading
...

In order to make this logic more consistent, I tried to make my own custom hooks and rename the properties provided by useQuery inside so I can access with spread syntax.

function useGetUsers(){
    const {data, isLoading} = useQuery(['users'], userService.getUsers);
    return {
        usersData: data,
        isUsersLoading: isLoading
    }
}

and same with products.

So now, I can write the previous example as:

const {usersData, isUsersLoading} = useGetUsers();
const {productsData, isProductsLoading} = useGetProducts();

Of course, in order to have all the keys, I iterated over all the keys provided by useQuery hook and customized my own custom keys with my own camel case rules, etc.

My question is, is this ok ? I mean, is this consider a good practice or just go with the users.isLoading logic ??


Solution

  • I find it surprising that the hook returns an object rather than an array like useState does, because this is why useState returns an array. (I'm not familiar with that hook; perhaps it returns a lot of things, in which case using named properties does make sense.)

    You can use renaming in the destructuring:

    const {data: users, isLoading: usersLoading} = useQuery(['users'], userService.getUsers);
    const {data: products, isLoading: productsLoading} = useQuery(['products'], userService.getProducts);
    

    Then use users and usersLoading for the users stuff, and products/productsLoading for the products stuff.


    If you're going to write your own hook, I think I'd rather write a general one that returns an array:

    function useStuff(what, how) {
        const {data, isLoading} = useQuery(what, how);
        return [data, isLoading];
    }
    

    Then:

    const [users, usersLoading] = useStuff(['users'], userService.getUsers);
    const [products, productsLoading] = useStuff(['products'], userService.getProducts);