admin 管理员组

文章数量: 1086019

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?

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?

Share Improve this question edited Jan 31, 2017 at 19:30 Ben Lime asked Jan 31, 2017 at 19:03 Ben LimeBen Lime 4936 silver badges17 bronze badges 4
  • You can't use .then(() => Actions.editor if createStory() doesn't return a promise, If you don't want to use promise, you can use callbacks, but promise is better in this case. – Dhruv Kumar Jha Commented Jan 31, 2017 at 19:22
  • And when you return a promise, .then will be only called after its resolved. use .catch if you want to do something else in case of error. – Dhruv Kumar Jha Commented Jan 31, 2017 at 19:23
  • Well yes. But the thing is that it feels odd to use a promise here at all. Assume I don't use a promise and have the action creator just return the action. If I call createStory() then call the transition Action.editor({ // ... }) the application will transition to the second last story, as the state has not been updated. – Ben Lime Commented Jan 31, 2017 at 19:30
  • Exactly, so you wait for state to update and then you transition., So it will have the latest id, Anyways you can just as easily if possible get/set the id in ` addStory()` and then use that id to make the transition, you can also use setTimeout - i wouldn't remend it, Anyways using Promise is good because if later you want to save the data in database before updating your state you can do so and not change the code for transition, but if that's not the case, then you can use callbacks – Dhruv Kumar Jha Commented Jan 31, 2017 at 19:39
Add a ment  | 

1 Answer 1

Reset to default 6

As discussed in ments

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 plete.. it doesn't matter. you do everything you have to do here and finally resolve it so the app/ponent 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/

本文标签: javascriptWait for action to update state in reactnative and reduxStack Overflow