I’m trying to write a simple toggle button for starting an application and need to access data from the Redux state in the mapDispatchToProps
, so I am using mergeProps
, as a result. The basic idea is this: when clicked, the component retrieves the gameStarted
property from the Redux store and in mapDispatchToProps
modifies the gameStarted
property (replacing it with its opposite) by dispatching the startGame
action. Because I need to access gameStarte
d from the current state I am merging props from dispatch and from state in mergeProps
, but when I do so I get an infinite loop, where the action is dispatched without the component being clicked which in turn causes the component to get re-rendered, dispatching the action again and so on. How do I stop this from happening?
This is my code:
//action
export const startGame = (started) => ({ type: START, gameStarted: started });
//reducer
const initialState = {
gameStarted: false,
};
const drumReducer = (state=initialState, action) => {
switch (action.type) {
case START:
console.log('reducer start', action.gameStarted);
return Object.assign({}, state, { gameStarted: !action.gameStarted });
default:
return state;
}
};
//component
class Button extends Component {
render() {
return (
<div className="start-container" onClick={this.props.starts}></div>
);
}
}
const mapStateToProps = (state) => ({ gameStarted: state.gameStarted });
const mapDispatchToProps = (dispatch) => ({
dispatchStarts: (gameStarted) => dispatch(startGame(gameStarted)),
});
const mergeProps = (propsFromState, propsFromDispatch) => (
{
...propsFromState,
...propsFromDispatch,
starts: propsFromDispatch.dispatchStarts(propsFromState.gameStarted),
}
);
export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(Button);