3

I really don't know how to describe as precise as possible. I need some sort of initialization function after async call, that would be called only once regardless if state is changed later.

I have a component and when it mounts I make async request using action creator to get some default values, also I call somethingElse() later, which makes my UI re-render again because the state was updated:

Here is action creator:

export function requestDefaults(){    
  return {
    type:     REQUEST_DEFAULTS,
    payload:  axios.get(ROOT_URL),
  };
}

export function somethingElse(){    
  return {
    type:     SOME_OTHER,
    payload:  "Whatever",
  };
}

And my reducer:

switch (action.type) {
    case REQUEST_DEFAULTS:
      return action.payload.data;
      break;

    case SOME_OTHER:
      return action.payload;
      break;

    default:
      return state;
}

In my component - when it's maunted I make async request and when I receive response I make UI visible - in this simplified case a button, which calls somethingElse:

componentDidMount(){
   this.props.requestDefaults();
 }


render(){
  // Have received async data show button - THIS NEEDS TO BE ONLY ONCE
  if( this.props.defaults.data !== undefined ){
     <a onClick={ this.props.someThingElse }>do it</a>
  }
}

// REQUEST_DEFAULTS & SOME_OTHER
function mapStateToProps( { defaults, someOther} ){
  return { defaults, someOther} 
}

Now whenever I call this.props.someThingElse the changes to the state are made and in my render() function the button gets re-rendered again, which is the problem - I need it to be rendered only once, when I receive the async data. But now state was updated and render() is called again and because now I have this.props.defaults.data my button gets re-rendered again, but I need it to be done only once after first async call and not when state changes later...

1 Answer 1

2

You could use shouldComponentUpdate method and re render only if default data was changed. In your case default data change only once (by default it is empty on the next step has some data), so render method will be called only once.

shouldComponentUpdate(nextProps, nextState) {
  return this.props.defaults.data !== nextProps.this.props.defaults.data;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Cool, I was just browsing React docs and found this method also and now you confirmed it too. Many thanks for the quick reply!
Hmm I ran into another problem now. If I want other things to be rendered except the button.. if shouldComponentUpdate returns false then nothing gets rendered....
You can add more options for return true in shouldComponentUpdate, but then re render will be called more than once. I think best solution here keep this button into separate component and pass callback via props.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.