Search code examples
reactjsreact-hooksrtk-query

React useEffect: how prevent a RTK query mutation to be executed twice?


I have this Component:

/* eslint-disable */
import React, { useEffect, useState } from "react";
import { usePostValidateMutation } from "./features/apiSlice";

export const App = () => {
  const [postValidate] = usePostValidateMutation();

  const [token, setToken] = useState(undefined);

  useEffect(() => {
    const queryParameters = new URLSearchParams(window.location.search);
    const tokenParam = queryParameters.get("token");
    console.log(tokenParam);
    setToken(tokenParam);
    validate();
  }, []);

  const validate = async () => {
    await postValidate(token)
      .unwrap()
      .then((data) => console.log(data))
      .catch((error) => console.log(error));
  };

  return (
    <div className="container-fluid">
      <Stats />
    </div>
  );
};

export default App;

App is called with a token in querystring: http://localhost?token=a1b2c3.

I need to get that (short live) token and make an API call (Via RTK Query mutation) to get a long lived token.

My issue is that useEffect run twice and not once (I see two API call and twice printed token in console).


Solution

  • It's likely caused by StrictMode having been enabled.

    This is on by default in newer version of React (React 18), but can be disabled for some development purposes.

    const root = createRoot(document.getElementById('root'));
    root.render(
      <StrictMode>
        <App />
      </StrictMode>
    );
    

    Strict Mode enables the following development-only behaviors:

    Additionally, editing and saving your code can also cause repeated re-renders due to the React hot-reload feature that is typically enabled from apps created with React-Scripts