我是一个 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
干杯。
如果您想使用没有 mapStateToProps
的 mapDispatchToProps
,只需使用 null
作为第一个参数。
export default connect(null, mapDispatchToProps)(Start)
您只是缺少 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)
利用
const StartContainer = connect(null, mapDispatchToProps)(Start)
代替
const StartContainer = connect(mapDispatchToProps)(Start)
我通过交换参数来解决它,我正在使用
export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)
这是错误的。 mapStateToProps
必须是第一个参数:
export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)
现在听起来很明显,但可能会对某人有所帮助。
我需要一个使用 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);
问题
为了理解连接组件在代码中的行为,需要注意以下几点:
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)
这个问题涵盖了一些人可能会陷入的陷阱,但没有在答案中解决,因为它在代码结构中略有不同,但返回完全相同的错误。
使用 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);
你在最后一个陈述中失踪了。由于我们没有 mapStateToProps,所以语句如下所示
const StartContainer = connect(null, mapDispatchToProps)(Start)
当您不提供 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,最后与函数/类连接。
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);
有时,当您在传递连接时更改组件函数的顺序时也会发生此错误。
错误的顺序:
export default connect(mapDispatchToProps, mapStateToProps)(TodoList);
正确的顺序:
export default connect(mapStateToProps,mapDispatchToProps)(TodoList);
我写的时候遇到了这个问题: export default connect (mapDispatchToProps,mapStateToProps)(SearchInsectsComponent);而不是导出默认连接 (mapStateToProps,mapDispatchToProps)(SearchInsectsComponent);
不定期副业成功案例分享
mapDispatchToProps
,请不要将该参数添加到connect
:connect(mapStateToProps)(MyComponent)