简体   繁体   中英

Wait for action to update state in react-native and redux

I have a simple react-native application with a redux store set up. Basically I want to add a new story, dispatch the redux action and transition to this new story after it has been created.

I have the following code in my Container Component, which runs when the user taps on an add button.

 addStory() {
    this.props.actions.stories.createStory()
      .then(() => Actions.editor({ storyId: last(this.props.stories).id }); // makes the transition)
  }

And the following action creator.

export const createStory = () => (dispatch) => {
  dispatch({ type: CREATE_STORY, payload: { storyId: uniqueId('new') } });
  return Promise.resolve();
};

As you see, I return a promise in the action creator. If I don't return a promise here, the transition will be made before the state has been updated.

This seems a little odd to me - why do I have to return a resolved Promise here? Aren't dispatches meant to be synchronous?

As discussed in comments

Callbacks Example:

addStory() {
    this.props.actions.stories.createStory( (id) => {
        Actions.editor({ storyId: id })
    });
}
export const createStory = ( callback ) => (dispatch) => {
    const _unique_id = uniqueId('new');
    dispatch({ type: CREATE_STORY, payload: { storyId: _unique_id } });
    callback(_unique_id);
};

Timeout Example: Here we're assuming the state would have updated by now.. that's not the case most of the times.

addStory() {
    this.props.actions.stories.createStory()
    setTimeout( () => {
        Actions.editor({ storyId: last(this.props.stories).id });
    }, 500);
}
export const createStory = () => (dispatch) => {
    dispatch({ type: CREATE_STORY, payload: { storyId: uniqueId('new') } });
};

Promise: this can take a sec or a minute to complete.. it doesn't matter. you do everything you have to do here and finally resolve it so the app/component can perform next actions.

export const createStory = () => (dispatch) => {
    return new Promise( (resolve, reject) => {
        // make an api call here to save data in server
        // then, if it was successful do this
        dispatch({ type: CREATE_STORY, payload: { storyId: uniqueId('new') } });
        // then do something else
        // do another thing
        // lets do that thing as well
        // and this takes around a minute, you could and should show a loading indicator while all this is going on
        // and finally
        if ( successful ) {
            resolve(); // we're done so call resolve.
        } else {
            reject(); // failed.
        }
    });
};

And now, checkout http://reactivex.io/rxjs/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM