Skip to content

Instantly share code, notes, and snippets.

@gargroh
Created January 10, 2020 13:58
Show Gist options
  • Save gargroh/0b9e5bf98b09f0ef62bcfad3475f911b to your computer and use it in GitHub Desktop.
Save gargroh/0b9e5bf98b09f0ef62bcfad3475f911b to your computer and use it in GitHub Desktop.
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