小编典典

redux / react应用程序中的状态具有一个带有减速器名称的属性

reactjs

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

根减速器使用combineReducers方法创建

const rootReducer = combineReducers({
  appReducer
});

初始状态为

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

但是在组件函数中mapStateToProps

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

state.sourcesundefined因为值state参数

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

这是redux的功能吗?因此,当我使用更多的reducer时,它们都会为state变量添加新属性吗?还是我这边有问题(在redux教程中我从未注意到这种行为)。

谢谢


阅读 263

收藏
2020-07-22

共1个答案

小编典典

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

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
  }
}

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

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

并将一个组件连接到它:

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

但是,减速器很难阅读,因为它可以一次更新许多不同的内容。现在, 是您要将其拆分为几个独立的reducer的时刻:

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),
  }
}

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

最后,作为最后一步,我们可以使用combineReducers()生成根app缩减器,而不用手工编写它:

// 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()代替手动编写根减少器没有什么大的好处,除了它效率更高一点,而且可以节省一些错别字。另外,您可以在您的应用程序中多次应用此模式:以嵌套的方式将不相关的化合器多次组合成一个化合器是很好的。

所有这些重构将不会对组件产生影响。

我建议您观看Redux上免费的Egghead课程,其中涵盖了 减速器组成的 这种模式并演示了如何combineReducers()实现。

2020-07-22