Using an API call in ComponentDidMount to update a Redux repository makes my component render twice

I am new to React / Redux. Any help would be great. I have a component that calls an API call on ComponentDidMount to retrieve data, and then updates my Redux store. This component also uses the connection to get the state of Redux and pass it as the details to the silent component.

componentDidMount() { this.props.dispatch(fetchSite()) //this triggers the api call and updates the redux store. } return ( <div> <Child myprop={this.props.name} /> </div> export default connect((state) => ({name: state.name}))(Container); 

Since componentDidMount starts after the component is rendered, it will display, run the api, and then re-render because the api changed the state of the reduction. This makes it so that the component is displayed twice. The first time without any data, and then the second with good data from the api.

Is there a better way?

Since my child component displays different things based on props, it is transmitted, it briefly shows something else the first time it is displayed. Then, when the api updates the repository and the components are reprocessed, it again shows something else. This is a flicker of two different states.

Is there a way to do this only once with the correct API data?

+9
reactjs redux
source share
3 answers

Think about what's going on here.

The page and all its assets are loaded in the browser, scripts are launched, and all React components are displayed. Only after they are displayed do you receive your data. So, of course, there will be an initial state, followed by a loaded state.

So, how do you feel about the state of your application before the data gets in?

You have already expressed your unacceptable hostility to presenting an application with empty data. You can defer rendering of your application until data arrives. But this will lead to a terrible user experience. They can look at a blank page for a few seconds before something happens.

Or there’s an old bootloader trick. You might have something like isLoading: true in your initial state. This corresponds to some visual loading indicator (a traditionally rotating GIF image) in the React component. This is by far the best option if you must upload your data via AJAX.

The best way

But here's the thing: you don't need to use AJAX for your initial state. You can completely avoid this delay by adding your details 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 you only need to “moisturize” your store when you create it.

 const store = createStore(rootReducer, window.__INITIAL_DATA__); 
+7
source share

It is best for fetchSite to return some error information, indicating that your component has not yet completed. You must also submit this action to componentWillMount. The sender should simply return null if fetchSite returned the loading indicator data. When fetchSite actually completes, it initiates a repository update, and the component will receive the actual data in the next call to fetchSite in the WillMount component.

0
source share

Another case on my part is loading a component using React Lazy. In the loaded component, componentDidMount / useEffect was called several times when I used asynchronous dispatch with redundancy. So when I removed React Lazy, the problem was resolved.

0
source share

All Articles