Reputation: 73
I have little problem with redirecting back to previous page - it happens too soon.
Basically I have functional component like that:
export const CreateRecordingControls = ({ recording, handleCreateRecording }) => {
const history = useHistory();
const handleCreate = async () => {
const promise = Promise.resolve(handleCreateRecording(recording));
await Promise.all([promise]).then(function () {
history.push('/home');
});
}
return (
<Fragment>
<button onClick={() => handleCreate()}>Create</button>
</Fragment>
);
}
const mapDispatchToProps = dispatch => ({
handleCreateRecording: recording => {
dispatch(handleCreateRecording(recording));
}
});
const CreateRecordingControlsView = withRouter(connect(null, mapDispatchToProps)(CreateRecordingControls));
export default CreateRecordingControlsView;
When user clicks "Create" it will call createRecording action:
export const handleCreateRecording = (recording) => {
return dispatch => {
dispatch(handleCreateRecordingBegin());
fetch(`${config.get('api')}/api/recordings/create`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(recording, replacer)
}).then(data => {
dispatch(handleCreateRecordingSuccess(data));
}).catch(error =>
dispatch(handleCreateRecordingFailure(error))
);
}
}
Which goes to reducer:
export default (state = [], action) => {
switch (action.type) {
case 'CREATE_RECORDING_BEGIN':
return {
...state,
loading: true,
error: null,
finished: false
}
case 'CREATE_RECORDING_SUCCESS':
return {
data: action.payload,
loading: false,
finished: true
}
default:
return state;
}
}
But in that case, it still shows that component on '/home' route will mount before handle success is called. Home component contains list of just added recordings. It seems currently it's a race who gets there first. So far newly created recording is in list, but I think this is still wrong behavior.
Any ideas how to wait success case to finish before redirecting?
Upvotes: 1
Views: 423
Reputation: 134
The fetch promise doesn't seem to be returned at the moment, so the Promise.resolve will just happen immediately.
I would try returning the actual promise from the fetch, i.e. awaiting the results of the handleCreateRecording fetch then returning that when you dispatch your action. The promise resolve and promise.all shouldn't be necessary. If you want to catch any fetch errors, then you could just wrap the await in a try/catch block.
Upvotes: 0
Reputation: 2706
The dispatch
function does not return a promise, so you're not waiting for anything. With redux-thunk
if you want to wait for the result of a dispatch, you must do so within your action creator: where you're dispatching your handleCreateRecordingSuccess
.
The alternative is to observe the state value finished
and push to your history when it gets the value that you're interested in.
Upvotes: 1