Typescript不允许ReactcreateContext(null)?

5t7ly7z5  于 2022-11-26  发布在  TypeScript
关注(0)|答案(4)|浏览(181)

我正在尝试使用useReducer和useContext挂钩设置React存储。React.createContext(defaultValue)在TS检查器中产生问题。我尝试了一些不同的方法,但本质上,我在组件useReducer()createContext(null)设置状态和分派,但当我调用Provider并将值传递为{state,dispatch}时,它并不告诉我“Type '{ state:任何;发送:React调度;“}"不能赋给类型”null.“
我不明白这一点,因为当它出错时,我已经分配了state和dispatch,值应该不再为null。
下面是我尝试创建的上下文提供程序 Package 器。

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没有被定义。
疯狂的是,我已经从一个旧项目中提取了这个,并且没有编译问题。

gr8qqesn

gr8qqesn1#

在这种情况下,可以临时强制执行该操作,以保存麻烦:

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>
  )
}
...
z9ju0rcb

z9ju0rcb2#

因为我刚刚做了一个账户来回答这个问题,所以我不能在上面发表评论。Alex韦恩是正确的,这对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,它应该都能很好地工作。

u3r8eeie

u3r8eeie3#

当你用null初始化一个上下文时,不能推断出想要的类型。在这种情况下,你必须显式地给予上下文的类型。
在这里,它看起来像这样:

const StoreContext = createContext<{
  state: MyStateType,
  dispatch: Dispact,
} | null>(null);
vwkv1x7d

vwkv1x7d4#

//So basically in my case you just have to assign an empty object that 
   will solve your problem.

 import React, { createContext, useReducer, FC, Dispatch } from 'react';
 import storeReducer, { initialState } from './reducer';
 import { Action, State } from './types';
 import { isNull } from 'util';

 // replaced null with {}
 // because assigning a value and any type of parameter will not be 
    acceptable in typescript
 const StoreContext = createContext({});

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;
}

相关问题