UNPKG

use-array-state

Version:

Provides a reducer to simplify handling of mutations to array state

192 lines (161 loc) 5.38 kB
import { useReducer, useCallback } from 'react'; import { createStandardAction, getType } from 'typesafe-actions'; function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } var ACTION_TYPES; (function (ACTION_TYPES) { ACTION_TYPES["PUSH"] = "PUSH"; ACTION_TYPES["POP"] = "POP"; ACTION_TYPES["UNSHIFT"] = "UNSHIFT"; ACTION_TYPES["SHIFT"] = "SHIFT"; ACTION_TYPES["SPLICE"] = "SPLICE"; ACTION_TYPES["UPDATE"] = "UPDATE"; ACTION_TYPES["SET"] = "SET"; ACTION_TYPES["INSERT"] = "INSERT"; ACTION_TYPES["MOVE"] = "MOVE"; ACTION_TYPES["REMOVE"] = "REMOVE"; ACTION_TYPES["SWAP"] = "SWAP"; })(ACTION_TYPES || (ACTION_TYPES = {})); const push = createStandardAction(ACTION_TYPES.PUSH)(); const pop = createStandardAction(ACTION_TYPES.POP)(); const unshift = createStandardAction(ACTION_TYPES.UNSHIFT)(); const shift = createStandardAction(ACTION_TYPES.SHIFT)(); const splice = createStandardAction(ACTION_TYPES.SPLICE)(); const update = createStandardAction(ACTION_TYPES.UPDATE)(); const set = createStandardAction(ACTION_TYPES.SET)(); const insert = createStandardAction(ACTION_TYPES.INSERT)(); const move = createStandardAction(ACTION_TYPES.MOVE)(); const remove = createStandardAction(ACTION_TYPES.REMOVE)(); const swap = createStandardAction(ACTION_TYPES.SWAP)(); const reducer = (state, action) => { switch (action.type) { case getType(push): return [...state, action.payload]; case getType(pop): return state.slice(0, state.length - 1); case getType(unshift): return [action.payload, ...state]; case getType(shift): return state.slice(1, state.length); case getType(splice): { const nextState = [...state]; nextState.splice(...action.payload); return nextState; } case getType(update): { const nextState = [...state]; nextState[action.payload.index] = action.payload.value; return nextState; } case getType(set): return action.payload; case getType(insert): { const nextState = [...state]; nextState.splice(action.payload.index, 0, action.payload.value); return nextState; } case getType(move): { const nextState = [...state]; if (action.payload.to >= nextState.length) { let i = action.payload.to - nextState.length + 1; while (i--) { nextState.push(undefined); } } nextState.splice(action.payload.to, 0, nextState.splice(action.payload.from, 1)[0]); return nextState; } case getType(remove): { const nextState = [...state]; nextState.splice(action.payload, 1); return nextState; } case getType(swap): { const nextState = [...state]; const largestIndex = Math.max(...action.payload); if (largestIndex >= nextState.length) { let i = largestIndex - nextState.length + 1; while (i--) { nextState.push(undefined); } } var _ref = [nextState[action.payload[1]], nextState[action.payload[0]]]; nextState[action.payload[0]] = _ref[0]; nextState[action.payload[1]] = _ref[1]; return nextState; } default: return state; } }; function useArrayState(initialState) { const _useReducer = useReducer(reducer, initialState || []), _useReducer2 = _slicedToArray(_useReducer, 2), state = _useReducer2[0], dispatch = _useReducer2[1]; const boundActions = { push: useCallback(value => dispatch(push(value)), []), pop: useCallback(() => dispatch(pop()), []), unshift: useCallback(value => dispatch(unshift(value)), []), shift: useCallback(() => dispatch(shift()), []), splice: useCallback(function (start, deleteCount) { for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { args[_key - 2] = arguments[_key]; } return dispatch(splice([start, deleteCount, ...args])); }, []), update: useCallback((index, value) => dispatch(update({ index, value })), []), set: useCallback(value => dispatch(set(value)), []), insert: useCallback((index, value) => dispatch(insert({ index, value })), []), move: useCallback((from, to) => dispatch(move({ from, to })), []), remove: useCallback(index => dispatch(remove(index)), []), swap: useCallback((indexA, indexB) => dispatch(swap([indexA, indexB])), []) }; return [state, boundActions]; } export default useArrayState; export { reducer };