Typescript 的 React useContext 问题——<Partial> 的任何替代方案?

React useContext problem with Typescript -- any alternative to <Partial>?

我有一个使用 useContext 的 React 应用程序,但我无法根据我的上下文正确输入内容。这是我拥有的:

import React, { useState, createContext } from 'react';
import endpoints from '../components/endpoints/endpoints';

interface contextTypes {
    endpointQuery: string,
    setEndpointQuery: React.Dispatch<React.SetStateAction<string>>,
    searchInput: string,
    setSearchInput: React.Dispatch<React.SetStateAction<string>>,
    filmSearch: string | undefined,
    setFilmSearch: React.Dispatch<React.SetStateAction<string>>
    pageIndex: number,
    setPageIndex: React.Dispatch<React.SetStateAction<number>>,
    resetState: () => void;
}

export const DisplayContext = createContext<Partial<contextTypes>>({});

interface Props {
    children: React.ReactNode;
}

const DisplayContextProvider = (props: Props) => {
    const { nowShowing } = endpoints;
    const [ endpointQuery, setEndpointQuery ] = useState(nowShowing);
    const [ searchInput, setSearchInput ] = useState('');
    const [ filmSearch, setFilmSearch ] = useState('');
    const [ pageIndex, setPageIndex ] = useState(1);

    const resetState = () => {
        setSearchInput('');
        setFilmSearch('');
        setPageIndex(1);
    };

    const values = {
        endpointQuery,
        setEndpointQuery,
        pageIndex,
        setPageIndex,
        filmSearch,
        setFilmSearch,
        searchInput,
        setSearchInput,
        resetState
    };
    
    return (
        <DisplayContext.Provider value={values}>
            {props.children}
        </DisplayContext.Provider>
    );
};

export default DisplayContextProvider;

问题是,当我使用 <Partial<contextTypes>> 时,我的整个应用程序都收到此错误:

Cannot invoke an object which is possibly 'undefined'

有没有办法解决这个问题,这样我就不必在出现未定义错误的所有地方都添加 ! 标记? (我对 Typescript 也很陌生,所以我完全有可能以完全错误的方式输入我的上下文)

我认为问题在于您无法使用有用的默认值初始化上下文,但您希望上下文提供程序在组件树中始终处于较高位置。

当我处于这种情况时,我想要以下行为:

  • 如果组件尝试使用上下文,但未在其上方使用提供程序,则抛出错误
  • 使用上下文的组件应该假设上下文已经设置。

所以,我通常会创建一个钩子来包装 useContext 并为我进行 null 检查。

import React, { useContext, createContext } from 'react';

interface contextTypes {
    // ...
}

// private to this file
const DisplayContext = createContext<contextTypes | null>(null);

// Used by any component that needs the value, it returns a non-nullable contextTypes
export function useDisplay() {
  const display = useContext(DisplayContext);
  if (display == null) {
    throw Error("useDisplay requires DisplayProvider to be used higher in the component tree");
  }
  return display;
}

// Used to set the value. The cast is so the caller cannot set it to null,
// because I don't expect them ever to do that.
export const DisplayProvider: React.Provider<contextTypes> = DisplayContext.Provider as any;

如果在组件树中没有 DisplayProvider 更高级别的组件中使用 useDisplay,它将抛出错误并且组件不会挂载。