属性 类型 "props | undefined" 上不存在进程
Property processes does not exist on type "props | undefined"
我正在学习 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]);
}
问题是当您创建上下文时,您指定它的类型可以是 undefined
。
createContext()
当组件在其祖先中没有提供程序的情况下调用它时,上下文采用默认值。您也将此值设置为 undefined
。
const ProcessContext = createContext<Props | undefined>(undefined);
这是一种完全有效的上下文初始化方法,如果组件的祖先中没有提供程序,那么上下文可以是 undefined
是有道理的。组件不“知道”是否有提供者作为祖先为其尝试使用的上下文提供值。
但是,如果您的上下文是 undefined
,那么表达式
const { processes } = useContext(ProcessContext);
导致 javascript 错误,这是 Typescript 警告您的内容。如果您从没有访问提供程序的组件调用上下文,则此警告只会变成 javascript 错误。仍然很高兴 Typescript 可以在它变成错误之前捕捉到它。
有两种方法可以解决这个问题:
- 当你调用
useContext()
时处理上下文值为undefined
的可能性
- 使用
undefined
以外的默认值初始化您的上下文
对于 1. 代码可能如下:
const processContextValue = useContext(ProcessContext);
if (processContextValue) {
const { processes, ... } = processContextValue;
// Do stuff with processes
}
该代码只是选项之一,处理未定义值的方法有很多。您可以在 typescript docs.
中检查 narrowing
类型的概念(从联合中找出类型)
对于 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
是一个可能的值,它们就必须是可选的。
我正在学习 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]);
}
问题是当您创建上下文时,您指定它的类型可以是 undefined
。
createContext()
当组件在其祖先中没有提供程序的情况下调用它时,上下文采用默认值。您也将此值设置为 undefined
。
const ProcessContext = createContext<Props | undefined>(undefined);
这是一种完全有效的上下文初始化方法,如果组件的祖先中没有提供程序,那么上下文可以是 undefined
是有道理的。组件不“知道”是否有提供者作为祖先为其尝试使用的上下文提供值。
但是,如果您的上下文是 undefined
,那么表达式
const { processes } = useContext(ProcessContext);
导致 javascript 错误,这是 Typescript 警告您的内容。如果您从没有访问提供程序的组件调用上下文,则此警告只会变成 javascript 错误。仍然很高兴 Typescript 可以在它变成错误之前捕捉到它。
有两种方法可以解决这个问题:
- 当你调用
useContext()
时处理上下文值为 - 使用
undefined
以外的默认值初始化您的上下文
undefined
的可能性
对于 1. 代码可能如下:
const processContextValue = useContext(ProcessContext);
if (processContextValue) {
const { processes, ... } = processContextValue;
// Do stuff with processes
}
该代码只是选项之一,处理未定义值的方法有很多。您可以在 typescript docs.
中检查narrowing
类型的概念(从联合中找出类型)
对于 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
是一个可能的值,它们就必须是可选的。