0
votes

I have a React App, that talks to several REST APIs.

I have refactored my app from redux-thunks to use react-query for the business logic of calling the APIs.

Watching videos on react-query, it was advised to abstract this into a custom hook.

So, for example:

//
// useTodos.js
import { useQuery } from 'react-query';
import { TodoApi } from 'my-api-lib';
import config from '../config';

const todoApi = new TodoApi(config.TODO_API_BASE_URL);

const useTodos = (params) => 
  useQuery(
    [todo, params],
    ()  => todoApi.fetchTodos(params)
);

I have another App where I could use these hooks to also talk to the REST APIs. So I'd like to move the hooks into a common library. But the config is provided by the client. How do I get the config (TODO_BASE_API_URI) or even the "todoApi" instance, to the custom hook from the client?

In Redux I essentially dependency-injected the TodoApi instance at startup with "thunk with extra argument"

Is there a "hooky" way to get the global config to my custom hook?

1
Maybe try a React context? User provides a config object to the context, the hook reads from the context (via useContext). - Drew Reese
thanks, useContext, the createUseTodo answer, and passing the api instance every hook call are the solutions I have thought of. I was hoping for a different way but maybe there's not. maybe some kind of proxy environment variable - user210757

1 Answers

1
votes

The library (I assume it's my-api-lib) should export a function that expects the url (or any other config), and returns the useTodoApi hook.

In your common library:

import { useQuery } from 'react-query';
import { TodoApi } from './TodoApi';

export const createUseTodoApi = url => {
  const todoApi = new TodoApi(url);

  return params => 
    useQuery(
      [todo, params],
      ()  => todoApi.fetchTodos(params)
  );
}

In your apps:

import { createTodoApi } from 'my-api-lib';
import config from '../config';

export const useTodoApi = createUseTodoApi(config.TODO_API_BASE_URL);