1
0
Fork 0
freesewing/packages/react/hooks/useStateObject/index.mjs

49 lines
1.4 KiB
JavaScript
Raw Normal View History

2025-05-30 11:29:55 +02:00
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]
}