useContext 返回未定义,即使它不应该是未定义的

Posted

技术标签:

【中文标题】useContext 返回未定义,即使它不应该是未定义的【英文标题】:useContext Returning Undefined Even Though It Shouldn't Be Undefined 【发布时间】:2021-09-11 21:27:53 【问题描述】:

我在 React 中创建了以下上下文:

import  useBoolean  from "@chakra-ui/react"
import  createContext, FC  from "react"

type useBooleanReturn = ReturnType<typeof useBoolean>

export const MobileContext = createContext<
  [show: useBooleanReturn[0], setShow: useBooleanReturn[1]] | undefined
>(undefined)

// --- PROVIDER
const MobileProvider: FC = ( children ) => 
  const [show, setShow] = useBoolean()

  return (
    <MobileContext.Provider value=[show, setShow]>
      children
    </MobileContext.Provider>
  )


export default MobileProvider

到目前为止一切都很好,但是当我尝试使用这个上下文时,事实证明正在传递的是undefined。也就是说,在下面的代码中value是未定义的:

const value = React.useContext(MobileContext)

不过,我不知道为什么会这样,因为我在设置上下文时使用了useBoolean 钩子——即这一行:const [show, setShow] = useBoolean()。然后我将showsetShow 传递给我的上下文:value=[show, setShow]。因此,不应该使用具有两个值(即showsetShow)的数组来定义值吗?

知道为什么没有发生这种情况吗?我能做些什么来解决它?

谢谢。

更新 这是我打电话给useContext时的完整示例:

import * as React from "react"
import MobileProvider,  MobileContext  from "./context.mobile"

const Mobile = () => 
  const value = React.useContext(MobileContext)

  console.log("value:", value)
  ...

以上是我为测试目的所做的。这是我的代码实际上应该是这样的:

import * as React from "react"
import Base from "./base"

import Header from "./Header"
import Menu from "./Menu"
import Footer from "./Footer"


import MobileProvider,  MobileContext  from "./context.mobile"

const Mobile = () => 
  const [show, setShow] = React.useContext(MobileContext)

  return (
    <MobileProvider>
      <Base onClick=setShow.toggle ref=ref show=show>
        <Header onClick=setShow.toggle />
        <Menu />
        <Footer />
      </Base>
    </MobileProvider>
  )


export default Mobile

【问题讨论】:

请显示完整示例,您实际调用useContext 的位置,您可以在代码框中复制它吗? @DennisVash 我已经更新了这个问题。如果您还需要什么,请告诉我。 仍然不是一个完整的例子,你如何渲染Mobile?请显示MobileProvider 组件树 @DennisVash 提供者应该在那里(我做了一个实验,我将提供者移到更高的位置,但它没有帮助)。无论哪种方式,我都重新编辑了包含MobileProvider 的代码。 但是您的Mobile 组件显然是高于 MobileProvider(它包括它)。所以它获取 default 上下文值,而不是提供者提供的实际值。 【参考方案1】:

您应该在 PROVIDER'S CONSUMERS 上致电useContext

换句话说,调用useContext (Mobile) 的组件必须是MobileProvider 的子组件。

在您的情况下,它不是消费者,这不是 API 定义的方式,因此您将获得默认值 (undefined),因为它在上下文之外调用。

const Mobile = () => 
  // NOT A CONSUMER
  const [show, setShow] = React.useContext(MobileContext)

  return (
    <MobileProvider>
      ...
    </MobileProvider>
  )

将组件移动到MobileProvider

<MobileProvider>
  <Mobile/>
</MobileProvider>

const Mobile = () => 
  // NOW A CONSUMER
  const [show, setShow] = React.useContext(MobileContext)

  return (
    <Base onClick=setShow.toggle ref=ref show=show>
        ...
    </Base>
  )

【讨论】:

谢谢——解决了这个问题。非常感谢:)。

以上是关于useContext 返回未定义,即使它不应该是未定义的的主要内容,如果未能解决你的问题,请参考以下文章

React.useContext() 不断返回未定义?

重新定义的 toString 的 getOwnPropertyDescriptor 应该是未定义的

useContext 返回未定义

反应useContext返回未定义

React - useContext 返回未定义

声明状态属性的组件是未定义的,即使它是,Auth