48 lines
1.4 KiB
JavaScript
48 lines
1.4 KiB
JavaScript
import { useState } from 'react'
|
|
import set from 'lodash/set.js'
|
|
import unset from 'lodash/unset.js'
|
|
|
|
/*
|
|
* Helper method to handle object updates
|
|
*
|
|
* This is a wrapper around lodash.set() with extra support for unsetting data.
|
|
*
|
|
* @param {object} obj - The object to update
|
|
* @param {array|string} path - The path to the property to update either as an array or string in dot notation
|
|
* @param {mixed} val - The value to set. If the value holds the string 'unset' the property will be removed
|
|
*
|
|
* @return {object} obj - The mutated object
|
|
*/
|
|
export const objUpdate = (obj = {}, path, val = undefined) => {
|
|
if (val === undefined) {
|
|
if (Array.isArray(path) && Array.isArray(path[0])) {
|
|
for (const [ipath, ival = undefined] of path) {
|
|
if (ival === undefined) unset(obj, ipath)
|
|
else set(obj, ipath, ival)
|
|
}
|
|
} else unset(obj, path)
|
|
} else set(obj, path, val)
|
|
|
|
return obj
|
|
}
|
|
|
|
/*
|
|
* This hooks provides an React state update with an
|
|
* update method that allows us to set deeply nested
|
|
* properties.
|
|
*/
|
|
export const useStateObject = (dflt = {}) => {
|
|
const [obj, setObj] = useState(dflt)
|
|
|
|
const replace = (val) => setObj(val)
|
|
|
|
const update = (path, val, altObj = false) => {
|
|
const newObj = altObj ? { ...altObj } : { ...obj }
|
|
objUpdate(newObj, path, val)
|
|
setObj(newObj)
|
|
|
|
return newObj
|
|
}
|
|
|
|
return [obj, update, replace]
|
|
}
|