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 transitionAction.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 usingPromise
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
1 Answer
Reset to default 6As 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/