Last active
January 16, 2023 23:24
-
-
Save npverni/30c5930209d03ddcdd4ee1ff40263f8f to your computer and use it in GitHub Desktop.
useConnector: A custom hook that enables a redux-like setup with action creators using useReducer under the hood
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const inc = () => | |
dispatch => dispatch({ type: 'inc' }); | |
export const dec = () => | |
dispatch => dispatch({ type: 'dec' }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import useConnector from './useConnector'; | |
import reducer from './reducer'; | |
import * as unboundActions from './actions'; | |
const App = () => { | |
const initialState = { count: 0 }; | |
const [state, actions] = useConnector(initialState, reducer, unboundActions); | |
return ( | |
<div> | |
Counter: {state.count} | |
<button onClick={actions.inc}>+</button> | |
<button onClick={actions.dec}>-</button> | |
</div> | |
); | |
} | |
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const reducer = (state, action) => { | |
switch (action.type) { | |
case 'inc': | |
return { ...state, count: state.count + 1}; | |
case 'dec': | |
return { count: state.count - 1}; | |
default: | |
throw new Error(); | |
} | |
} | |
export default reducer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useReducer } from 'react'; | |
const bindActionsToDispatchAndState = (unboundActions, dispatch, state) => | |
Object.keys(unboundActions).map(key => | |
[key, (...args) => unboundActions[key](...args)(dispatch, state)], | |
).reduce( | |
(acc, cur) => ({ ...acc, [cur[0]]: cur[1] }), | |
{}, | |
); | |
const useConnector = ( | |
initialState, | |
reducer, | |
unboundActions, | |
) => { | |
const [state, dispatch] = useReducer(reducer, initialState); | |
const actions = bindActionsToDispatchAndState(unboundActions, dispatch, state); | |
return [state, actions]; | |
}; | |
export default useConnector; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment