当参数指向 Redux 中的 mapToDispatchToProps()时,‘  派遣’不是一個函數

我是一个构建一个小型应用程序的 javascript/redux/response 初学者,使用 redux、 response-redux 和 response。由于某种原因,当使用 mapDispatchToProps 函数与 connect (response-redux 绑定)一起使用时,我会收到一个 TypeError,表明当我试图执行结果道具时,分派不是一个函数。但是,当我将调度作为一个道具调用时(请参见提供的代码中的 setAddr 函数) ,它可以工作。

我很好奇为什么会这样,在 redux docs 中的 TODO 应用程序示例中,mapDispatchToProps 方法的设置方式是相同的。当我在函数内部调度时,它说调度是 object 类型。我可以继续使用派遣这种方式,但我会感觉更好,知道为什么会发生这种情况,然后我继续任何进一步的还原。我使用 webpack 和 babel-loader 来编译。

我的准则:

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

干杯。

176564 次浏览

只是遗漏了 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)

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

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

export default connect(null, mapDispatchToProps)(Start)

使用

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

而不是

const StartContainer = connect(mapDispatchToProps)(Start)

我通过交换论点来解决这个问题

export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)

这是错误的。 mapStateToProps必须是第一个论点:

export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)

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

如果没有提供 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

我就是这么用的。.容易理解的第一个参数是 mapStateToProps,第二个参数是 mapDispatchToProps,最后连接到 function/class。

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);

问题

为了理解代码中连接元件(图论)的行为,需要注意以下几点:

connect事务的简洁性: connect(mapStateToProps, mapDispatchToProps)

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

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

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

连接元件(图论)在没有提供 mapDispatch的情况下默认接收 dispatch

此外,您的组件接收 dispatch,因为它接收 null作为 mapDispatch的第二个位置。如果正确地传入 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)

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

错误顺序:

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

正确的顺序:

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

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

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

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

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

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

导出默认连接(null,mapDispatchToProps)(索引) ;

我得到这个问题时,我写道:
导出默认连接 (mapDispatchToProps,mapStateToProps)(SearchInsectsComponent) ; 而不是 Export default connect < strong > (mapStateToProps,mapDispatchToProps)(SearchInsectsComponent) ;

您在最后一个语句中遗漏了。因为我们没有 mapStateToProps,所以这个语句将如下所示

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