Reputation: 1191
I have very little experience in creating frontend applications and would like to establish some conventions for myself when using Redux.
Currently my reducers for async actions look like this:
const initialState = {
isRunning: false,
isFinished: false,
hasError: false,
response: null
};
export const updatePostReducer = (state = initialState, action=null) => {
switch (action.type) {
case UPDATE_POST:
return {
isRunning: true,
isFinished: false,
hasError: false,
response: null
};
break;
case UPDATE_POST_SUCCESS:
return {
isRunning: false,
isFinished: true,
hasError: false,
response: action.payload
};
break;
case UPDATE_POST_ERROR:
return {
isRunning: false,
isFinished: false,
hasError: true,
response: null,
statusCode: action.statusCode
};
case UPDATE_POST_INVALIDATE:
return initialState;
break;
default:
return state;
}
};
There is no problem with the approach above, but I find the the "process stages" confusing. Therefor my idea is to shorten it to:
// IMPORTED FROM SEPARATE FILE
const stage = {
INITIAL: "INITIAL",
RUNNING: "RUNNING",
FINISHED: "FINISHED",
ERROR: "ERROR"
};
const initialState = {
stage: stage.INITIAL,
response: null
};
export const updatePostReducer = (state = initialState, action=null) => {
switch (action.type) {
case UPDATE_POST:
return {
stage: stage.RUNNING,
response: null
};
case UPDATE_POST_SUCCESS:
return {
stage: stage.FINISHED,
response: action.payload
};
case UPDATE_POST_ERROR:
return {
stage: stage.ERROR,
response: null,
statusCode: action.statusCode
};
case UPDATE_POST_INVALIDATE:
return initialState;
default:
return state;
}
};
I see 2 advantages using the latter approach:
The disadvantages are:
My question is: Since there is no fine-grained control of the stages, will this cause problems in some scenarios? For example, could there be occasions where it is needed to have hasError=true, isRunning=true
at the same time?
Upvotes: 1
Views: 36
Reputation: 29739
The question you pose is difficult to answer without knowing the use cases of your application. But if it's not a very simple one, i'd state that you could run into problems sooner or later with that kind of simplification.
I also see some problems with non-initialized values like statusCode
. Which is not updated for the other states by the way. If the code is updated when an error occurs, it's still the same after a successful retry.
I would propose another way, being even more explicit with combineReducers()
.
Here is how:
const isRunningReducer = (state=false, action=null) => {
switch (action.type) {
case UPDATE_POST:
return true;
case UPDATE_POST_SUCCESS:
return false;
case UPDATE_POST_ERROR:
return false;
case UPDATE_POST_INVALIDATE:
return false;
default:
return state;
}
};
const isFinishedReducer = (state=false, action=null) => {
switch (action.type) {
case UPDATE_POST:
return false;
case UPDATE_POST_SUCCESS:
return true;
case UPDATE_POST_ERROR:
return false;
case UPDATE_POST_INVALIDATE:
return false;
default:
return state;
}
};
const hasErrorReducer = (state=false, action=null) => {
switch (action.type) {
case UPDATE_POST:
return false;
case UPDATE_POST_SUCCESS:
return false;
case UPDATE_POST_ERROR:
return true;
case UPDATE_POST_INVALIDATE:
return false;
default:
return state;
}
};
const statusCodeReducer = (state=null, action=null) => {
switch (action.type) {
case UPDATE_POST:
return null;
case UPDATE_POST_SUCCESS:
return action.statusCode;
case UPDATE_POST_ERROR:
return action.statusCode;
case UPDATE_POST_INVALIDATE:
return null;
default:
return state;
}
};
const responseReducer = (state=null, action=null) => {
switch (action.type) {
case UPDATE_POST:
return null;
case UPDATE_POST_SUCCESS:
return action.payload;
case UPDATE_POST_ERROR:
return null;
case UPDATE_POST_INVALIDATE:
return null;
default:
return state;
}
};
export const updatePostReducer = combineReducers({
isRunningReducer,
isFinishedReducer,
hasErrorReducer,
statusCodeReducer,
responseReducer,
});
Disadvantages:
Advantages:
All of this can be made even more elegant with an own createReducer()
method as described here: Reducing Boilerplate - Generating Reducers
Upvotes: 1