I am using react/redux to build my app. There are multiple buttons and the app needs to keep track of states of whether these buttons were clicked. These buttons are all using the same reducer logic, which is to alternate the state from true to false whenever the button is clicked. The only differentiator is the name of the state. Is there a way to reduce my code by defining a "global" reducer that can be applied to multiple states? Please refer to this image for an example
Thank you!
This is how I would do it. Instead of dispatching unique action for every button type like MENU_BTN
, SEARCH_BTN
, etc.. I would dispatch { type: 'TOGGLE_BUTTON', payload: 'menu' }
and in reducer
case TOGGLE_BUTTON:
return {
[payload]: !state[payload]
...state
}
You can then toggle buttons like this
const toggleButton = key => ({
type: 'TOGGLE_BUTTON',
payload: key
})
dispatch(toggleButton('menu'))
dispatch(toggleButton('search'))
That way you can keep track of as many buttons as you want. Your state will then look something like this
...
buttons: {
menu: true,
search: false
}
...
and you can easily write selector for every button
// Component displaying state of menu button //
let MyComponent = ({ menuButtonState }) => (
<div>
Menu button is {menuButtonState ? 'on' : 'off'}
</div>
)
// Helper function for creating selectors //
const createGetIsButtonToggledSelector = key => state => !!state.buttons[key]
// Selector getting state of a menu button from store //
const getIsMenuButtonToggled = createGetIsButtonToggledSelector('menu')
// Connecting MyComponent to menu button state //
MyComponent = connect(state => ({
menuButtonState: getIsMenuButtonToggled(state)
})(MyComponent)