'dispatch' 不是 Redux 中 mapToDispatchToProps() 参数时的函数
'dispatch' is not a function when argument to mapToDispatchToProps() in Redux
我是 javascript/redux/react 初学者,使用 redux、react-redux 和 react 构建小型应用程序。出于某种原因,当我将 mapDispatchToProps 函数与 connect(react-redux 绑定)结合使用时,我收到一个 TypeError,表明当我尝试执行生成的 prop 时,dispatch 不是一个函数。但是,当我将 dispatch 作为 prop 调用时(请参阅提供的代码中的 setAddr 函数)它可以工作。
我很好奇为什么会这样,在 redux 文档的示例 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
干杯。
您只是缺少 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)
我需要一个使用 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);
如果您想在没有 mapStateToProps
的情况下使用 mapDispatchToProps
,只需使用 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)
然后您将自动获得对组件 props 的调度,因此您可以:
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
的 return 已合并到组件的 props 中。但这不是应该注入 mapDispatch
的方式。
您可以使用 mapDispatch
而无需定义 mapState
。传入 null
代替 mapState
,您的组件将不会受到存储更改的影响。
连接组件默认接收dispatch
,当没有提供mapDispatch
时
此外,您的组件收到 dispatch
,因为它在 mapDispatch
的第二个位置收到 null
。如果你正确地传入 mapDispatch
,你的组件将不会收到 dispatch
.
常见做法
以上回答了为什么组件会这样。虽然,通常的做法是使用 mapStateToProps
的对象 shorthand 简单地传入动作创建者。并在组件的 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);
这个问题涵盖了一些人可能会遇到的陷阱,但没有在答案中解决,因为它在代码结构中略有不同,但 returns 完全相同的错误。
使用 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 检查下面的例子。
export default connect(mapStateToProps, mapDispatchToProps)(Index);
`
如果我们不想从 redux 中检索状态,那么我们设置 null 而不是 mapStateToProps。
export default connect(null, mapDispatchToProps)(Index);
我在写 :
时遇到了这个问题
导出默认连接 (mapDispatchToProps,mapStateToProps)(SearchInsectsComponent);
代替
导出默认连接 (mapStateToProps,mapDispatchToProps)(SearchInsectsComponent);
你在最后一句话中漏掉了。由于我们没有 mapStateToProps,所以声明如下
const StartContainer = connect(null, mapDispatchToProps)(Start)
我是 javascript/redux/react 初学者,使用 redux、react-redux 和 react 构建小型应用程序。出于某种原因,当我将 mapDispatchToProps 函数与 connect(react-redux 绑定)结合使用时,我收到一个 TypeError,表明当我尝试执行生成的 prop 时,dispatch 不是一个函数。但是,当我将 dispatch 作为 prop 调用时(请参阅提供的代码中的 setAddr 函数)它可以工作。
我很好奇为什么会这样,在 redux 文档的示例 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
干杯。
您只是缺少 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)
我需要一个使用 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);
如果您想在没有 mapStateToProps
的情况下使用 mapDispatchToProps
,只需使用 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)
然后您将自动获得对组件 props 的调度,因此您可以:
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
的 return 已合并到组件的 props 中。但这不是应该注入 mapDispatch
的方式。
您可以使用 mapDispatch
而无需定义 mapState
。传入 null
代替 mapState
,您的组件将不会受到存储更改的影响。
连接组件默认接收dispatch
,当没有提供mapDispatch
时
此外,您的组件收到 dispatch
,因为它在 mapDispatch
的第二个位置收到 null
。如果你正确地传入 mapDispatch
,你的组件将不会收到 dispatch
.
常见做法
以上回答了为什么组件会这样。虽然,通常的做法是使用 mapStateToProps
的对象 shorthand 简单地传入动作创建者。并在组件的 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);
这个问题涵盖了一些人可能会遇到的陷阱,但没有在答案中解决,因为它在代码结构中略有不同,但 returns 完全相同的错误。
使用 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 检查下面的例子。
export default connect(mapStateToProps, mapDispatchToProps)(Index);
`
如果我们不想从 redux 中检索状态,那么我们设置 null 而不是 mapStateToProps。
export default connect(null, mapDispatchToProps)(Index);
我在写 :
时遇到了这个问题
导出默认连接 (mapDispatchToProps,mapStateToProps)(SearchInsectsComponent);
代替
导出默认连接 (mapStateToProps,mapDispatchToProps)(SearchInsectsComponent);
你在最后一句话中漏掉了。由于我们没有 mapStateToProps,所以声明如下
const StartContainer = connect(null, mapDispatchToProps)(Start)