0

i have a problem where my component is making two api calls instead of one. I am using react and react-redux with reactjs/toolkit. I tried different solutions like changing dependancy array in useEffect hook, changing request headers, looking through entire codebase to find another call. Nothing worked. I also tried this but it did not work. Why does my fetch query run multiple times in my React component

I want this code to call api once, soon after component is mounted.

Redux dev tools shows that there are two api call. One right after another. Sceenshoot of actions in dev tools.

Here api call is dispatched.

useEffect(() => {
    dispatch(fetchPosts('hot', ''));
  }, [dispatch]);

Entire project is here: https://github.com/chpiotr06/Reddit-minimal/tree/dev

Fetching thunk looks like this:

export const fetchPosts = createAsyncThunk(
  'wall/fetchPosts',
  async (type, query) => {
    const response = await Reddit.fetchPosts(type, query);
    const data = await response.json();
    return data;
  }
)

Reddit.fetchPosts (Work in progress):

const Reddit = {
  fetchPosts: (type, query) => {
    return fetch(`https://www.reddit.com/${type}.json`, {
      method: 'GET',
      mode: 'cors',
    })
  },
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

0

Not sure if that's the right guess, but could it have to do with the strictmode? If you comment out <React.StrictMode> in index.js, does it still render twice?

edit: Glad I could help!

I did some research on react strict mode and thought I'd share my findings here. Strict-mode helps you debug your code in development mode (it has no effect on production, so no worries if you find components rendering twice). Generally, leaving it on is considered best practice since it will help detect deprecated code and spot unwanted side effects.

Now on the matter of double rendering: In version 18, react is preparing for components that can be mounted and unmounted multiple times while preserving their state. Actually, to achieve that, the components will not get unmounted in the traditional sense (removed from the component tree), but just hidden from the user. React will still call the same old unmount function to tell the component that it's being hidden, but it will also save its state to put the component back on the screen the same way it was before. That means that if an effect doesn't properly clean up subscriptions, its state is still present and the state react saved is added on top of it on rerender.

Strictmode simulates these future changes by mounting, unmounting and remounting the components while preserving their state. That's why commenting out <React.StrictMode> makes your app work, but also why it's not recommended. However, to keep on working and preserve sanity it's the only approach I know of ;)

further reading:

There's a really interesting thread over at https://github.com/reactwg/react-18/discussions/19 concerning double rendering in strict-mode. Including a breakdown of what goes wrong in redux by Andarist/Mateusz Burzyński.

and of course, the docs: https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state

Moira
  • 56
  • 6