pmpc
pmpc

Reputation: 493

RTK Query: How to call Redux API endpoint on change event?

I'm new to React and Redux and I want to do a GET request using a debouncer, whenever a user inputs change but I'm not allowed to use the hook from redux inside the onChange event. What's the best way to do this?

The eslint error I get:

ESLint: React Hook "useGetPostsQuery" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.(react-hooks/rules-of-hooks)

The reason I'm not calling it in the React component's root is because I need to call it multiple times and not only once... basically whenever the user writes something (taking into account the debouncer obviously)

Upvotes: 1

Views: 3921

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42228

How to call an endpoint from onChange

You can use the "lazy" version of your query hook when you need to call a query API from inside of an onChange handler or other function.

Each query endpoint has a useLazyQuery hook in addition to the standard useQuery hook.

You call the useLazyQuery hook at the top-level of your component so that you don't violate the rules of hooks. But calling the hook doesn't actually execute the API call. Calling the hook returns a trigger function. Then your event handler calls the trigger function with the correct arguments to execute the API call.

const options = { pollingInterval: 1000 };

const [trigger, result, lastPromiseInfo] = api.useLazyGetPostsQuery(options);

const onChange = (e) => {
    trigger(e.target.value);
}

How to use a top-level query with onChange

The other way to approach this problem is to call the standard useQuery hook in the normal way. Instead of calling the API directly from your onChange, you can use the onChange handler to setState in your component. Then pass those stateful variables as arguments to your useQuery hook.

const [text, setText] = useState('');

const options = { pollingInterval: 1000, skip: text === '' };

const result = api.useGetPostsQuery(text, options);

const onChange = (e) => {
    setText(e.target.value);
}

Upvotes: 6

Related Questions