Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 在Typescript中对createContext问题作出反应?_Reactjs_Typescript_React Hooks_React Context - Fatal编程技术网

Reactjs 在Typescript中对createContext问题作出反应?

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

所以我对React-Context+Typescript有一个非常奇怪的问题

在上面的示例中,您可以看到我正在尝试做的实际工作。从本质上说,我使用新的useContext方法管理状态,它工作得非常好

但是,当我尝试在我的盒子上执行此操作时,它似乎找不到通过useReducer传递的状态值

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;