开发者问题收集

类型“props | undefined”上不存在属性流程

2021-12-25
1170

我正在学习 React Context,我正在使用我构建的一个项目作为测试。

创建上下文后,我尝试在一个组件上使用它,但出现以下错误:属性“processes”在类型“Props | undefined”上不存在。但它确实存在于接口上,并且也存在于 ProcessContext.tsx 上。

interface.tsx

export default interface Props {
  children?: any;
  processes?: Array<string>;
  setProcesses?: (active: any) => void;
  updating?: boolean;
  setUpdating?: (active: boolean) => void;
  getProcesses?: () => void;
}

ProcessContext.tsx

import { createContext, FC, useState } from "react";
import { collection, getDocs } from "firebase/firestore";
import { db } from "../firebase";
import Props from "../Interface/Api";

const ProcessContext = createContext<Props | undefined>(undefined);
export const ProcessProvider: FC<Props> = ({ children }) => {
  const [processes, setProcesses] = useState<Array<any>>([]);
  const [updating, setUpdating] = useState<boolean>(false);

  const getProcesses = async () => {
    const processCollectionRef = collection(db, "processes");
    const data = await getDocs(processCollectionRef);
    setProcesses(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
  };

  return (
    <ProcessContext.Provider
      value={{ processes, setProcesses, updating, setUpdating, getProcesses }}
    >
      {children}
    </ProcessContext.Provider>
  );
};

export default ProcessContext;

CourseTable.tsx

import React, { FC, Fragment, useState, useContext, useEffect } from "react";
import CheckIcon from "@mui/icons-material/Check";
import {
  Modal,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
} from "@mui/material";
import ModalData from "./ModalData";
import ProcessContext from "../context/ProcessContext";
import Props from "../Interface/Api";

const CourseTable: FC = () => {
  const { processes, updating, getProcesses } = useContext(ProcessContext);
  const [open, setOpen] = useState(false);
  const handleOpen = () => setOpen(true);
  const handleClose = () => setOpen(false);

  useEffect(() => {
    getProcesses();
  }, [updating]);
}
1个回答

问题是,当您创建上下文时,您指定其类型可以是 undefined 。 当组件在其祖先中没有提供程序的情况下调用 createContext() 时,它将为上下文采用默认值。您也可以将此值设置为 undefined

const ProcessContext = createContext<Props | undefined>(undefined);

这是一种完全有效的初始化上下文的方法,如果组件的祖先中没有提供程序,则上下文可能为 undefined 是有道理的。组件“不知道”是否有提供程序作为祖先来为其尝试使用的上下文提供值。

但是,如果您的上下文是 undefined ,则表达式

const { processes } = useContext(ProcessContext);

会导致 javascript 错误,这就是 Typescript 警告您的内容。如果您从无法访问提供程序的组件调用上下文,此警告将仅变为 javascript 错误。Typescript 可以在错误发生之前捕获该错误,这仍然是一件好事。

有两种方法可以解决此问题:

  1. 在调用 useContext() 时处理上下文值 undefined 的可能性
  2. 使用 undefined 以外的默认值初始化上下文

对于 1.,代码可能如下:

const processContextValue = useContext(ProcessContext);
if (processContextValue) {
  const { processes, ... } = processContextValue;
  // Do stuff with processes
}

该代码只是选项之一,有很多方法可以处理未定义的值。您可以在 typescript 文档 中查看 缩小 类型的概念(从联合中找出类型)。

对于 2.,通常的做法是使用合理的默认值(也可以是未定义的)初始化上下文对象中的每个成员( Props 接口中指定的所有项目)。

const ProcessContext = createContext<Props>({
  children: undefined,
  processes: [], // You can always use `undefined`, but you can also use a default value like an empty array
  setProcesses: undefined,
  updating: false,
  setUpdating: undefined, // Functions could be `undefined`
  getProcesses: () => null, // or a default function that satisfies the type
});

我还注意到您将每个字段都设为可选,没有必要只因为您使用了 Context ,只有当 undefined 是一个可能的值时,它们才必须是可选的。

Francisco Aguirre
2021-12-25