Using an API call in ComponentDidMount to update Redux store makes my component render twice
Let's think about what's going on here.
The page and all its assets are loaded in the browser, the scripts are run and all the React components are rendered. Only after they're rendered do you fetch your data. So of course there will be an initial state followed by a loaded state.
So how do you deal with the state of your app before the data comes in?
You've already expressed your understandable dislike of presenting the app with blank data. You could delay the rendering of your app until the data arrives. But this would result in a horrible user experience. They could be staring at a blank page for potentially several seconds before anything happens.
Or there's the old loader trick. You might have something like isLoading: true
in your initial state. That would correspond to some visual loading indicator (traditionally a spinning GIF image) in your React component. This is surely the best option if you must load in your data via AJAX.
A better way
But here's the thing: you don't need to use AJAX for your initial state. You can avoid this delay entirely by appending your data to the page.
<!-- place this BEFORE your Redux/React scripts -->
<script>
// This object must match the shape of your Redux reducer state
var __INITIAL_DATA__ = {
todos: [{
name: "Gather requirements",
done: false
}, {
name: "Write code",
done: false
}]
};
</script>
Now all you need do is "hydrate" your store upon creation.
const store = createStore(rootReducer, window.__INITIAL_DATA__);