我正在重構我正在關注TypeScript的教程。ReactJS在大多數情況下,本教程教你如何重構大部分代碼作為獎勵材料。然而,登錄部分只完成了ReactJS/JavaScript,我試圖重構我的代碼作為挑戰自己的一種方式。我堅持的部分是createContext因為我無法理解所需的型別。
原始JS代碼
JS 代碼 - 背景關系/提供者
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);
我的嘗試
我試過的
我嘗試應用以下解決方案,但我并沒有真正掌握這些概念以成功應用它們:
- 無法在打字稿中宣告 React 背景關系?[復制]
- 使用反應創建背景關系時找不到命名空間“ctx”錯誤 - 打字稿
- 如何在 TypeScript 中使用 React 背景關系
- React Context TypeScript — The Easy Way
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>
Type 'IUser | undefined' is not assignable to type 'IUser'. Type 'undefined' is not assignable to type 'IUser'.ts(2322)
const [_user, setUser] = useContext(Context);
Type 'UserContextType | undefined' is not an array type.ts(2461)
uj5u.com熱心網友回復:
首先,您像這樣宣告背景關系型別:
export const Context = createContext<UserContextType | undefined>(undefined);
這意味著value背景關系的 要么是具有所有屬性的物件,要么UserContextType是undefined。
那么這里:
const [state, setState] = useState<IUser>();
您創建的狀態型別為IUser. 但是因為您沒有提供默認值,所以默認值為undefined. 這會為您添加到州的型別中。state型別也是如此IUser | undefined。
然后我們來到這里:
value={{state, setState}}
state是IUser | undefined,但背景關系型別需要IUser[]該屬性的一個。所以那里既不是IUser也不undefined是有效型別。
首先,您需要確保如果您傳入一個物件,那么該物件的型別是正確的。這意味著它具有所有必需的屬性。否則,傳入未定義。您可以使用三元運算式來做到這一點:
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;
};
哪個有效,請參閱操場
或者你需要傳入一個用戶陣列:
const UserProvider: React.FC<React.ReactNode> = ({ children }) => {
const [state, setState] = useState<IUser[]>([]);
return (
<Context.Provider value={{state, setState}}>{children}</Context.Provider>
)
};
這也有效,見操場
您還可以將背景關系型別更改為:
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>
)
};
應該可以正常作業,請參閱操場
uj5u.com熱心網友回復:
這是 Typescript 上的背景關系示例
AuthContext.tsx:
import { createContext, ReactNode, useContext, useState } from "react";
import { AuthContextData } from "../models/AuthContextData.model";
const AuthContext = createContext<AuthContextData>({} as AuthContextData);
export const AuthProvider = ({ children }: { children: ReactNode }) => {
const [user, setUser] = useState<object | null>(null);
const [loading, setLoading] = useState<boolean>(true);
async function signIn(): Promise<void> {
console.log('sign in')
}
async function signOut(): Promise<void> {
console.log('sign out')
}
return (
<AuthContext.Provider
value={{ signed: !!user, user, signIn, signOut, loading }}
>
{children}
</AuthContext.Provider>
);
};
export function useAuth() {
const context = useContext(AuthContext);
return context;
}
AuthContextData.ts:
export interface AuthContextData {
signed: boolean;
user: object | null;
signIn(): Promise<void>;
signOut(): Promise<void>;
loading: boolean;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/442543.html
