【问题标题】:React useContext & Typescript: Not an Array TypeReact useContext & Typescript:不是数组类型
【发布时间】:2021-09-11 17:22:34
【问题描述】:

我使用 React createContext 创建了以下上下文:

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(false)

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

export default MobileProvider

据我所知,这可以正常工作(至少我没有收到任何打字稿错误)。

我现在想按如下方式“使用”该上下文:

import * as React from "react"

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

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

export default Mobile

我在这里遇到了一些打字错误——特别是,[show, setShow] 带有红色波浪线下划线和以下消息:

Type '[
  show: boolean, 
  setShow: { 
    readonly on: () => void; 
    readonly off: () => void; 
    readonly toggle: () => void; 
    }
  ] | undefined' is not an array type.ts(2461)

我不明白为什么这不是数组类型或如何解决这个问题。

有什么想法吗?

谢谢。

【问题讨论】:

    标签: reactjs typescript react-context use-context


    【解决方案1】:

    我会这样做

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

    这里唯一的问题是showsetShow 可能是未定义的。如果需要,您实际上可以为这些设置默认值:

    const [
      show = false,
      setShow = () => {},
    ] = React.useContext(MobileContext) ?? []
    

    不过,设置默认值可能会混淆showsetShow的类型,例如可以设置show = 1。所以,你知道...负责任地使用。

    【讨论】:

      【解决方案2】:
      export const MobileContext = createContext<
        [show: useBooleanReturn[0], setShow: useBooleanReturn[1]] | undefined
      >(undefined)
      

      您已指定虽然值可能是一个数组,但它也可能是undefined。如果这是正确的,那么您将需要在与它交互之前检查 undefined,就好像它是一个数组一样:

      const Mobile = () => {
        const value = React.useContext(MobileContext);
        if (value) {
          const [show, setShow] = value;
          // do something with show and setShow
        }
      }
      

      另一方面,如果您不希望undefined 成为可能,则更新上下文的初始化:

      export const MobileContext = createContext<
        [show: useBooleanReturn[0], setShow: useBooleanReturn[1]]
      >([false, () => {}])
      

      【讨论】:

      • 我不希望 undefined 成为可能,我只添加它是因为 React Context 需要一个默认值。话虽如此,当我尝试您的解决方案时,() =&gt; {} 出现不同的错误。即:Type '() =&gt; void' is missing the following properties from type '{ readonly on: () =&gt; void; readonly off: () =&gt; void; readonly toggle: () =&gt; void; }': on, off, toggle。知道如何解决这个问题吗?
      • 您需要填写与useBooleanReturn[1] 类型匹配的默认值。我猜了一下可能是什么并做了一个空函数,但显然不匹配。
      【解决方案3】:

      你只是说它可以是未定义的,如果它是未定义的,那么它就不能以这种方式解构。

      很容易看出这会引发错误: const [show, setShow] = undefined;

      所以要么检查从 useContext 返回的值是否未定义,要么使用虚拟数据对其进行初始化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-14
        • 2021-06-04
        • 2018-08-19
        • 1970-01-01
        相关资源
        最近更新 更多