1

I'm having an issue with a component that is rendering from an external site that is rendering twice, I'm using react 18 and I already use a ref to handle the strict mode and new useEffect behavior, but i can't figure out why my dispatch is executing twice. I have removed everything from the component leaving only the log and I still get the same problem.

Routes:

  return (
    <Grid>
      <PersistGate loading={null} persistor={persistor}>
        <SidebarProvider>
          <Routes>
            <Route path="/" element={<Welcome />} />
            <Route path="oauth2-callback" element={<Oauth />} />
            <Route element={<ProtectedRoutes />}>
              <Route element={<Layout />}>
                <Route path="/home" element={<Home />} />
                <Route path="/client-view/*" element={<Submission />} />
              </Route>
            </Route>
          </Routes>
        </SidebarProvider>
      </PersistGate>
    </Grid>
  );
};

export default App;

Component:

import { useSearchParams } from "react-router-dom";
import { useAppDispatch } from "../../store/hooks/hooks";
import { getOauth } from "../../store/thunks/app/app.thunks";

const Oauth = () => {
  const dispatch = useAppDispatch();
  const shouldDispatch = useRef(true);
  const [searchParams] = useSearchParams();
  useEffect(() => {
    if (shouldDispatch.current) {
      shouldDispatch.current = false;
      dispatch(
        getOauth({
          code: searchParams.get("code") || "",
          state: searchParams.get("state") || "",
        })
      );
    }
  }, []);
  return null;
};

export default Oauth;

URL: https://localhost:3000/oauth2-callback?state=dsada2321&code=12345

Neketo
  • 51
  • 7
  • Using a React ref to track "mounting" is now considered a React anti-pattern. This won't help here anyway since the component is being ***mounted*** twice as a way to [ensure reusable state](https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state). It's just a React18 thing in the `React.StrictMode` component. The solution is to properly cleanup any side-effects. – Drew Reese Feb 07 '23 at 17:29

1 Answers1

0

It seems likely this is due to a new feature implemented in React 18 for Strict Mode which affects development-side only. This drove me mad initially but if you remove Strict Mode as a test, you should see the behavior stop.

https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state

React 18 strict mode causing component to render twice

Wesley LeMahieu
  • 2,296
  • 1
  • 12
  • 8
  • No, i already remove it and still happens also i was able to catch it with the ref on the component otherwise i would get 4 renders. – Neketo Feb 07 '23 at 13:15
  • My apologies, I misread that you handled for that! Can you provide details on the SidebarProvider provider? Have you tried stepping the log further up the parent tree to see when the double-render stops? I suspect either SidebarProvider or PersistGate. edit* If you wanted to provide a sandbox I could help troubleshoot this. – Wesley LeMahieu Feb 07 '23 at 13:23
  • i already tried removing both it and same result my best guess something with router v6 – Neketo Feb 07 '23 at 13:25
  • So I just realized StrictMode does not only trigger a re-render on useEffect but on the first load will load the whole application twice that and since this is an external redirect from a sso portal that's why I'm seeing two renders. Im trying to find any documentation to why or how to avoid this. A little bit weird i was able to understand the useEffect but this im unable to find any documentation or work around without removing the strictmode. – Neketo Feb 07 '23 at 13:34
  • 1
    I think the pros of the `StrictMode` component vastly outweighs any perceived cons. Suggesting to just remove it is not a viable solution unless you really just don't want the extra debugging help when developing. – Drew Reese Feb 07 '23 at 17:34
  • I agree Drew. If it's causing an issue with the app's functionality, it's a signal that side-effects need to be fixed / optimized. I could have provided more detail however it was the correct answer. – Wesley LeMahieu Feb 07 '23 at 17:50