【问题标题】:How to fix Property 'incrementCount' does not exist on type 'ContextType | undefined'如何修复类型'ContextType | 上不存在属性'incrementCount'不明确的'
【发布时间】:2021-04-12 00:14:09
【问题描述】:

我试图抽象 useContext 和 useReducer 的逻辑,以便在我创建新上下文时不重复代码,但是当我尝试使用 typescript 强类型 createContext 时遇到了一些问题。

使用此功能,我可以自动创建上下文:

import React, { createContext, ReactElement, useReducer } from 'react';

type ProviderProps = {
    children: ReactElement;
};

type ActionType = {
  type: string;
    payload?: any;
};

export default function <StateType>(
    reducer: (state: StateType, action: ActionType) => StateType,
    actions: any,
    initialState: StateType,
) {
    type ContextType = {
        state: StateType;
        actions:{
            [k: string]: Function;
        }
    };
    const Context = React.createContext<ContextType | undefined>(undefined);

    const Provider = ({ children }: ProviderProps) => {
        const [state, dispatch] = useReducer(reducer, initialState);

        const boundActions: any = {};

        for (let key in actions) {
            boundActions[key] = actions[key](dispatch);
        }
        return (
            <Context.Provider value={{ state, actions:{
                ...boundActions
            } }}>
                {children}
            </Context.Provider>
        );
    };

    return { Context, Provider };
}

上下文创建示例:

import createDataContext from './createDataContext';
import { INCRASE_COUNT, DECRASE_COUNT } from './ActionTypes';

type ActionType = {
    type: string;
    payload?: any;
};

type StateType = {
    count: number;
};

const reducer = (state: StateType, action: ActionType) => {
    switch (action.type) {
        case INCRASE_COUNT:
            return { count: state.count + 1 };
        case DECRASE_COUNT:
            return { count: state.count - 1 };
        default:
            return state;
    }
};

const incrementCount = (dispatch: React.Dispatch<any>) => {
    return () => {
        dispatch({ type: INCRASE_COUNT });
    };
};

const decrementCount = (dispatch: React.Dispatch<any>) => {
    return () => {
        dispatch({ type: DECRASE_COUNT });
    };
};

export const { Context, Provider } = createDataContext<StateType>(
    reducer,
    {
        incrementCount,
        decrementCount,
    },
    { count: 69 },
);

当我使用它时:

import { Context as ExampleContext } from '../context/ExampleContext';

const { state, actions } = useContext(
    ExampleContext,
);

它用红线强调状态和动作,并说: 'ContextType | 类型不存在属性'状态,操作'未定义'

我做错了什么,我错过了什么吗?

PLZZZZZZ 帮帮我。

【问题讨论】:

    标签: reactjs typescript react-native react-hooks react-typescript


    【解决方案1】:

    您收到错误,因为您将上下文类型指定为 ContextType | undefinedundefined 没有 stateactions 属性。 您可以像这样重构代码,而不是将 undefined 传递给 createContext

    export default function <StateType>(
        reducer: (state: StateType, action: ActionType) => StateType,
        actions: any,
        initialState: StateType,
    ) {
        type ContextType = {
            state: StateType;
            actions: typeof actions;
        };
        
        const Context = React.createContext<ContextType>({
          state: initialState,
          actions,
        });
        
        ...
    
        return { Context, Provider };
    }
    
    

    【讨论】:

    • 不,先生,这是行不通的,因为“状态”并不总是 { count: 0},它可以是任何东西,这就是为什么我将 StateType 作为泛型,因此状态类型可以是动态的跨度>
    • 那你为什么不通过initialState 而不是count: 0 呢?更正了我的答案,请检查一下。
    • 我试过了,它成功了 const Context = React.createContext({ state: initialState, actions, });非常感谢 THNX
    猜你喜欢
    • 2019-06-26
    • 1970-01-01
    • 2018-09-27
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 2019-11-11
    • 2021-11-12
    相关资源
    最近更新 更多