Redux中mapToDispatchToProps()的参数时,“ dispatch”不是函数


124

我是一名javascript / redux / react初学者,使用redux,react-redux和react构建一个小型应用程序。出于某种原因,当在连接(反应-redux绑定)的同时使用mapDispatchToProps函数时,我收到一个TypeError,指示我尝试执行生成的prop时,dispatch不是函数。但是,当我将调度作为道具调用时(请参阅提供的代码中的setAddr函数),它可以工作。

我很好奇这是为什么,在redux docs的示例TODO应用程序中,mapDispatchToProps方法是以相同的方式设置的。当我在函数内部进行console.log(dispatch)时,它说dispatch是类型对象。我可以继续以这种方式使用调度,但是在继续使用redux之前,我会更好地知道为什么会这样。我正在将webpack与babel-loaders一起使用进行编译。

我的代码:

import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import { setAddresses } from '../actions.js';
import GeoCode from './geoCode.js';
import FlatButton from 'material-ui/lib/flat-button';

const Start = React.createClass({
    propTypes: {
        onSubmit: PropTypes.func.isRequired
    },

    setAddr: function(){
        this.props.dispatch(
            setAddresses({
                pickup: this.refs.pickup.state.address,
                dropoff: this.refs.dropoff.state.address
            })
        )   

    },

    render: function() {
        return (
            <div>
                <div className="row">
                    <div className="col-xs-6">
                        <GeoCode ref='pickup' />
                    </div>
                    <div className="col-xs-6">
                        <GeoCode ref='dropoff' />
                    </div>
                </div>
                <div className="row">
                    <div className="col-xs-6">
                        <FlatButton 
                            label='Does Not Work'
                            onClick={this.props.onSubmit({
                                pickup: this.refs.pickup.state.address,
                                dropoff: this.refs.dropoff.state.address
                            })} 
                            />
                    </div>
                    <div className="col-xs-6">
                        <FlatButton 
                            label='Works'
                            onClick={this.setAddr} 
                            />
                    </div>
                </div>
            </div>
        );
    }
})

const mapDispatchToProps = (dispatch) => {
    return {
        onSubmit: (data) => {
            dispatch(setAddresses(data))
        }
    }
}

const StartContainer = connect(mapDispatchToProps)(Start)

export default StartContainer

干杯。


我遇到了这个问题,帮助我解决了问题
Alex W

Answers:


248

如果您想mapDispatchToProps不带参数地mapStateToProps使用null第一个参数。

export default connect(null, mapDispatchToProps)(Start)


4
这就是我一直在寻找的东西。现在,我知道是否只想调度一些动作。
皇帝克劳斯

这正是我想要的东西。感谢您的完美解决方案。如果我们不必在任何组件中使用mapDispatchToProps怎么办?我们处理这种情况的方式是否相同?
阿伦·拉马尚德兰

1
如果您不需要mapDispatchToProps,只需将其添加至connectconnect(mapStateToProps)(MyComponent)
inostia,

107

你只是缺少第一个参数connect,这是mapStateToProps方法。Redux todo应用摘录:

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

3
是否必须使用此方法?这个方法只是捕捉状态,如果我们不需要这个方法呢?
Muneem Habib

6
@MuneemHabib看到了inostia的答案,即如果您不需要它,该如何不提供该方法
Brandon

21

const StartContainer = connect(null, mapDispatchToProps)(Start) 

代替

const StartContainer = connect(mapDispatchToProps)(Start)

5

我通过交换参数解决了它

export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)

这是错误的。在mapStateToProps有可能成为第一个参数:

export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)

现在听起来很明显,但可能会对某人有所帮助。


3

我需要使用一个示例,React.Component因此将其发布:

import React from 'react';
import * as Redux from 'react-redux';

class NavigationHeader extends React.Component {

}

const mapStateToProps = function (store) {
    console.log(`mapStateToProps ${store}`);
    return {
        navigation: store.navigation
    };
};

