【问题标题】:redux Store does not have a valid reducer coffeescriptredux Store 没有有效的 reducer coffeescript
【发布时间】:2016-07-26 02:32:10
【问题描述】:

第一次使用 Redux,我了解 Actions 和 Reducers 的概念,但无法让它们在我的代码中很好地发挥作用,我担心这是因为我使用的是 CoffeeScript 而不是 ES6。

认为问题是我不能在我的 /app/reducers/index.coffee 中使用export default ...,但老实说 Redux 对我来说很新,而且我一直在与 webpack 一起磕磕绊绊,反应了一段时间,但仍然不是最舒服的,所以¯\_(ツ)_/¯

我不断收到错误:

Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers.

/app/actions/index.coffee

{ FETCH_ITEMS, FETCH_SINGLE_ITEM } = require('../constants')

fetch_items = ->
  { type: FETCH_ITEMS }


fetch_single_item = (id) ->
  {
    type: FETCH_SINGLE_ITEM,
    id: id
  }

module.exports = { fetch_items, fetch_single_item }

/app/reducers/items.coffee

$ = require('jquery')
{ FETCH_ITEMS, FETCH_SINGLE_ITEM } = require('../constants')
{ fetch_items } = require('../actions')

INITIAL_STATE = []

items = (state=INITIAL_STATE, action) ->
  console.log action.type
  switch action.type
    when FETCH_ITEMS
      console.log 'FETCH_ITEMS'
      $.get "http://dosomething.com/items", (resp) ->
        console.log resp
    when FETCH_SINGLE_ITEM
      console.log 'do something'
    else
      console.log "suckit turk!"
  state

module.exports = { items }

/app/reducers/index.coffee

{ combineReducers } = require('redux')
items = require('./items')

reducers = combineReducers({ items })

module.exports = { reducers }

最后是 /app/index.cjsx

React        = require("react")
ReactDOM     = require("react-dom")
{
  createStore,
  combineReducers,
  appyMiddleware
} = require('redux')

{ reducers } = require("./reducers/")

STORE = createStore combineReducers({ reducers, routing: routerReducer     })
HISTORY = syncHistoryWithStore(browserHistory, STORE)

STORE.subscribe () ->
  console.log STORE.getState()

...omitted react render: ->...

编辑

对不起大家,是的 routeReducer 已定义,我只是省略了它,因为我很确定这不是问题。

/app/index.cjsx

React        = require("react")
ReactDOM     = require("react-dom")
{
  createStore,
  combineReducers,
  appyMiddleware
} = require('redux')

{
  syncHistoryWithStore,
  routerReducer
} = require('react-router-redux')


{ reducers } = require("./reducers/")

STORE = createStore combineReducers({ reducers, routing: routerReducer     })
HISTORY = syncHistoryWithStore(browserHistory, STORE)

STORE.subscribe () ->
  console.log STORE.getState()

...omitted react render: ->...

【问题讨论】:

  • index.coffeeindex.cjsx 中是否抛出此错误?另外,index.cjsx 中的 routerReducer 定义在哪里?
  • CoffeeScript 从来都不是一个好主意,现在是一个更糟糕的主意:/
  • 感谢 @mash 没有任何帮助

标签: javascript coffeescript ecmascript-6 redux


【解决方案1】:

reducer 必须:

  1. 接收状态和动作作为参数
  2. 始终返回相同或新的状态。

您的“reducer”items 仅在switch 语句中的任何情况都不匹配的情况下才会返回一个状态,这意味着它不是有效的 reducer。如果您在发出其中一个操作时遇到此错误,redux 可能会检测到尚未返回新状态。看看在将items 设置为适当的reducer 后是否仍然遇到此问题。

旁注

您正在从您的 items reducer 进行异步 API 调用,并且您的存根代码看起来像您计划添加第二个。这不是减速器的正确使用; store 应该保存与应用程序状态相关的数据,reducer 应该在给定旧状态和操作类型和/或有效负载的情况下制造新状态。

相反,在“动作创建器”中调用这些类型的异步函数。 (See docs.)

fetch_items 这样的动作创建者将执行 AJAX 请求,并在成功时触发 set_items 动作的调度,例如{ type: 'SET_ITEMS', payload: [...response.items...] }。您的 reducer 将侦听 SET_ITEMS 操作并返回一个新状态,并使用有效负载进行更新。

【讨论】:

  • 感谢您的回复 this-vidor 我编辑了上面的帖子,我需要 routeReducersyncHistoryWithStore 并且错误发生在 index.cjsx 中。当我注销reducers 时,我得到function combination() { ... }
  • @Sparkmasterflex 已更新。
  • 再次感谢@this-vidor,就是这样,感谢您的额外帮助。
  • @Sparkmasterflex 很高兴这能让你跑步! documentation 列出了一些编写 reducer 的最佳实践:纯函数,没有副作用。给定相同的输入,它们应该始终返回相同的输出。尽量减少 reducer 本身的计算——它是动作(以精确的方式表达改变状态的意图)和状态本身之间的一个分类层。
猜你喜欢
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
  • 2018-04-27
  • 2019-09-05
  • 1970-01-01
  • 2019-06-20
相关资源
最近更新 更多