score:7

Accepted answer

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__);

score:0

A better way is for fetchSite to return some mock info immediately indicating your component that its not done yet. Also you should dispatch this action in componentWillMount. The render should simply return null if fetchSite returned the loading indicator data. When fetchSite actually finishes, it will trigger the store update and the component will get the actual data in the next fetchSite call in componentWillMount.

score:0

Another case in my side that, I was loading my component with React Lazy. In the loaded component componentDidMount / useEffect were called multiple times when I used async dispatch with redux. So when I removed React Lazy the problem is solved.


Related Query

More Query from same tag