Typescript 不允许 React createContext(null)?

Nic*_*zyk 3 typescript reactjs react-hooks

我正在尝试使用 useReducer 和 useContext 挂钩设置 React 商店。React.createContext(defaultValue) 给我的 TS 检查器带来了问题。我尝试了一些不同的事情,但本质上,我createContext(null)然后在组件useReducer()中设置状态和调度,但是当我调用 Provider 并将值作为 {state, dispatch} 传递时,它没有告诉我“Type '{ state : any; 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;
}
Run Code Online (Sandbox Code Playgroud)

如果我将它保留为 simple const StoreContext = createContext();,那么它会抱怨 defaultValue 没有被定义。

疯狂的是我已经从一个旧项目中解除了这个并且编译没有问题。

eri*_*ock 33

在这种情况下,为了省去麻烦,可以暂时施放它:

interface Store {
  state: MyStateType,
  dispatch: Dispatch,
}

const StoreContext = createContext<Store>({} as Store);

const StoreProvider = ({children}) => {
  const {state, dispatch} = theseAreAlwaysPresent()

  return (
    <StoreContext.Provider value={{state, dispatch}}>
      {children}
    </StoreContext.Provider>
  )
}
... 

Run Code Online (Sandbox Code Playgroud)


小智 11

由于我刚刚注册了一个帐户来回答这个问题,所以我无法发表评论。Alex Wayne 是正确的,Typescript 可以接受。然而,useContext这个钩子并不能真正起作用,因为就 Typescript 而言,你可能null在该 Context 中拥有一个值。

从原来的答案...这是我们在打字稿中的上下文 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;
}
Run Code Online (Sandbox Code Playgroud)

使用这个钩子代替useContext,它应该一切正常。


Ale*_*yne 5

当您使用 初始化上下文时null,无法推断出预期的类型。在这种情况下,您必须明确给出上下文的类型。

在这里看起来像:

const StoreContext = createContext<{
  state: MyStateType,
  dispatch: Dispact,
} | null>(null);
Run Code Online (Sandbox Code Playgroud)

  • 我已经尝试过了。当我声明类型时,我让它工作,但随后在消费者(我调用 useContext )中,我收到以下错误:`Argument of type 'Context&lt;MyContextType | null&gt;' 不可分配给类型为 'Context&lt;MyContextType&gt;' 的参数。` 我为“MyContextType”创建了一个接口,如下所示: `export interface MyContextType { state: State; 调度:调度&lt;任意&gt;;}`。这是消费者中的上下文回调:`const ctx = useContext&lt;MyContextType&gt;(StoreContext)` (4认同)