我正在使用useContext和useReducer來管理應用程式狀態。
以下是片段:
//ReducerProvider.tsx
type ContextProviderType = {
state: StateInterface,
dispatch: React.Dispatch<ActionInterface>
}
type CreateContextType = ContextProviderType | string; // i am passing to the createContext either the ContextProviderType or a string (the string is just to initialize without errors since useReducer is not declared yet)
export const ReducerContext = React.createContext<CreateContextType>('');
interface ProviderProps {
children: ReactNode
}
export const ReducerProvider: React.FC<ProviderProps> = ({children}): JSX.Element => {
const [state, dispatch] = useReducer(reducer, initialState);
return <>
<ReducerContext.Provider value={{state, dispatch}}>
{children}
</ReducerContext.Provider>
</>
}
//App.tsx
const App: React.FC = (): JSX.Element => {
return <>
<ReducerProvider>
//components here so they can take the value of the provider component
</ReducerProvider>
</>;
}
僅當我嘗試獲取狀態和調度值時才會出現錯誤,如下所示:
//Component.tsx
export const Component: React.FC = (): JSX.Element => {
const { state, dispatch } = useContext(ReducerContext)
//ERROR: Property 'state' does not exist on type 'CreateContextType'
//ERROR: Property 'dispatch' does not exist on type 'CreateContextType'
return (
<div className="box">
//...
</div>
)
}
但是我不理解這個錯誤,因為我宣告 CreateContextType 可以是字串或 ContextProviderType,它是一個接收狀態和調度引數的物件。
uj5u.com熱心網友回復:
但我不理解這個錯誤,因為我宣告 CreateContextType 可以是字串或 ContextProviderType,
這正是您收到錯誤的原因:您說它可能是一個字串。如果它是一個字串,那么它就沒有stateanddispatch屬性。由于它可能沒有這些屬性,因此打字稿不會讓您訪問它們,除非您撰寫代碼以確保它們首先存在。
檢查字串可能如下所示:
let state;
let dispatch;
const value = useContext(ReducerContext);
if (typeof value === 'string') {
throw new Error('Uh oh, i got a string');
} else {
({ state, dispatch }) = value;
}
這顯然很麻煩,因此您可以將此檢查提取到自定義鉤子中:
export const useReducerContext = () => {
const value = useContext(ReducerContext);
if (typeof value === 'string') {
throw new Error("Don't forget to render a <ReducerProvider> higher up the tree")
}
return value;
}
// used like:
const { state, dispatch } = useReducerContext();
另一種選擇是更改 ReducerContext 上的型別,使其僅使用ContextProviderType,而不是string。這確實意味著您需要提供完整的默認值:
export const ReducerContext = React.createContext<ContextProviderType>({
state: {
// Fill out an entire fake state object here
},
dispatch: () => {}
});
制作一個永遠不會使用的默認值可能會很痛苦,因此您可以使用型別斷言來關閉打字稿:
export const ReducerContext = React.createContext<ContextProviderType>(
{} as ContextProviderType
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/481470.html
