Don't use useState directly when working with nested Object
But let you replace useState with a simple custom hook, and it would bring you much more fun and comfortable
Photo by Lautaro Andreani on Unsplash
I used a lot of useState
and feel uncomfortable when working with nested object
in updating state. I wrote a simple custom hook that would let working with nested Objects be comfortable and easy. It's named useLocalComponentCache
.
With the help of lodash
library, updating an object becomes so easy. Let's get started.
Hook signature
Please note that init
is optional
. If you update
a non-existed path, then it would be created automatically.
const {
localCache,
handlers: {
setLocalCache
}
} = useLocalComponentCache(init)
//the signature of the function
setLocalCache(value, path = "", toggle = false)
Sample object
const sampleObject= {
background: {
color: "#c69ef9",
imgUrl: "/themes/simplicity/preview/callout-bg.svg",
disabled: false
},
heading: {
text: "Welcome to ProDesk",
color: "#000000",
size: {
small: "10px",
medium: "16px",
large: "25px"
}
}
}
Usage
//change the heading text
setLocalCache("Welcome to my App", "heading.text")
//change the fontsize of medium
setLocalCache("15px", "heading.size.medium")
//add new value which not yet existed in init data
setLocalCache("40px", "heading.size.big")
//to toggle a value, we bypass the first parameter
setLocalCache(undefined, "background.disabled", true)
//or you can replace all with a completely new object
setLocalCache(newObject)
Note: to read the state, just read localCache
directly as a normal object
The hook
Note: the hook uses lodash
and react-use
library for simple implementation.
import { get, set, cloneDeep } from "lodash"
import { useDeepCompareEffect } from "react-use"
...
export default function useLocalComponentCache(_object = {}) {
const [cache, setCache] = useState(_object)
useDeepCompareEffect(() => {
setCache(_object)
}, [_object])
const handlers = React.useMemo(
() => ({
setLocalCache: (value, path = "", toggle = false) => {
if (!path)
setCache(value)
else
setCache(
(prevState) => {
let newCache = cloneDeep(prevState)
set(
newCache,
path,
toggle
? !get(prevState, path)
: value
)
return newCache
}
)
}
}), [])
return {
localCache: cache,
handlers
}
}
Thank you for reading my very first article
on the internet related to programming.
Code: gist.github.com/chasoft/78fcf8d922afb825664..
Have a nice day!