React-Redux中mapDispatchToProps传Action Creator失效问题
React-Redux connect中mapDispatchToProps函数版失效的原因与解决方法
问题出在你写的mapDispatchToProps函数上——它没有正确绑定Redux的dispatch方法,导致点击按钮时只是生成了Action对象,却没有派发到Store中。
两种写法的核心差异
当你把Action Creator组成的对象直接传给connect的第二个参数时,React-Redux会自动调用Redux内置的bindActionCreators工具函数,把每个Action Creator包装成能自动触发dispatch的函数。
但如果你用函数作为mapDispatchToProps,React-Redux会把dispatch作为参数传给这个函数,需要你自己手动完成Action Creator与dispatch的绑定——你的失效代码恰恰跳过了这一步,直接返回了原始的Action Creator。
失效代码的问题点
你的mapDispatchToProps是一个无参函数:
const mapDispatchToProps = () => { return { increment, decrement } }
这里返回的increment和decrement只是原始的Action Creator,调用它们只会返回{type: 'increment'}这类Action对象,不会自动执行dispatch,所以Redux Store根本接收不到动作,状态也就不会更新。
正确的函数版写法
有两种方式可以修复这个问题:
方式1:手动用dispatch包装Action Creator
直接接收dispatch参数,返回绑定后的函数:
const mapDispatchToProps = (dispatch) => { return { increment: () => dispatch(increment()), decrement: () => dispatch(decrement()) } }
方式2:使用bindActionCreators工具函数
借助Redux的bindActionCreators批量绑定:
// 需要先导入bindActionCreators import { bindActionCreators } from 'redux' const mapDispatchToProps = (dispatch) => { return bindActionCreators({ increment, decrement }, dispatch) }
修正后的完整代码
<script type="text/babel" data-plugins="proposal-class-properties" data-presets="env,react"> // Action Creators - You don't need to change these const increment = () => ({ type: 'increment' }); const decrement = () => ({ type: 'decrement' }); const Counter = (props) => { return ( <div> <button className="increment" onClick={props.increment}>Increment</button> <button className="decrement" onClick={props.decrement}>Decrement</button> Current Count: <span>{props.count}</span> </div> ); }; const mapStateToProps = (state) => { return { count: state.count } } // 修正后的mapDispatchToProps const mapDispatchToProps = (dispatch) => { return { increment: () => dispatch(increment()), decrement: () => dispatch(decrement()) } } const WrappedCounter = ReactRedux.connect(mapStateToProps, mapDispatchToProps)(Counter); // Only change code *before* me! // ----------- const store = Redux.createStore(Redux.combineReducers({ count: (count = 0, action) => { if (action.type === 'increment') { return count + 1; } else if (action.type === 'decrement') { return count - 1; } else { return count; } } })); ReactDOM.render( <ReactRedux.Provider store={store}> <WrappedCounter /> </ReactRedux.Provider>, document.querySelector('#root') ); </script>
内容的提问来源于stack exchange,提问作者KARTHIKEYAN.A
相关产品推荐
相关产品推荐

