首页 文章

'dispatch'在Redux中mapToDispatchToProps()的参数时不是函数

提问于
浏览
65

我是一个javascript / redux / react初学者,用redux,react-redux和react做一个小应用程序 . 出于某种原因,当使用mapDispatchToProps函数与connect(react-redux绑定)串联时,我收到一个TypeError,指示当我尝试执行生成的prop时,dispatch不是函数 . 当我将调度调用为prop时(参见提供的代码中的setAddr函数),它可以工作 .

我很好奇为什么会这样,在redux文档中的示例TODO应用程序中,mapDispatchToProps方法的设置方式相同 . 当我在函数内部调度console.log(dispatch)时,它表示dispatch是type对象 . 我可以继续以这种方式使用调度,但在我继续使用redux之前,我会更好地了解为什么会发生这种情况 . 我正在使用带有babel-loaders的webpack进行编译 .

我的代码:

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

干杯 .

8 回答

  • 3

    我通过交换参数来解决它,我正在使用

    export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)
    

    这是错的 . mapStateToProps 必须是第一个参数:

    export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)
    

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

  • 12

    您只是缺少 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)
    
  • 99

    我正在使用这样..它易于理解的第一个参数是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);
    
  • 0

    使用

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

    代替

    const StartContainer = connect(mapDispatchToProps)(Start)
    
  • 1

    问题

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

    The Arity of connect Matters: connect(mapStateToProps, mapDispatchToProps)

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

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

    您可以在不定义 mapState 的情况下使用 mapDispatch . 传入 null 代替 mapState ,您的组件将不受商店更改的影响 .

    Connected Component Receives dispatch by Default, When No mapDispatch Is Provided

    此外,您的组件收到 dispatch ,因为它收到 null 作为 mapDispatch 的第二个位置 . 如果您正确传入 mapDispatch ,您的组件将不会收到 dispatch .

    普通实践

    以上解释了组件为何如此表现的原因 . 虽然,通常的做法是你只需使用 mapStateToProps 's object shorthand. And call that within your component' s onSubmit 传递你的动作创建者即:

    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)
    
  • 3

    如果你想在没有 mapStateToProps 的情况下使用 mapDispatchToProps ,只需使用 null 作为第一个参数 .

    export default connect(null, mapDispatchToProps)(Start)

  • 89

    当你不提供 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

    我需要一个使用 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);
    

相关问题