我正在将其重构为TypeScript a tutorial/ReactJS,我正在遵循这一点.在大多数情况下,本教程将教您如何重构大部分代码作为额外material .然而,登录部分只在ReactJS/JavaScript年完成,我试图重构代码,以此挑战自己.我被卡住的部分是createContext,因为我无法理解所需的类型.

原始JS代码

JS code - Context/Provider

import React, { useState, createContext } from "react";


export const Context = createContext();

const UserProvider = ({ children }) => {
    const [state, setState] = useState(undefined);

    return (
        <Context.Provider value={[state, setState]}>{children}</Context.Provider>
    )
};

export default UserProvider;

在登录组件上,它被const [_user, setUser] = useContext(Context);调用

我的try

What I've tried

我试图应用以下解决方案,但我对这些概念掌握得不够好,无法成功应用它们:

TS code - Context/Provider

import React, { useState, createContext } from "react";
import { IUser, UserContextType } from "./@types/context";


export const Context = createContext<UserContextType | undefined>(undefined);

const UserProvider: React.FC<React.ReactNode> = ({ children }) => {
    const [state, setState] = useState<IUser>();

    return (
        <Context.Provider value={{state, setState}}>{children}</Context.Provider>
    )
};

export default UserProvider;

TS code - types

export interface IUser {
    user: string;
    password: string;
};

export type UserContextType = {
    state: IUser;
    setState: (newSession: IUser) => void;
};

Errors

<Context.Provider value={{state, setState}}>{children}</Context.Provider>

类型"IUser | undefined"不可分配给类型"IUser".类型"undefined"不能分配给类型"IUser".ts(2322)

const [_user, setUser] = useContext(Context);

类型"UserContextType | undefined"不是数组类型.ts(2461)

推荐答案

首先,您可以这样声明上下文类型:

export const Context = createContext<UserContextType | undefined>(undefined);

这意味着上下文的value要么是所有属性都为UserContextType的对象,要么是undefined.

然后这里:

const [state, setState] = useState<IUser>();

创建类型为IUser的状态.但由于没有提供默认值,因此默认值为undefined.这将添加到州的类型中.state属于IUser | undefined型.

然后我们来到这里:

value={{state, setState}}

stateIUser | undefined,但上下文类型要求该属性为IUser[].所以IUserundefined都不是有效的类型.


首先,您需要确保如果传入对象,那么该对象的类型是正确的.这意味着它具有所有必需的属性.否则,请输入未定义.可以使用三元表达式来实现这一点:

value={state ? {state, setState} : undefined}

现在,如果state有一个值,那么将创建并传递上下文值.否则,上下文值为undefined.


但现在你会发现这个错误:

    Types of property 'state' are incompatible.
      Type 'IUser' is missing the following properties from type 'IUser[]': length, pop, push, concat, and 26 more.(2322)

这是因为您试图将单个用户IUser分配给一组用户IUser[].

看起来您的意思是内容只包含一个用户,因此您可能希望将上下文类型更改为:

export type UserContextType = {
    state: IUser;
    setState: (newSession: IUser) => void;
};

哪个有效,see playground

或者您需要传入一组用户:

const UserProvider: React.FC<React.ReactNode> = ({ children }) => {
    const [state, setState] = useState<IUser[]>([]);

    return (
        <Context.Provider value={{state, setState}}>{children}</Context.Provider>
    )
};

这同样有效,see playground


您还可以将上下文类型更改为:

export type UserContextType = {
    state?: IUser;
    setState: (newSession: IUser) => void;
};

这使得state个可选,然后:

const UserProvider: React.FC<React.ReactNode> = ({ children }) => {
    const [state, setState] = useState<IUser>();

    return (
        <Context.Provider value={{state, setState}}>{children}</Context.Provider>
    )
};

应该可以,see playground

Javascript相关问答推荐

如果没有尾随斜线,托管在收件箱中的React/Vite将无法工作

使用复选框在d3.js多折线图中添加或删除线条

类型自定义lazy Promise. all

将状态向下传递给映射的子元素

InDesign—创建一个独立的窗口,在文档中进行更正时保持打开状态

如何禁用附加图标点击的v—自动完成事件

当作为表达式调用时,如何解析方法decorator 的签名?

无法访问Vue 3深度监视器中对象数组的特定对象值'

我怎么才能得到Kotlin的密文?

如果Arrow函数返回函数,而不是为useEffect返回NULL,则会出现错误

如何在coCos2d-x中更正此错误

在WordPress中使用带有WPCode的Java代码片段时出现意外令牌错误

使用领域Web SDK的Vite+Vue应用程序中的Web程序集(WASM)错误

JQuery Click事件不适用于动态创建的按钮

在使用位板时,如何在Java脚本中判断Connect 4板中中柱的对称性?

NG/Express API路由处理程序停止工作

为什么我的按钮没有从&q;1更改为&q;X&q;?

react 路由DOM有条件地呈现元素

有没有办法在R中创建一张具有多个色标的热图?

验证Java脚本函数中的两个变量