Created
January 10, 2020 13:58
-
-
Save gargroh/0b9e5bf98b09f0ef62bcfad3475f911b to your computer and use it in GitHub Desktop.
This file contains hidden or 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 { actions } from '../../react-table/utils'; | |
// Actions | |
actions.forceUpdate = 'forceUpdate'; | |
export const useControlledState = (hooks) => { | |
hooks.stateReducers.push(reducer); | |
hooks.useInstance.push(useInstance); | |
}; | |
useControlledState.pluginName = 'useControlledState'; | |
function useInstance(instance) { | |
// Watch for `gridState` key, whenever it updates, then its time to dispatch `forceUpdate` | |
React.useEffect(() => { | |
// Syncing grid state fron outside to inside | |
instance.dispatch({ | |
type: 'forceUpdate', | |
newState: { ...instance.state, ...instance.gridState } | |
}); | |
}, [instance.gridState]); | |
} | |
function reducer(state, action, previousState, instance) { | |
/** | |
* Directly set state given by `forceUpdate` action | |
*/ | |
if (action.type === actions.forceUpdate) { | |
return { | |
...state, | |
...action.newState | |
}; | |
} | |
/** For actions which are going to be controlled, two things are handled here - | |
* 1. Stop from applying newState | |
* 2. dispatch callabck to consumer, so that they can update their state | |
* */ | |
if (isActionControlled(action.type, instance.gridState)) { | |
const { onDispatch } = instance; | |
if (onDispatch) { | |
onDispatch(state, previousState, action, instance); | |
} | |
return previousState; | |
} | |
} | |
/** List of all state keys with actions which manipulate them */ | |
const CONTROLLED_ACTIONS = { | |
sortBy: ['resetSortBy', 'toggleSortBy', 'clearSortBy'], | |
selectedRowIds: ['resetSelectedRows', 'toggleAllRowsSelected', 'toggleRowSelected'] | |
// ... | |
// ... | |
// ... | |
}; | |
/** Returns true if the given `action` exists in any key of `gridState` */ | |
function isActionControlled(name, gridState) { | |
return Object.keys(gridState).some((key) => { | |
return CONTROLLED_ACTIONS[key].includes(name); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment