prosource

Typescript에서 createContext 문제를 해결하시겠습니까?

probook 2023. 4. 3. 21:36
반응형

Typescript에서 createContext 문제를 해결하시겠습니까?

React Context + Typescript에 매우 이상한 문제가 있습니다.

작업 예

위의 예에서는 실제로 무엇을 하려고 하는지 알 수 있습니다.기본적으로 새로운 use Context 메서드로 상태를 관리하고 있으며 완벽하게 작동합니다.

다만, 이것을 박스로 실행하려고 해도, 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>
   );
}

오류 메시지:

Type '{ state: { isAuth: boolean; user: string; }; dispatch: 
Dispatch<Actions>; }' is missing the following properties from type 
'IState': isAuth, user

지금 사용하고 있는 코드가 제 박스에서 사용하고 있는 것과 똑같습니다.샌드박스에서 코드를 다운로드하여 실행하려고 해도 동작하지 않습니다.

VSCode 1.31을 사용하고 있습니다.

콘텍스트를 작성하는 방법을 바꾸면 다음과 같이 추론할 수 있습니다.

export const AdminStore = React.createContext(initialState);

로.

export const AdminStore = React.createContext(null);

값 속성이 해당 오류를 발생시키지 않게 되었습니다.

그러나 현재 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);

Provider React 컴포넌트는 에러에 대해 불평하지 않게 됩니다.

다음은 변경 목록입니다.

admin-store.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>
  );
}

재밌는 시간을 보냈기 때문에 제가 생각해낸 것을 공유해야겠다고 생각했어요.

SidebarProps콘텍스트의 상태를 나타냅니다.환원 작용을 제외한 다른 모든 것은 본질적으로 그대로 사용될 수 있습니다.

다음은 완전히 동일한 회피책을 설명하는 좋은 기사입니다(TypeScript에는 없습니다). Hooks와 Context API의 혼합

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;

타이프스크립트가 날 제압할 때 내 속이 뒤집힌다.
이 경우, 저는 타입에 대해서는 전혀 신경 쓰지 않고, 다음과 같이 해결합니다.

다음은 정상적으로 동작합니다.

const ctx = createContext<any>({});

TS를 사용하지 않는 대부분의 예에서는 파라미터가 전혀 사용되지 않습니다.필요 이상의 코드를 추가하는 것은 의미가 없습니다.

언급URL : https://stackoverflow.com/questions/54577865/react-createcontext-issue-in-typescript

반응형