无法从上下文提供程序获取挂钩
Unable to get hook from context provider
我正在使用上下文提供程序设置此自定义挂钩 based on this approach
const mainState = (initial: number | null = null) => {
const [edit, setEdit] = React.useState<number | null>(initial)
return {
edit,
clear: () => setEdit(null)
}
}
const MainContext = React.createContext<ReturnType<typeof mainState> | null>(null)
export const useMainContext = () => React.useContext(MainContext)
export function MainProvider({ children }: { children: React.ReactNode }) {
return (
<MainContext.Provider value={mainState()}>{children}</MainContext.Provider>
)
}
然后我将整个应用程序包装在提供程序中
import React from 'react'
import ReactDom from 'react-dom'
import { MainProvider } from './store'
import { App } from './app'
ReactDom.render(
<MainProvider>
<App />
</MainProvider>,
document.getElementById('root')
)
但是当我尝试使用
获取钩子 TypeScript 错误时
Property 'edit' does not exist on type '{ edit: number | null; clear: () => void; } | null'
import * as React from 'react'
import { useMainContext } from './store'
export const App = () => {
const { edit } = useMainContext()
...
}
正如 Typescript 告诉您的那样,上下文的类型可以是 null
或 { edit: number | null; clear: () => void; }
记住您最初将其设置为:const MainContext = React.createContext<ReturnType<typeof mainState> | null>(null)
。
您不能解构 null,这就是 Typescript 不满意的原因。要么你不使用解构:
const context = useMainContext()
context?.edit
或者您将上下文设置为具有编辑默认值的不同值。
我刚刚注意到 mainState 正在使用 useState 但 mainState 似乎既不是自定义反应挂钩也不是组件。 React 文档声明自定义 React 挂钩应以 use
开头。并且必须在另一个自定义反应钩子或组件中使用钩子。
修复代码的一种方法:
const useMainState = (initial: number | null = null) => { // this is now a custom react hook
const [edit, setEdit] = React.useState<number | null>(initial)
return {
edit,
clear: () => setEdit(null)
}
}
export function MainProvider({ children }: { children: React.ReactNode }) {
// it's called in a component, Ok
const mainState = useMainState()
return (
<MainContext.Provider value={mainState}>{children}</MainContext.Provider>
)
}
现在 React 可以跟踪您的状态。这就是为什么永远不要在 if 之后使用钩子也很重要的原因。在一个组件中必须始终使用相同数量的挂钩。
这与您所做的非常相似,但是您在 prop 中进行了调用,即使它有效,在设计方面也不是很好。
我正在使用上下文提供程序设置此自定义挂钩 based on this approach
const mainState = (initial: number | null = null) => {
const [edit, setEdit] = React.useState<number | null>(initial)
return {
edit,
clear: () => setEdit(null)
}
}
const MainContext = React.createContext<ReturnType<typeof mainState> | null>(null)
export const useMainContext = () => React.useContext(MainContext)
export function MainProvider({ children }: { children: React.ReactNode }) {
return (
<MainContext.Provider value={mainState()}>{children}</MainContext.Provider>
)
}
然后我将整个应用程序包装在提供程序中
import React from 'react'
import ReactDom from 'react-dom'
import { MainProvider } from './store'
import { App } from './app'
ReactDom.render(
<MainProvider>
<App />
</MainProvider>,
document.getElementById('root')
)
但是当我尝试使用
获取钩子 TypeScript 错误时Property 'edit' does not exist on type '{ edit: number | null; clear: () => void; } | null'
import * as React from 'react'
import { useMainContext } from './store'
export const App = () => {
const { edit } = useMainContext()
...
}
正如 Typescript 告诉您的那样,上下文的类型可以是 null
或 { edit: number | null; clear: () => void; }
记住您最初将其设置为:const MainContext = React.createContext<ReturnType<typeof mainState> | null>(null)
。
您不能解构 null,这就是 Typescript 不满意的原因。要么你不使用解构:
const context = useMainContext()
context?.edit
或者您将上下文设置为具有编辑默认值的不同值。
我刚刚注意到 mainState 正在使用 useState 但 mainState 似乎既不是自定义反应挂钩也不是组件。 React 文档声明自定义 React 挂钩应以 use
开头。并且必须在另一个自定义反应钩子或组件中使用钩子。
修复代码的一种方法:
const useMainState = (initial: number | null = null) => { // this is now a custom react hook
const [edit, setEdit] = React.useState<number | null>(initial)
return {
edit,
clear: () => setEdit(null)
}
}
export function MainProvider({ children }: { children: React.ReactNode }) {
// it's called in a component, Ok
const mainState = useMainState()
return (
<MainContext.Provider value={mainState}>{children}</MainContext.Provider>
)
}
现在 React 可以跟踪您的状态。这就是为什么永远不要在 if 之后使用钩子也很重要的原因。在一个组件中必须始终使用相同数量的挂钩。
这与您所做的非常相似,但是您在 prop 中进行了调用,即使它有效,在设计方面也不是很好。