Reactjs 在Typescript中对createContext问题作出反应?
所以我对React-Context+Typescript有一个非常奇怪的问题 在上面的示例中,您可以看到我正在尝试做的实际工作。从本质上说,我使用新的useContext方法管理状态,它工作得非常好 但是,当我尝试在我的盒子上执行此操作时,它似乎找不到通过useReducer传递的状态值Reactjs 在Typescript中对createContext问题作出反应?,reactjs,typescript,react-hooks,react-context,Reactjs,Typescript,React Hooks,React Context,所以我对React-Context+Typescript有一个非常奇怪的问题 在上面的示例中,您可以看到我正在尝试做的实际工作。从本质上说,我使用新的useContext方法管理状态,它工作得非常好 但是,当我尝试在我的盒子上执行此操作时,它似乎找不到通过useReducer传递的状态值 export function AdminStoreProvider(props: any) { const [state, dispatch] = useReducer(reducer, initialSt
export function AdminStoreProvider(props: any) {
const [state, dispatch] = useReducer(reducer, initialState);
// state.isAuth is avail here
// state.user is avail here
const value = { state, dispatch };
// value.state.isAuth is avail here
return (
/* value does not contain state once applied to the value prop */
<AdminStore.Provider value={value}>{props.children}
</AdminStore.Provider>
);
}
到
value属性不再抛出该错误
但是,现在useContext返回一个错误:null上不存在状态。如果我将上下文的defaultState设置为{},也是一样的
当然如果我
React.createContext();
然后TS大喊没有提供defaultValue
在沙盒中,创建上下文对象的所有3个版本都可以正常工作
提前感谢您的建议。显示的
defaultValue
的值应为以下类型:
interface IContextProps {
state: IState;
dispatch: ({type}:{type:string}) => void;
}
一旦为该类型创建了Context
对象,例如:
export const AdminStore = React.createContext({} as IContextProps);
提供程序React组件不应再抱怨此错误
以下是更改列表:
管理商店.tsx
import React, { useReducer } from "react";
import { initialState, IState, reducer } from "./reducer";
interface IContextProps {
state: IState;
dispatch: ({type}:{type:string}) => void;
}
export const AdminStore = React.createContext({} as IContextProps);
export function AdminStoreProvider(props: any) {
const [state, dispatch] = useReducer(reducer, initialState);
const value = { state, dispatch };
return (
<AdminStore.Provider value={value}>{props.children}</AdminStore.Provider>
);
}
import React,{useReducer}来自“React”;
从“/reducer”导入{initialState,IState,reducer};
接口IContextProps{
国家:巴基斯坦;
分派:({type}:{type:string})=>void;
}
export const AdminStore=React.createContext({}作为IContextProps);
导出函数AdminStoreProvider(道具:任意){
const[state,dispatch]=useReducer(reducer,initialState);
常量值={state,dispatch};
返回(
{props.children}
);
}
我玩得很开心,所以我想分享一下我的想法
SidebarProps
表示上下文的状态。除减速器动作外,其他所有动作基本上都可以按原样使用
下面是一篇很好的文章,解释了完全相同的解决方法(不是在TypeScript中):
import React,{createContext,Dispatch,Reducer,useContext,useReducer}来自“React”;
接口动作{
类型:字符串;
价值:任何;
}
界面边栏道具{
显示:布尔;
内容:JSX.Element | null;
}
接口侧栏ProviderProps{
减速器:减速器;
initState:SidebarProps;
}
接口InitContextProps{
状态:侧边栏道具;
调度:调度;
}
export const SidebarContext=createContext({}作为InitContextProps);
export const SidebarProvider:React.FC=({reducer,initState,children})=>{
const[state,dispatch]=useReducer(reducer,initState);
常量值={state,dispatch};
返回(
{儿童}
);
};
export const useSidebar=()=>useContext(SidebarContext);
const SidebarController:React.FC=({children})=>{
const initState:SidebarProps={
秀:假,,
内容:空
};
const reducer:reducer=(状态、操作)=>{
开关(动作类型){
案例“setShow”:
返回{
……国家,
表演:动作。价值
};
案例“setContent”:
返回{
……国家,
内容:action.value
};
违约:
返回状态;
}
};
返回(
{儿童}
);
};
导出默认边栏控制器;
谢谢,这确实删除了错误,但现在它出现了错误:类型“{state:{isAuth:boolean;user:string;};dispatch:dispatch;}”不可分配给类型“IContextProps”。属性“dispatch”的类型不兼容。类型“Dispatch”不可分配给类型“({Type}:{Type:string;})=>void”。参数“value”和“0”的类型不兼容。类型“{Type:string;}”不可分配给类型“Actions”。类型“{type:string;}”中缺少属性“value”,但类型“ILogout”中需要属性“value”
这是我的最新版本:它现在实际编译,但在浏览器中崩溃:导出函数AdminStoreProvider(props:any){
说“TypeError:对象(…)不是函数”旁注,一旦我从react导入分派,然后导出并导入操作,我的主要问题就解决了,出现了警告和错误。interface IContextProps{state:IState;Dispatch:Dispatch;}
是我的最后一个界面,它对我不起作用。我得到了错误:禁止对对象文本进行类型断言,请改用类型注释。
@bauervision是答案,因为它已经完成,或者有人需要从您的评论中添加代码(2月14日19:38)为了使其工作?如果是,请您相应地更新答案,以便接受的答案包含正确的代码?
interface IContextProps {
state: IState;
dispatch: ({type}:{type:string}) => void;
}
export const AdminStore = React.createContext({} as IContextProps);
import React, { useReducer } from "react";
import { initialState, IState, reducer } from "./reducer";
interface IContextProps {
state: IState;
dispatch: ({type}:{type:string}) => void;
}
export const AdminStore = React.createContext({} as IContextProps);
export function AdminStoreProvider(props: any) {
const [state, dispatch] = useReducer(reducer, initialState);
const value = { state, dispatch };
return (
<AdminStore.Provider value={value}>{props.children}</AdminStore.Provider>
);
}
import React, { createContext, Dispatch, Reducer, useContext, useReducer } from 'react';
interface Actions {
type: string;
value: any;
}
interface SidebarProps {
show: boolean;
content: JSX.Element | null;
}
interface SidebarProviderProps {
reducer: Reducer<SidebarProps, Actions>;
initState: SidebarProps;
}
interface InitContextProps {
state: SidebarProps;
dispatch: Dispatch<Actions>;
}
export const SidebarContext = createContext({} as InitContextProps);
export const SidebarProvider: React.FC<SidebarProviderProps> = ({ reducer, initState, children }) => {
const [state, dispatch] = useReducer(reducer, initState);
const value = { state, dispatch };
return (
<SidebarContext.Provider value={value}>
{children}
</SidebarContext.Provider>
);
};
export const useSidebar = () => useContext(SidebarContext);
const SidebarController: React.FC = ({ children }) => {
const initState: SidebarProps = {
show: false,
content: null
};
const reducer: Reducer<SidebarProps, Actions> = (state, action) => {
switch (action.type) {
case 'setShow':
return {
...state,
show: action.value
};
case 'setContent':
return {
...state,
content: action.value
};
default:
return state;
}
};
return (
<SidebarProvider reducer={reducer} initState={initState}>
{children}
</SidebarProvider>
);
};
export default SidebarController;