export default Redux.connect(mapStateToProps)(NavigationHeader);

3

问题

为了理解代码中连接的组件的行为,需要注意以下几点:

的元数connect事项:connect(mapStateToProps, mapDispatchToProps)

React-Redux调用connect第一个参数mapStateToProps和第二个参数mapDispatchToProps

因此,尽管您已传入,但是mapDispatchToPropsReact-Redux实际上将其视为mapState因为它是第一个参数。您仍然可以onSubmit在组件中获得注入的函数,因为的返回mapState已合并到组件的props中。但这不是mapDispatch应该注入的方式。

您可以使用mapDispatch而无需定义mapStatenull代替传递,mapState您的组件将不会更改存储。

dispatch默认情况下,未mapDispatch提供连接组件时会接收

另外,您的组件会收到,dispatch因为它收到null了的第二个位置mapDispatch。如果您正确传递mapDispatch,则组件将不会收到dispatch

普通做法

上面的答案解释了组件为什么会这样。不过,通常的做法是,您仅使用mapStateToProps的对象速记来传递动作创建者。并在组件的onSubmitThat中调用它,即:

import { setAddresses } from '../actions.js'

const Start = (props) => {
  // ... omitted
  return <div>
    {/** omitted */}
    <FlatButton 
       label='Does Not Work'
       onClick={this.props.setAddresses({
         pickup: this.refs.pickup.state.address,
         dropoff: this.refs.dropoff.state.address
       })} 
    />
  </div>
};

const mapStateToProps = { setAddresses };
export default connect(null, mapDispatchToProps)(Start)

0

当您不提供mapDispatchToProps第二个参数时,如下所示:

export default connect(mapStateToProps)(Checkbox)

那么您将自动获得对组件的道具的派遣,因此您可以:

class SomeComp extends React.Component {
  constructor(props, context) {
    super(props, context);
  }
  componentDidMount() {
    this.props.dispatch(ACTION GOES HERE);
  }
....

没有任何mapDispatchToProps


0

我正在这样使用..其易于理解的第一个参数是mapStateToProps,第二个参数是mapDispatchToProps最后与函数/类连接。

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

export default connect(mapStateToProps,mapDispatchToProps)(TodoList);

如果你没有第一个参数,然后只是通过空/未定义,然后第二个参数..
阿卜杜勒Moiz

0

有时在传递连接时更改组件功能的顺序时也会发生此错误。

顺序错误:

export default connect(mapDispatchToProps, mapStateToProps)(TodoList);

正确的顺序:

export default connect(mapStateToProps,mapDispatchToProps)(TodoList);

0

这个问题涵盖了一些可能会遇到的陷阱,但是在答案中未解决,因为它的代码结构略有不同,但返回的错误完全相同。

使用bindActionCreators而不通过dispatch函数时发生此错误

错误代码

import someComponent from './someComponent'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'
import { someAction } from '../../../actions/someAction'

const mapStatToProps = (state) => {
    const { someState } = state.someState

    return {
        someState
    }
};

const mapDispatchToProps = (dispatch) => {
    return bindActionCreators({
        someAction
    });
};

export default connect(mapStatToProps, mapDispatchToProps)(someComponent)

固定码

import someComponent from './someComponent'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'
import { someAction } from '../../../actions/someAction'

const mapStatToProps = (state) => {
    const { someState } = state.someState

    return {
        someState
    }
};

const mapDispatchToProps = (dispatch) => {
    return bindActionCreators({
        someAction
    }, dispatch);
};

export default connect(mapStatToProps, mapDispatchToProps)(someComponent)

dispatch错误代码中缺少该功能


0

React-redux'connect'函数接受两个参数,第一个是mapStateToProps,第二个是mapDispatchToProps检查,例如ex。

export default connect(mapStateToProps, mapDispatchToProps)(Index); `

如果我们不想从redux检索状态,则将其设置为null而不是mapStateToProps。

export default connect(null, mapDispatchToProps)(Index);

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.