Reputation: 736
I've been learning React/Redux for the past couple of months and I find that my code is getting very repetitive. The application that I'm currently working on has a bunch pages - each of which modifies a different section of state in the Redux store. Therefore I have a reducer file, action creator file and container for each page. But I find that simple actions - such as toggling the visibility of a component become very repetitive as I have to replicate the action creator for each separate page, i.e.
An action creator for one page might look like:
export const updateMapVisibility = (component, visibility) => {
return {
'type': 'UPDATE_MAP_VISIBILITY',
'component': component,
'visibility': visibility
}
}
while a seperate one looks like:
export const updatePubVisibility = (component, visibility) => {
return {
'type': 'UPDATE_PUB_VISIBILITY',
'component': component,
'visibility': visibility
}
}
and then this action creator gets replicated across a bunch of pages that require toggleable components. One possible solution to this replication that I've considered is just to make a base action creators containing something like:
export const updateVisibility = (type, component, visibility) => {
return {
'type': type,
'component': component,
'visibility': visibility
}
}
and then in my container pass in the type string as follows:
const mapDispatchToProps = (dispatch) => {
return {
'updateVisibility': (component, visibility) => {
dispatch(updateVisibility('UPDATE_PUB_VISIBILITY', component, field))
}
}
}
But then looking at that I started to ask myself if I'm defeating the purpose of using action creators in the first place. I was wondering if there's a common practice or library for dealing with this type of situation in Redux.
Upvotes: 1
Views: 320
Reputation: 35797
Rather than pushing the part with the type name into your component - which as you say, feels like defeating the purpose somewhat - you could create a function which returns action creator functions (insert Inception trailer noise here):
const visibilityAction = type => (component, visibility) => ({
'type': type,
'component': component,
'visibility': visibility
});
export const updateMapVisibility = visibilityAction("UPDATE_MAP_VISIBILITY");
export const updatePubVisibility = visibilityAction("UPDATE_PUB_VISIBILITY");
A similar (but even more general) example is demonstrated in the Redux docs, under 'Generating Action Creators'. In general though, Redux doesn't make a lot of these decisions for you, leaving you to find the abstractions that work best for your specific use case.
EDIT: For maximum terseness, you could also make use of ES6 shorthand property names:
const visibilityAction = type => (component, visibility) => ({ type, component, visibility });
export const updateMapVisibility = visibilityAction("UPDATE_MAP_VISIBILITY");
export const updatePubVisibility = visibilityAction("UPDATE_PUB_VISIBILITY");
Upvotes: 4