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
,它将抛出错误并且组件不会挂载。
我有一个使用 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
,它将抛出错误并且组件不会挂载。