question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[react] Support for generic createApi type

See original GitHub issue

version

Issues

Hello, I’m currently writing a ui framework agnostic library using redux-toolkit as core state management solution.

Currently, it seems impossible to decouple my core from any react related dependencies if I want to use auto-generated hooks and its typings of @reduxjs/toolkit/query/react

here are the libraries i am writing

  • my-lib-core: provide abstractions for api fetching, state management (no dependency to any ui libraries)
  • my-lib-react: wrap my-lib-core with react api
  • my-lib-vue: wrap my-lib-core with vue api
  • etc…

if i create Api with createApi exported from @reduxjs/toolkit/query. i have to manually write all api hooks.

To avoid inventing the wheels, I searched documentations and official type declarations, but no luck

Details

Dependency Injection using Generic types

I am experimenting with generic createApi like this

import  {CreateApi} from '@reduxjs/toolkit/query';

const createMyApi = <T>(createApi: CreateApi<T>) => {
  return createApi({...});
}

but it fails because CreateApi types requires unique symbol

So i did this:

core/api.ts

// not officially supported type
import type {ModuleName} from '@reduxjs/toolkit/dist/query/apiTypes';
import  {CreateApi} from '@reduxjs/toolkit/query';

const createMyApi = <T extends ModuleName>(createApi: CreateApi<T>) => {
  return createApi({...});
};

react/api.ts

import {createMyApi} from 'core/api';
import {
  buildCreateApi,
  coreModule,
  reactHooksModule,
} from '@reduxjs/toolkit/query/react';
import {useStore} from './hooks/useStore';
import {useDispatch} from './hooks/useDispatch';
import {useSelector} from './hooks/useSelector';

const customCreateApi = buildCreateApi(
  coreModule(),
  reactHooksModule({
    useDispatch,
    useSelector,
    useStore,
  }),
);

const api = createMyApi(customCreateApi);

this works, but uses unofficial types.

Official api converter

i think it would be better if a converting helper was provided.

import {createApi} from '@reduxjs/toolkit/query';
import {withHooksHelper} from '@reduxjs/toolkit/query/react';

const api  = createApi({...});

const apiWithHooks = withHooksHelper(api);

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:12 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
kasparkallascommented, Dec 9, 2021

To add to the discussion, I’m also building a UI-agnostic core API package using RTK-Query, i.e. it’s a slice published to NPM that consumers will plug into their Redux store.

I don’t want to include React hooks in the core library but I also don’t want to give up this amazing feature. I also want to include the upcoming SSR/redux-persist support without actually including these dependencies in the core.

I hope it makes sense. In a nut shell, I want all the power of RTK-Query but in a completely compatible and agnostic manner. 😃

A issue arises from the fact that createApi is not a callback and creates a concrete object. This means I have to choose @reduxjs/toolkit/dist/query or @reduxjs/toolkit/dist/query/react at the time of creation. The same applies for injectEndpoints which I’ve used to organize the code.

My current strategy is to make creation of the core API slice a callback (similar to OP) which takes createApi as input so the consumers decide whether they want the hooks or not. The callback will have extension point to include SSR/redux-persist support as well (to add the hydration reducers). I probably will have to abandon injectEndpoints usage though.

*by “callback” I mean exporting a function to create the slice instead of actually creating the slice and exporting it.

Currently working on it. No question here – just sharing my experience and the way I’m using RTK-Query.

0reactions
markeriksoncommented, May 22, 2022

I’m going to close this because we don’t have any plans to make specific changes in this direction, and tbh I’m not sure what changes we could make.

To be clear, this is not a “we will never add anything like this” - it’s more of a “we don’t have time to investigate this ourselves” thing.

If anyone can actually put together a PR that improves this behavior, we can definitely take a look.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Usage With TypeScript
The React-specific entry point for RTK Query exports a version of createApi which ... The BaseQueryFn type accepts the following generics:.
Read more >
RTKQ: TS2339 when trying to create a generic ...
I'm currently stuck with an idea: create a generic method that would ... {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react'; ...
Read more >
How to store the result of query from createApi in a slice?
1 Answer 1 · Hi, @phry I am following extraReducer approach for the experiment. I m storing data to slice reducer when endpoint...
Read more >
Introduction to Redux Toolkit Query with TypeScript
It offers excellent support for TypeScript because it is written in it. ... Both builder.query and builder.mutation uses generic types.
Read more >
RTK Query Best Practices
In June 2021, Redux Toolkit introduced a powerful tool for data fetching and caching called RTK Query. Compared to popular alternatives like React-Query, ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found