使用 Typescript 不允许 React createContext(null)?
Posted
技术标签:
【中文标题】使用 Typescript 不允许 React createContext(null)?【英文标题】:React createContext(null) not allowed with Typescript? 【发布时间】:2020-11-14 17:25:13 【问题描述】:我正在尝试使用 useReducer 和 useContext 挂钩设置 React 存储。 React.createContext(defaultValue) 正在使用我的 TS 检查器创建问题。我尝试了一些不同的东西,但本质上,我 createContext(null)
然后在组件 useReducer()
中设置状态和调度,但是当我调用提供者并将值作为 state, dispatch 传递时,它没有告诉我“类型'状态:任何;调度:React.Dispatch;'不可分配给类型'null'。
我不明白这一点,因为当它出错时,我已经分配了状态和调度,并且值不应再为空。
这是我正在尝试创建的 Context Provider 包装器。
import React, createContext, useReducer, FC, Dispatch from 'react';
import storeReducer, initialState from './reducer';
import Action, State from './types';
import isNull from 'util';
const StoreContext = createContext(null);
const StoreProvider:FC = ( children ) =>
const [state, dispatch] = useReducer(storeReducer, initialState);
const value = state, dispatch
return (
<StoreContext.Provider value=value>
children
</StoreContext.Provider>
);
;
export StoreProvider, StoreContext ;
export interface IStoreContext
dispatch: (action: Action<any>) => ;
state: State;
如果我将其保留为简单的 const StoreContext = createContext();
,那么它会抱怨 defaultValue 没有被定义。
疯狂的是,我已经从一个旧项目中提取了这个并且编译时没有问题。
【问题讨论】:
【参考方案1】:当您使用null
初始化上下文时,无法推断出预期的类型。在这种情况下,您必须明确给出上下文的类型。
这里看起来像:
const StoreContext = createContext<
state: MyStateType,
dispatch: Dispact,
| null>(null);
【讨论】:
我试过了。当我声明类型时,我让它工作,但在消费者(我称之为 useContext)中,我收到以下错误:Argument of type 'Context<MyContextType | null>' is not assignable to parameter of type 'Context<MyContextType>'.
我为“MyContextType”创建了一个接口,如下所示:export interface MyContextType state: State; dispatch: Dispatch<any>;
。这是消费者中的上下文回调:const ctx = useContext<MyContextType>(StoreContext)
它不喜欢 null
在我初始化时作为值,但它也不允许我声明 <TypeName | null>
。【参考方案2】:
由于我刚刚注册了一个帐户来回答这个问题,我无法在上面发表评论。
Alex Wayne 是正确的,Typescript 可以接受。但是,useContext
钩子并不能真正解决这个问题,因为就 Typescript 而言,您可能在该上下文中有一个 null
值。
来自原始答案...这是我们在 Typescript 中的上下文
const StoreContext = createContext<state: MyStateType, dispatch: Dispatch | null>(null);
所以,我们需要创建一个新的钩子,我们称之为useContextAndErrorIfNull
。这看起来像:
const useContextAndErrorIfNull = <ItemType>(context: Context<ItemType | null>): ItemType =>
const contextValue = useContext(context);
if (contextValue === null)
throw Error("Context has not been Provided!");
return contextValue;
使用这个钩子代替useContext
,它应该都能正常工作。
【讨论】:
完美,当您知道在提供程序未初始化时您将永远不会使用您的上下文时,这非常有用【参考方案3】:在这种情况下,为了省去麻烦,可以暂时施放它:
interface Store
state: MyStateType,
dispatch: Dispact,
const StoreContext = createContext<Store>( as Store);
const StoreProvider = (children) =>
const state, dispatch = theseAreAlwaysPresent()
return (
<StoreContext value=state, dispatch>
children
</StoreContext.Provider>
)
...
【讨论】:
以上是关于使用 Typescript 不允许 React createContext(null)?的主要内容,如果未能解决你的问题,请参考以下文章
允许typescript编译器仅在一个react状态属性上调用setState
react native 可以使用typescript开发吗