最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin4浏览0评论

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/

发布评论

评论列表(0)

  1. 暂无评论