【问题标题】:Redux combineReducers not passing state to reducerRedux combineReducers 没有将状态传递给 reducer
【发布时间】:2017-02-16 06:22:22
【问题描述】:

在下面的代码中,数据(state, action) 没有通过combineReducers 传递给reducers。它会生成以下错误。可能只是我犯的一个小错误。链接到 JSFiddle:https://jsfiddle.net/bengrunfeld/1h0t59uf/

import React from 'react'
import { render } from 'react-dom'
import { combineReducers } from 'redux'
import { Constants } from './constants/constants'


const goal = (state = 0, action) => {
  (action.type === Constants.ADD) ?
    state + action.payload:
    state
}

const target = (state = 0, action) => {
  (action.type === Constants.REMOVE)?
    state - action.payload:
    state
}

const reducer = combineReducers({
  goal,
  target
})

const state = 10

const newState = reducer(state, {
  type: Constants.REMOVE,
  payload: 5
})

render(
  <div>
    <p>{newState}</p>
  </div>,
  document.getElementById('main')
)

错误信息

main.bundle.js:28054 Uncaught Error: Reducer "goal" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined.
    at http://localhost:3000/main.bundle.js:28054:13
    at Array.forEach (native)
    at assertReducerSanity (http://localhost:3000/main.bundle.js:28049:25)
    at combineReducers (http://localhost:3000/main.bundle.js:28104:5)
    at Object.<anonymous> (http://localhost:3000/main.bundle.js:13236:42)
    at __webpack_require__ (http://localhost:3000/main.bundle.js:20:30)
    at Object.<anonymous> (http://localhost:3000/main.bundle.js:31673:18)
    at __webpack_require__ (http://localhost:3000/main.bundle.js:20:30)
    at module.exports (http://localhost:3000/main.bundle.js:66:18)
    at http://localhost:3000/main.bundle.js:69:10

【问题讨论】:

    标签: javascript ecmascript-6 redux react-redux


    【解决方案1】:

    const Constants = {
      REMOVE: "REMOVE",
      ADD: "ADD"
    }
    
    const goal = (state = 5, action) => {
      return (action.type === Constants.ADD) ?
        state + action.payload:
        state
    }
    
    const target = (state = 5, action) => {
      return (action.type === Constants.REMOVE)?
        state - action.payload:
        state
    }
    
    const reducer = Redux.combineReducers({
      goal,
      target
    })
    
    const state = {goal: 10, target:5}
    
    const newState = reducer(state, {
      type: Constants.REMOVE,
      payload: 5
    })
    
    console.log(newState);
    
    ReactDOM.render(
      <div>
        <p>{newState.goal}</p>
        <p>{newState.target}</p>
      </div>,
      document.getElementById('main')
    )
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.min.js"></script>
    
    
    <div id="main"></div>
    1. 您需要为每个 reducer 定义一个初始状态。
    2. 您还应该从减速器返回一个状态。

    【讨论】:

    • 您的答案有效,但收到以下警告:The previous state received by the reducer has unexpected type of "Number". Expected argument to be an object with the following keys: "goal", "target" warning @ redux.js:376
    • 你已经将你的状态初始化为state = 10,而它应该是这样的对象 {goal: 10, target: 10} .goal reducer 将仅传递 state.goal 作为状态,target reducer 将仅传递stat.target 作为状态。
    【解决方案2】:

    你需要让 Redux 知道初始状态会是什么。

    无论是在减速器本身(注意 es6 默认参数)

    编辑:我刚刚注意到你没有返回任何东西

    const goal = (state = 0, action) => {
      return (action.type === Constants.ADD) ?
        state + action.payload:
        state
    }
    
    const target = (state = 0, action) => {
      return (action.type === Constants.REMOVE)?
        state - action.payload:
        state
    }
    

    或者在CreateStore的第二个参数中

    以下是一些全面的文档: http://redux.js.org/docs/recipes/reducers/InitializingState.html

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2019-04-01
    • 2017-08-12
    • 2020-10-29
    • 2017-10-18
    相关资源
    最近更新 更多