I have a context like this
ProductProvider.js
import React, { createContext, useMemo } from 'react'
const INITIAL_HANDLER = {
sortType: null,
offset: 0
}
export const ProductProviderContext = createContext({
...INITIAL_HANDLER,
setHandler: () => null
})
export default ({ children }) => {
const [data, setData] = React.useState(INITIAL_HANDLER)
const setHandler = (value) => {
setData({ ...data, ...value })
}
const contextValue = useMemo(() => ({
...data,
setHandler
}), [data])
return (
<ProductProviderContext.Provider value={contextValue}>
{children}
</ProductProviderContext.Provider>
)
}
And in one of my child component that has been wrapped inside ProductProvider
I want to call setHandler
but I want to access the last value of data
like the useState
callback function so when I access a ProductProviderContext
from child, I can use setHandler
like useState
(either passing changed value directly or using callback to get previous data
value).
Example usage that I expect setHandler
to accept:
setHandler({ sortType: 'popular' })
// or I can use it like this
setHandler(prevData => ({ offset: prevData.offset++ }))
How do I refactor the setHandler
so I can call setHandler
like above?
3
Answers
Hmmm, you can try in
ProductProvider.js
I usually pass two
data
,setData
inProvider
. You can try this:The
setData
state updater function already does exactly what you are asking to do, so you can just pass it down directly to consumers if you like.Or you can update
setHandler
to consume a value that is either a value or a callback function that is passed to thesetData
state updater function.Either implementation should allow you to pass a value directly.
Or pass an updater callback. Be sure to not mutate the current state though (e.g. you still need to apply a mutable state update!).