简体   繁体   中英

How to handle repetitive action creator boilerplate in Redux

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, ie

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.

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");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM