简体   繁体   中英

Avoiding reducer name collision without breaking redux-logger

According to the official Redux docs , it is recommended to only create one store per app, for various reasons.

In that case, how should I avoid name collision with reducers? For example, consider a react-native app that has two screens:

  1. Inbox
  2. News

You can refresh the data separately on each screen, which should during the promised fetch existence, show it's respective RefreshControl component.

Considering the following boilerplate code,

// createReducer.js
export default function createReducer(initialState, handlers) {
    return function reducer(state = initialState, action) {
        if (handlers.hasOwnProperty(action.type)) {
            return handlers[action.type](state, action)
        } else {
            return state
        }
    }
}

I could solve my refreshing problem, via the traditional way, but increasing the namespace pollution.

export const refreshingInbox = createReducer(false, {
    [types.REQUEST_INBOX](state, action) {
        return true
    },
    [types.UPDATE_INBOX](state, action) {
        return false
    },
})
export const refreshingNews = createReducer(false
    [types.REQUEST_NEWS](state, action) {
        return true
    },
    [types.UPDATE_NEWS](state, action) {
        return false
    },
})

I would like to avoid this, by doing the following:

export const refreshing = createReducer({inbox: false, news: false}, {
    [types.REQUEST_INBOX](state, action) {
        return Object.assign(state, {inbox: true})
    },
    [types.UPDATE_INBOX](state, action) {
        return Object.assign(state, {inbox: false})
    },
    [types.REQUEST_NEWS](state, action) {
        return Object.assign(state, {news: true})
    },
    [types.UPDATE_NEWS](state, action) {
        return Object.assign(state, {news: false})
    },
})

Both solutions get the job done, but my solution breaks the logger. The logger cannot detect any differences. I imagine that his has to do with the fact that I am returning immutable objects.

What should I do then, that doesn't increase namespace pollution (I can't even imagine how bad it can get with a team production on a huge project), but still doesn't break the logger, which is very helpful in development.

Your issue about change detection is because you are indeed returning a immutable object. Redux (actually it's part of React architecture) will point to an address of memory, if you change where it's pointing to it'll detect change, but if you change what's in it then it won't. That's why you should either return {...state, news: false} or Object.assign({}, state, {news: false}) . That first {} is the new object that will make React see it changed. Back to your original problem, personally I'd suggest defining one reducer per feature (and you can use that feature name to prefix/suffix your action types to make sure there's name collision), and combine them with combineReducers. It depends on the application, but I can imagine it easily having more than 10 different features with different states, and eventually with more logic than just a 1 line assignment, so at some point you'll just have a method that's hundreds/thousands of lines long.

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