redux / react app中的状态具有属性为reducer的属性 [英] State in redux/react app has a property with the name of the reducer

查看:79
本文介绍了redux / react app中的状态具有属性为reducer的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Redux和React创建一个应用程序。我遇到了一个问题,我无法将状态映射到组件属性,因为状态有一个与我使用的reducer名称相匹配的属性。

I am creating an app using Redux and React. I run into a problem where I cannot map state to component properties since the state has a property that matches the name of the reducer I used.

根减少器是用 combineReducers method

The root reducer is created with combineReducers method

const rootReducer = combineReducers({
  appReducer
});

初始状态是

const initialState = {
  sources: [], 
  left: {}, 
  right: {},
  diff: {} 
}

但是在组件函数 mapStateToProps 中:

function mapStateToProps(state) {
  return {
    sources: state.sources
  }
}

state.sources 未定义因为参数的值是

{
  appReducer: {
    sources: [], 
    left: {}, 
    right: {}, 
    diff: {}
  }
}

这是redux的功能吗?所以当我使用更多reducers时,所有这些都将为 state 变量添加新属性?或者我的方面有什么问题(在redux教程中我从未注意到这种行为)。

Is this a feature of redux? So when I use more reducers, all of them will add new property to state variable? Or is there something wrong on my side (I never noticed this behavior in redux tutorials).

谢谢

推荐答案

如果您只有一个reducer,则不需要 combineReducers()。只需直接使用它:

If you only have a single reducer, you don’t need combineReducers(). Just use it directly:

const initialState = {
  sources: [],
  left: {},
  right: {}
}
function app(state = initialState, action) {
  switch (action.type) {
  case 'ADD_SOURCE':
    return Object.assign({}, state, {
      sources: [...state.sources, action.newSource]
    })
  case 'ADD_SOURCE_TO_LEFT':
    return Object.assign({}, state, {
      left: Object.assign({}, state.left, {
        [action.sourceId]: true
      })
    })
  case 'ADD_SOURCE_TO_RIGHT':
    return Object.assign({}, state, {
      right: Object.assign({}, state.right, {
        [action.sourceId]: true
      })
    })
  default:
    return state
  }
}

现在您可以使用该减速器创建商店:

Now you can create a store with that reducer:

import { createStore } from 'redux'
const store = createStore(app)

并将组件连接到它:

const mapStateToProps = (state) => ({
  sources: state.sources
})

然而你的减速机是难以阅读,因为它一次更新许多不同的东西。现在,这个是您想要将其拆分为多个独立缩减器的时刻:

However your reducer is hard to read because it update many different things at once. Now, this is the moment you want to split it into several independent reducers:

function sources(state = [], action) {
  switch (action.type) {
  case 'ADD_SOURCE':
    return [...state.sources, action.newSource]
  default:
    return state
  }
}

function left(state = {}, action) {
  switch (action.type) {
  case 'ADD_SOURCE_TO_LEFT':
    return Object.assign({}, state, {
      [action.sourceId]: true
    })
  default:
    return state
  }    
}

function right(state = {}, action) {
  switch (action.type) {
  case 'ADD_SOURCE_TO_RIGHT':
    return Object.assign({}, state, {
      [action.sourceId]: true
    })
  default:
    return state
  }    
}

function app(state = {}, action) {
  return {
    sources: sources(state.sources, action),
    left: left(state.left, action),
    right: right(state.right, action),
  }
}

这更容易维护和理解,也可以更容易地独立更改和测试减速器。

This is easier to maintain and understand, and it also makes it easier to change and test reducers independently.

最后,作为最后一步,我们可以使用 combineReducers()来生成root app reducer,而不是手工编写:

Finally, as the last step, we can use combineReducers() to generate the root app reducer instead of writing it by hand:

// function app(state = {}, action) {
//   return {
//     sources: sources(state.sources, action),
//     left: left(state.left, action),
//     right: right(state.right, action),
//   }
// }

import { combineReducers } from 'redux'
const app = combineReducers({
  sources,
  left,
  right
})

使用 combineReducers()没有大的好处而不是手动编写根减速器,除了它稍微有点效率,可能会省去一些拼写错误。此外,您可以在应用程序中多次应用此模式:将不相关的Reducer以嵌套方式多次组合到单个reducer中可以。

There is no large benefit to using combineReducers() instead of writing the root reducer by hand except that it’s slightly more efficient and will likely save you a few typos. Also, you can apply this pattern more than once in your app: it’s fine to combine unrelated reducers into a single reducer several times in a nested way.

所有这些重构都会对组件没有影响。

All this refactoring would have no effect on the components.

我建议你观看我的 Redux上的免费Egghead课程,涵盖了 reducer composition 的这种模式,并展示了如何实现 combineReducers()

I would suggest you to watch my free Egghead course on Redux which covers this pattern of reducer composition and shows how combineReducers() is implemented.

这篇关于redux / react app中的状态具有属性为reducer的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