ChatGPT解决这个技术问题 Extra ChatGPT

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

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

我很好奇为什么会这样,在 redux 文档中的示例 TODO 应用程序中,mapDispatchToProps 方法的设置方式相同。当我在函数内使用 console.log(dispatch) 时,它说 dispatch 是类型对象。我可以继续以这种方式使用 dispatch,但在我继续使用 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

干杯。

我遇到了这个问题,this 帮我解决了这个问题

i
inostia

如果您想使用没有 mapStateToPropsmapDispatchToProps,只需使用 null 作为第一个参数。

export default connect(null, mapDispatchToProps)(Start)


这就是我一直在寻找的。现在我知道我是否只想调度一些动作。
这正是我一直在寻找的东西。感谢您提供完美的解决方案。如果我们不必在任何组件中使用 mapDispatchToProps 怎么办?我们必须以同样的方式处理这种情况吗?
如果您不需要 mapDispatchToProps,请不要将该参数添加到 connectconnect(mapStateToProps)(MyComponent)
B
Brandon

您只是缺少 connect 的第一个参数,即 mapStateToProps 方法。摘自 Redux 待办事项应用程序:

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)

是否必须使用这种方法?这个方法只是捕捉状态如果我们不需要这个方法怎么办?
@MuneemHabib 请参阅 inostia 的答案,了解如何在不需要时不提供此方法
ρ
ρяσѕρєя K

利用

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

代替

const StartContainer = connect(mapDispatchToProps)(Start)

D
Derek Brown

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

export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)

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

export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)

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


A
Amio.io

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

w
wgao19

问题

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

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

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

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

您可以使用 mapDispatch 而不定义 mapState。传入 null 代替 mapState,您的组件不会受到存储更改的影响。

如果未提供 mapDispatch,则连接的组件默认接收 dispatch

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

常见做法

上面回答了为什么组件会这样。不过,通常的做法是使用 mapStateToProps 的对象简写方式传入您的操作创建者。并在您的组件的 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)

i
imbatman

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

使用 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


S
Sachin Metkari

React-redux 'connect' 函数接受两个参数,第一个是 mapStateToProps,第二个是 mapDispatchToProps 检查下面的例子。

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

如果我们不想从 redux 中检索状态,那么我们设置 null 而不是 mapStateToProps。

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


E
Elikill58

你在最后一个陈述中失踪了。由于我们没有 mapStateToProps,所以语句如下所示

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

S
Sergio Nikolaev

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


A
Abdul Moiz

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

如果您没有第一个参数,则只需传递 null / undefined 然后是第二个参数..
C
Codiee

有时,当您在传递连接时更改组件函数的顺序时也会发生此错误。

错误的顺序:

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

正确的顺序:

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

h
harika

我写的时候遇到了这个问题: export default connect (mapDispatchToProps,mapStateToProps)(SearchInsectsComponent);而不是导出默认连接 (mapStateToProps,mapDispatchToProps)(SearchInsectsComponent);