Good Day Good Day - 16 days ago 5
Javascript Question

dispacthing actions creator gets called twice using componentWillMount

I call action creator using componentWillMount method, then it gets called twice. look at below screenshot of the result.

enter image description here

this is my action creator :

export function fetchAdmin(){
return (dispatch)=>{
axios.get(`${Config.API_URL}/admin`,{
headers: { authorization: localStorage.getItem('token')}
})
.then(response => {
return dispatch({
type: FETCH_DATA,
payload: response.data
});
}
)
.catch(response => {
console.log(response);
});
}
}


and this is my reducer :

import { FETCH_DATA } from '../actions/types';

export function admin(state= {}, action){
switch(action.type){
case FETCH_DATA:
return {...state, lists: action.payload };
default:
return { state, lists: 'YEY!'}
}


}


and this is my container and the way i call my action creator using componentWillMount.

import React, { Component } from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import * as actions from 'actions/admin_action';


class Admin extends Component{
componentWillMount(){
this.props.fetchAdmin()
}
renderData(){
var lists = this.props.lists;
console.log(lists);
}
render(){

return(
<div>
{this.renderData()}
</div>
)
}

const mapStateToProps = (state) => {
return { lists: state.admin.lists };
}

export default connect(mapStateToProps, actions)(Admin);


from the screenshot i assume that render() gets called twice. the first call goes to default action creator so that the result is "YEY!" and the second is the valid one.

can someone explain it to me why componentWillMount perform like this and actually in the first render i just wanna my array not "YEY!" how to solve this problem? Thank you.

Answer

There is no problem here! When your component render first time, it reached the rendering before the logic componentWillMount is finished, so:

First time rendering: Your component is rendered while the lists in global state is the default which equals YEY!.

Second time rendering: When data is fetched successfully, after that the reducer change in the lists in the global state with the fetched ones, after that your component detects the change due to mapStateToProps that got the lists from the global state.

Needless to say that React component is re-rendered on propsChange, that's why there is a method componentWillReceiveProps so that you can add some logic (if you need) on each time your props change.

This behavior allows you to handle waiting the data to be fetched by:

  • Add a loading spinner.
  • Get your layout rendered.
  • Get the other components in your page rendered.
Comments