https://codesandbox.io/s/jvj6o043yv
我正在尝试使用非常简单的Counter示例来理解react-redux连接,Provider,mapStateToProps和MapDispatchToProps的基础知识 . 练习的目的是将道具和动作注入Counter组件 .
我看到的问题是我的操作在每次点击按钮时都会触发两次 . 我是Redux noob,所以我确信(我希望)这是一个相当基本的错误 . 我很欣赏任何指向错误的地方 . 提前致谢 .
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { connect } from 'react-redux'
import { createStore, applyMiddleware } from 'redux';
import { createLogger } from 'redux-logger';
// Reducer
const counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
// store setup
const configureStore = () => {
const middlewares = [];
if (process.env.NODE_ENV !== 'production') {
middlewares.push(createLogger());
}
return createStore(
counter,
applyMiddleware(...middlewares)
);
};
const store = configureStore();
// functional component
let Counter = ({
currCounter,
onIncrement,
onDecrement
}) => (
<div>
<h1>{currCounter}</h1>
<button onClick={onIncrement}>+</button>
<button onClick={onDecrement}>-</button>
</div>
);
// Connect logic
const mapStateToProps = (state) => ({
currCounter: state
})
const mapDispatchToProps = {
onIncrement: () =>
store.dispatch({
type: 'INCREMENT'
}),
onDecrement: () =>
store.dispatch({
type: 'DECREMENT'
}),
}
Counter = connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
// Entry point
const render = () => {
ReactDOM.render(
<Provider store={store}>
<Counter />
</Provider>,
document.getElementById('root')
);
};
store.subscribe(render);
render();
3 回答
你're getting a duplicated dispatch is because of the way you'写了你的
mapDispatchToProps
对象的原因(看似无辜地使用双箭头语法) .没有大括号的双箭头语法,如
() => value
,转换为function { return value }
.因此,
onIncrement
实际上不再是一个看起来像{ store.dispatch(...) }
的函数 - 它只是调度的动作 .如果我们写
onIncrement
看起来像这样(它只返回操作对象):我们最终会在按下按钮时执行适当的操作 .
这导致你的双重调度 -
onIncrement
首先调用store.dispatch
然后从返回的对象中旋转另一个调度 .无论如何,只需在
onIncrement()
中添加大括号即可解决这个问题:您也可以只返回操作对象,如前所示 .
mapDispatchToProps()
已经在调度动作 . 添加store.dispatch()
是多余的 .如果您正在使用mapDspatchToProps(),则不需要添加store.dspatch(),因为它已经隐含了 .
干杯