如何在createContext中为TypeScript初始化useState的set函数?
How to initialise the set function of useState for TypeScript in a createContext?
我有一个 Provider
通过两个 contexts
.
提供状态变量及其对应的 setter
const BookedBatchContext = createContext({})
const SetBookedBatchContext = createContext(null)
const initialState = {
id: null
}
Provider
看起来像这样:
export const BookedBatchProvider = ({ children }: { children: any }) => {
const [bookedBatch, setBookedBatch] = useState(localState ||initialState)
return (
<SetBookedBatchContext.Provider value={setBookedBatch}>
<BookedBatchContext.Provider value={bookedBatch}>
{ children }
</BookedBatchContext.Provider>
</SetBookedBatchContext.Provider>
)
}
通过自定义挂钩,我使 setBookedBatch
可用于其他组件:
export const useBookedBatch = () => {
const bookedBatch = useContext(BookedBatchContext)
const setBookedBatch = useContext(SetBookedBatchContext)
return { bookedBatch, setBookedBatch }
}
尝试使用 setBookedBatch
函数时,我在给定组件中收到以下错误:
setBookedBatch(selectedBatch)
错误:
TS2721: Cannot invoke an object which is possibly 'null'.
由于useState
函数的setter不是我创建的函数,所以创建context的时候不知道怎么初始化:
const SetBookedBatchContext = createContext(null)
这样 TypeScript 就不会报错了。
- 如何知道setter函数的初始值?
- 如果我不提供任何类型,如何避免 TS 抱怨空值?
React.createContext
和React.useState
的return类型是根据您传入的初始值推断出来的。
1.) 您可以通过手动指定通用类型来创建适当的上下文类型:
const SetBookedBatchContext = createContext<null | React.Dispatch<React.SetStateAction<State>>>(null)
注意:useState
的 setter 类型为 React.Dispatch<React.SetStateAction<State>>
,其中 State
是 localState || initialState
的类型。
2.) 在您的自定义 Hook useBookedBatch
中断言 setBookedBatch
是 不是 null
:
export const useBookedBatch = () => {
const bookedBatch = useContext(BookedBatchContext)
const setBookedBatch = useContext(SetBookedBatchContext)
if (setBookedBatch === null) throw new Error() // this will make setBookedBatch non-null
return { bookedBatch, setBookedBatch }
// returns: { bookedBatch: {}; setBookedBatch: React.Dispatch<React.SetStateAction<State>>; }
}
3.) 然后 setBookedBatch
之后可以在没有断言的情况下被调用:
const App = () => {
const { setBookedBatch } = useBookedBatch()
useEffect(() => { setBookedBatch({ id: "foo" }) }, [])
}
我有一个 Provider
通过两个 contexts
.
const BookedBatchContext = createContext({})
const SetBookedBatchContext = createContext(null)
const initialState = {
id: null
}
Provider
看起来像这样:
export const BookedBatchProvider = ({ children }: { children: any }) => {
const [bookedBatch, setBookedBatch] = useState(localState ||initialState)
return (
<SetBookedBatchContext.Provider value={setBookedBatch}>
<BookedBatchContext.Provider value={bookedBatch}>
{ children }
</BookedBatchContext.Provider>
</SetBookedBatchContext.Provider>
)
}
通过自定义挂钩,我使 setBookedBatch
可用于其他组件:
export const useBookedBatch = () => {
const bookedBatch = useContext(BookedBatchContext)
const setBookedBatch = useContext(SetBookedBatchContext)
return { bookedBatch, setBookedBatch }
}
尝试使用 setBookedBatch
函数时,我在给定组件中收到以下错误:
setBookedBatch(selectedBatch)
错误:
TS2721: Cannot invoke an object which is possibly 'null'.
由于useState
函数的setter不是我创建的函数,所以创建context的时候不知道怎么初始化:
const SetBookedBatchContext = createContext(null)
这样 TypeScript 就不会报错了。
- 如何知道setter函数的初始值?
- 如果我不提供任何类型,如何避免 TS 抱怨空值?
React.createContext
和React.useState
的return类型是根据您传入的初始值推断出来的。
1.) 您可以通过手动指定通用类型来创建适当的上下文类型:
const SetBookedBatchContext = createContext<null | React.Dispatch<React.SetStateAction<State>>>(null)
注意:useState
的 setter 类型为 React.Dispatch<React.SetStateAction<State>>
,其中 State
是 localState || initialState
的类型。
2.) 在您的自定义 Hook useBookedBatch
中断言 setBookedBatch
是 不是 null
:
export const useBookedBatch = () => {
const bookedBatch = useContext(BookedBatchContext)
const setBookedBatch = useContext(SetBookedBatchContext)
if (setBookedBatch === null) throw new Error() // this will make setBookedBatch non-null
return { bookedBatch, setBookedBatch }
// returns: { bookedBatch: {}; setBookedBatch: React.Dispatch<React.SetStateAction<State>>; }
}
3.) 然后 setBookedBatch
之后可以在没有断言的情况下被调用:
const App = () => {
const { setBookedBatch } = useBookedBatch()
useEffect(() => { setBookedBatch({ id: "foo" }) }, [])
}