在typescript中使用带有react钩子的react上下文



下面的代码演示了我如何尝试用react钩子实现react的上下文,这里的想法是我将能够轻松地从任何子组件访问上下文,比如这个

const {authState, authActions} = useContext(AuthCtx);

首先,我创建了一个导出上下文和提供程序的文件。

import * as React from 'react';
const { createContext, useState } = React;
const initialState = {
email: '',
password: ''
};
const AuthCtx = createContext(initialState);
export function AuthProvider({ children }) {
function setEmail(email: string) {
setState({...state, email});
}
function setPassword(password: string) {
setState({...state, password}); 
}
const [state, setState] = useState(initialState);
const actions = {
setEmail,
setPassword
};
return (
<AuthCtx.Provider value={{ authState: state, authActions: actions }}>
{children}
</AuthCtx.Provider>
);
}
export default AuthCtx;

这是可行的,但我在提供程序的value中收到了以下错误,可能是因为我在中添加了操作,因此问题是,有没有一种方法可以让我保持所有内容的类型,并且仍然能够导出上下文和提供程序?

我相信我也不能把createContext放在我的主函数中,因为它会一直重新创建它?

[ts]类型'{authState:{email:string;password:string!};authActions:{setEmail:(email:string(=>void;setPassword:(密码:string(=>void;};}'不可分配给类型"{email:一串password:string;}'。对象文字只能指定已知属性,并且类型"{email:string;"中不存在"authState";password:string;}'。[2232]index.d.ts(266,9(:所需的类型来自在类型上此处声明的属性"value"'本质属性&ProviderProps<{email:string;密码:string;}>'(property(authState:{电子邮件:字符串;密码:string;}

上面的答案有效,因为禁用了严格的类型检查规则。具有严格规则的上下文示例:

import { createContext, Dispatch, SetStateAction, useState } from 'react';
import { Theme } from '@styles/enums';
import { Language } from '@common/enums';
type Props = {
children: React.ReactNode;
};
type Context = {
appLang: string;
appTheme: string;
setContext: Dispatch<SetStateAction<Context>>;
};
const initialContext: Context = {
appLang: Language.EN,
appTheme: Theme.DEFAULT,
setContext: (): void => {
throw new Error('setContext function must be overridden');
},
};
const AppContext = createContext<Context>(initialContext);
const AppContextProvider = ({ children }: Props): JSX.Element => {
const [contextState, setContext] = useState<Context>(initialContext);
return (
<AppContext.Provider value={{ ...contextState, setContext }}>
{children}
</AppContext.Provider>
);
};
export { AppContext, AppContextProvider };

它对我有效。ThemeLanguage只是枚举,如下所示:

export enum Theme {
DEFAULT = 'DEFAULT',
BLACK = 'BLACK',
}

如果程序员没有在Provider中定义setContext,我会在setContext内部的initialContext中发送Error函数以引发错误。你可以直接使用

setContext: (): void => {}

祝你好运!

在创建Context时,您正在为其提供初始值。以您期望的格式为提供程序提供该值,如:

const initialState = {
authState : { 
email: '',
password: ''
},
authActions = {
setEmail: () => {},
setPassword: () => {}
};
};
const AuthCtx = createContext(initialState);

此外,您甚至不需要initialState,因为它只传递给Consumer,如果您在Consumer的层次结构中没有更高级别的Provider。

相关内容

  • 没有找到相关文章

最新更新