Reputation: 17384
I have a situation when it would be really convenient to have a promise object as a part of the state. In short - there is a state which contains all the info which user gave in the question-answer mode and after some answer it would be nice to send a call, result of which will be needed after several more questions:
Q1 -> Q2 -> Q3 - -> Q4 - - -> Q5 -> Q6 -> Q7
\ - - Call to API - - /
Before Q7 I need to check result of call after Q3. It would be really easy to do with promise as a part of the state and then just subscribe to result. But I have inner feeling that it should not happen. Is it ok to do it this way?
I don't think that my code will help to understand, so feel free to just ask questions if it's not clear.
Upvotes: 0
Views: 258
Reputation: 2925
You should not do that because serializing your state would not be possible anymore. How much of a problem that is, not sure, it might only break the devtools or some persistence/hydration library you are using or will use. But to stay true to redux and its simplicity, reduce your scenario to a single truth:
Based on that you send the request:
if (currentQuestion > 3 && currentQuestion < 7 && !isDataRequested) {
dispatch(callToApi()); // this sets isDataRequested to true.
}
This will work with persisting and hydrating the state.
Upvotes: 1
Reputation: 957
You can use redux-promise middleware, Your actions will return you promise if that action is completed, in-flight or failed. So you can easily manage questions and make call exactly at the right time you needed based on the promise. I have a sample example in my github account which shall explain how to use it. Let know if you find it useful.
Below is suedo code
Action controller
export const action_CALL = () => {
return {
type: SOME_CALL,
payload: new Promise((resolve, reject) => {
let wait = setTimeout(() => {
resolve('DUMMY ... Few questions answered in x mins');
}, 2000)
}),
};
};
Reducer
export const countReducer = typeToReducer({
[SOME_CALL]: {
PENDING: (state, action) => ({
...state,
answered: false,
}),
REJECTED: (state) => ({
...state,
answered: false,
}),
FULFILLED: (state, action) => ({
answered: true,
callResponse: action.payload,
})
}
}, initState);
This approach will give you fine-grained control.
Upvotes: 1