Robert Koritnik
Robert Koritnik

Reputation: 105071

Redux-Toolkit (RTK) Query get mutation endpoint loading state

I have a component (like a dialog box) that provides the Submit button. This dialog component then renders a form component.

Form component includes all the fields and also RTK Query to send the mutation to backend.

The problem

I would like to check the RTK Query endpoint state from the dialog component so that I can set the loading state of the submit button. Ideally hook to state changes or subscribe... If nothing else using a useEffect to run when the state changes.

Where can I read the state?

I've tried using useSelector(state => ...) that can get me the RTK state including all endpoints, but it seems that mutations always just have the "fulfilled" state value.

How can I do this?


What I'm doing now

I'm currently passing a react state from the dialog to the form:

Dialog:

const loadingState = useState<boolean>(false);

// render
<Form state={loadingState} ... />

Form:

const [_, setLoading] = props.state;
const [update] = api.useUpdateMutation();

const onSubmit = (data) => Promise.resolve()
  .then(() => setLoading(true))
  .then(() => update(data).unwrap())
  .finally(() => setLoading(false))

This works, but it would be better if the parent component that renders the dialog and the form within would just hook onto the RTK Query update mutation endpoint state changes.

Upvotes: 1

Views: 61

Answers (1)

Drew Reese
Drew Reese

Reputation: 203333

Two solutions I see being viable are:

Use a Shared fixedCacheKey

Use a shared fixedCacheKey for the update mutation and access the useUpdateMutation hook's result data in both components. This allows all instances of the mutation hook to share results.

See Shared Mutation Results for details.

Example

Dialog:

const [, { isLoading }] = api.useUpdateMutation({
  fixedCacheKey: "update"
});

// render
<Form  ... />
<button
  disabled={isLoading}
  type="submit"
>
  Submit
</button>

Form:

const [update] = api.useUpdateMutation({
  fixedCacheKey: "update"
});

const onSubmit = async (data) => {
  try {
    ...
    await update(data).unwrap();
    // mutation success
  } catch(error) {
    // Catch & handle/ignore any submission errors/rejections
  }
};

Completely Hoist the Hook to Parent

Hoist the useUpdateMutation to the parent Dialog component and pass down the update trigger function as props to the Form.

Example

Dialog:

const [update, { isLoading }] = api.useUpdateMutation();

// render
<Form update={update}  ... />
<button
  disabled={isLoading}
  type="submit"
>
  Submit
</button>

Form:

const onSubmit = async (data) => {
  try {
    ...
    await props.update(data).unwrap();
    // mutation success
  } catch(error) {
    // Catch & handle/ignore any submission errors/rejections
  }
};

Upvotes: 0

Related Questions