redux Actions 必须是普通对象,但我定义了普通对象

Posted

技术标签:

【中文标题】redux Actions 必须是普通对象,但我定义了普通对象【英文标题】:redux Actions must be plain objects but I defined plain object 【发布时间】:2017-06-06 10:19:11 【问题描述】:

我使用 redux + react 来搭建我的网站,我想用 redux 来控制一个侧边栏可见。侧边栏是由语义-ui-react 定义的。因为我想跨另一个组件控制它,所以我在侧边栏的父组件const visible, dispatch = this.props中定义了props,有一个onClick函数来处理这个。我会展示我的代码。

未捕获的错误:操作必须是普通对象。使用自定义中间件进行异步操作。

这个错误让我困惑了一下午,我不知道为什么!这是我的操作代码:

**action**

export const SIDEBARISVISIBLE = 'sidebarVisible'

export function sidebarVisibleAction() 
  return  type: SIDEBARISVISIBLE 

如您所见,我定义了一个动作创建者返回一个普通对象。

这是我的减速器代码:

**reducer**

import SIDEBARISVISIBLE from '../actions/outside.js'

function sidebarVisible(state = 
  sidebarIsVisible: false
, action) 

    switch (action.type) 
        case SIDEBARISVISIBLE:
            return Object.assign(, state, 
                sidebarIsVisible: !state.sidebarIsVisible
            )
        default:
            return state
    


export default sidebarVisible

还有我的商店代码:

**store**

import  createStore, applyMiddleware, compose  from 'redux'
import thunk from 'redux-thunk'
import sidebarVisible from '../reducers/outside.js'

export default initialState => 
  return createStore(
    sidebarVisible,
    initialState,
    applyMiddleware(thunk)
  )

然后,我的组件代码(部分):

class OutsideView extends Component 

    constructor(props) 
        super(props)
        this.state =  activeItem: '' 
    

    handleItemClick = (e,  name ) => this.setState( activeItem: name )

    render() 
        const  activeItem  = this.state
        const  visible, dispatch  = this.props

        return (
            <div>
                <SidebarNav visible= visible  />

                ......

                   <Menu.Item
                    name='sidebar'
                    active= activeItem === 'sidebar'
                    onClick= (e, name) => 
                                this.setState( activeItem: name )
                                dispatch(sidebarVisibleAction)
                             >
                    <Icon color='red' name='list' />
                </Menu.Item>

OutsideView.PropTypes = 
    visible: PropTypes.bool.isRequired,
    dispatch: PropTypes.func.isRequired


function mapStateToProps(state) 
  return 
    visible: state.sidebarIsVisible,
  


export default connect(
    mapStateToProps
)(OutsideView)

最后,我的路由器:

import configureStore from './store/index.js'
const store = configureStore()

export default class Root extends Component 

    render() 
        return (
            <Provider store= store >
            <Router history= browserHistory >
                <Route path="/" component= OutsideRedux >
                    <Route path='register' component= Register  />
                    <Route path='login' component= Login  />
                    <Route path='blog' component= Blog  />
                    <Route path='about' component= About  />
                    <Route path='home' component= Home  />
                    <Route path='ask' component= Ask  />
                    <Route path='panel' component= Panel  />
                    <Route path='setting' component= Setting  />
                    <Route path='user' component= User  />
                </Route>
            </Router>
            </Provider>
        )
    

所以,我搜索这个错误的答案,他们中的大多数人说,你必须设置 redux-thunk 并使用 ApplyMiddleware 来使用它,最简单的方法。但我定义的操作是 plain object。如果我不使用redux-thunk,我想我也不会遇到这个错误。所以,我很困惑,如何解决这个问题?

感谢大家的帮助

【问题讨论】:

不确定这是否相关,因此我将其写为评论。你为什么使用dispatch?您应该在connect 中使用mapDispatchToProps 并将操作设为this.props.actionName。只要确保您使用的是道具版本而不是导入的版本。犯这个错误太多次了:D 还有一个关于你的代码的一般评论,如果你已经在使用 redux,为什么还要使用组件状态?如果你使用 redux,最好通过 redux 来做所有的状态管理,代码更容易推理,更容易测试。一个额外的好处是这样,你不需要类,你可以使用纯组件。 @MarkoGrešak 是的,我会解释一下你说的。首先,我使用 dispatch,因为我参考了官方 redux Reddit API 代码。其次,我使用的状态是只是为了激活一个项目,这是semantic-ui-react默认实现,所以我不改变它。 除了一些非常基本的例子,我没有在我的代码中使用dispatch,因此我没有看到错误,但是@nobody 找到了答案。但是我的建议仍然有效,因为mapDispatchToProps 将动作扭曲为调度调用,因此您可以将动作用作常规函数并省略dispatch(action(args)) 语法,在我看来,更干净的action(args) 调用。 【参考方案1】:

这里:

dispatch(sidebarVisibleAction)

您将函数 sidebarVisibleAction 传递给 dispach。您应该调用它并传递结果,因此代码如下所示:

dispatch(sidebarVisibleAction())

(现在dispatch 将获取对象,而不是函数)。

【讨论】:

很棒的收获。我在寻找答案时正在看这个,但不知何故错过了它。对于作者(他们提到他们指的是官方 Reddit API 示例),可以在这里看到:redux.js.org/docs/advanced/… 是的,这就是答案!谢谢!但是我更改了代码,发现了一个新错误: (0 , _outside2.default) 不是函数。感谢@MarkoGrešak,我认为您是对的,我将代码更改为使用 mapDispatchToProps 和连接它。我正在尝试解决新错误。 @g1eny0ung 这看起来像是错误使用了import 和/或export。很难说在哪里,因为您似乎没有包含所有代码。如果您自己没有弄清楚,请发布一个新问题。 @MarkoGrešak 是的,你是对的。 reducer 代码的 import 错误,我应该使用 将 SIDEBARISVISIBLE 括起来。非常感谢也感谢@nobody。英语不是我的母语,所以我只知道“谢谢”,这种感谢(这句话用翻译,哈哈?) 完美答案,为像我这样的初学者提供解释:) +1

以上是关于redux Actions 必须是普通对象,但我定义了普通对象的主要内容,如果未能解决你的问题,请参考以下文章

Redux-Thunk Chaining Actions,得到一个“dispatch(...)然后不是函数错误

动作必须是普通对象。 Redux 不工作

Redux 错误操作必须是普通对象。使用自定义中间件进行异步操作

使用 redux thunk 时,操作必须是普通对象

如何解决:错误:操作必须是普通对象。使用自定义中间件进行异步操作

redux-thunk:错误:动作必须是普通对象。使用自定义中间件进行异步操作