I am trying do use context with React hook with typescript. I have no idea where did I do wrong.
export interface IPayload {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}
export interface ModeContextType {
menuInfo: IPayload;
modeData: IPayload;
currentModeCode: number;
setCurrentModeCode: (arg0: string) => void;
}
export const ModeContext = createContext<ModeContextType | undefined>(undefined);
const modeContextValue = {
menuInfo: menuInfo,
modeData: modeData,
currentModeCode: currentModeCode,
setCurrentModeCode: setCurrentModeCode,
};
return (
<>
<ModeContext.Provider value={modeContextValue}>
<Header currentModeCode={currentModeCode} />
<div className="thumbnail-block" ref={thumbnailBlock}>
{listOfThumbnails}
</div>
<div id="detail-set-block">
<DetailCampaign key={currentCampaignCode} info={currentCampaign} />
</div>
<div className="clearfix">
<button id="see-all" type="button" className="btn btn-dark">
{t("top.see_all_product_at_this_fair")}
</button>
</div>
<Category />
</ModeContext.Provider>
</>
);
In the child component, I use useContext
as follow
function Category(): JSX.Element {
const { menuInfo, modeData, currentModeCode, setCurrentModeCode } = useContext(ModeContext);
the error is
Property 'menuInfo' does not exist on type 'ModeContextType | undefined'. TS2339
6 |
7 | function Category(): JSX.Element {
> 8 | const { menuInfo, modeData, currentModeCode, setCurrentModeCode } = useContext(ModeContext);
| ^
9 | // const modeData = getMode(menuInfo);
10 | const listOfModes = Object.entries(modeData).map(([modeCode, modeInfo]) => {
11 | return (
CodePudding user response:
You've typed your context as ModeContextType | undefined
, and it has a default value of undefined
. Which means that you can't assume that the properties that you are destructuring actually exist.
The error you're getting is because menuInfo
does not exist on all members of that union type, because of those members is undefined
.
So you may need to do something like:
const modeContextValue = useContext(ModeContext);
if (modeContextValue) {
{ menuInfo, modeData, currentModeCode, setCurrentModeCode } = modeContextValue
// other code that can run when modeContextValue has a value.
}
Or perhaps remove undefined
from the context type and provide a full set of defaults:
export const ModeContext = createContext<ModeContextType>({
menuInfo: {},
modeData: {},
currentModeCode: 0,
setCurrentModeCode: () => undefined,
});