admin管理员组文章数量:1425245
I'm following a React tutorial on youtube where I'm trying to convert the Project from JavaScript to TypeScript, and I'm having a lot of trouble with the useContext, I would appreciate it if someone were to help me here. If you're wondering which tutorial here it is Tutorial
import React, {createContext, useContext, useState } from 'react';
const StateContext = createContext();
export const ContextProvider = ({ children }) => {
const [activeMenu, setActiveMenu] = useState(true);
return (
<StateContext.Provider value={{activeMenu, setActiveMenu}}>
{children}
</StateContext.Provider>
)
}
export const useStateContext = () => useContext(StateContext)
I'm following a React tutorial on youtube where I'm trying to convert the Project from JavaScript to TypeScript, and I'm having a lot of trouble with the useContext, I would appreciate it if someone were to help me here. If you're wondering which tutorial here it is Tutorial
import React, {createContext, useContext, useState } from 'react';
const StateContext = createContext();
export const ContextProvider = ({ children }) => {
const [activeMenu, setActiveMenu] = useState(true);
return (
<StateContext.Provider value={{activeMenu, setActiveMenu}}>
{children}
</StateContext.Provider>
)
}
export const useStateContext = () => useContext(StateContext)
Share
Improve this question
asked Oct 23, 2022 at 18:20
BardyliBardyli
651 silver badge5 bronze badges
3
- What is the problem exactly? – Konrad Commented Oct 23, 2022 at 18:22
- Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Bot Commented Oct 23, 2022 at 18:45
- From the question, it is not clear where the problem is. So please edit your question to have the solution. – shiblee saidul Commented Oct 23, 2022 at 19:03
2 Answers
Reset to default 5There are 3 options I've seen in the wild.
Option 1
This option is a bit annoying because the type of StateContext value can be null | StateContextType
. But in the code you provided, it will only be null
on creation and not null inside the provider. Regardless, everywhere you use useContext
you'll have to have a guard against null
.
import React, { createContext, useState } from 'react';
type StateContextType = {
activeMenu: boolean;
setActiveMenu: React.Dispatch<React.SetStateAction<boolean>>;
};
export const StateContext = createContext<null | StateContextType>(null);
type ContextProviderProps = {
children: React.ReactNode;
};
export const ContextProvider = ({ children }: ContextProviderProps) => {
const [activeMenu, setActiveMenu] = useState(true);
const value = {
activeMenu,
setActiveMenu,
};
return (
<StateContext.Provider value={value}>{children}</StateContext.Provider>
);
};
Option 2
With this option, you cast StateContext value type to StateContextType. It means that the value of StateContext is assumed to be StateContextType. The only downside is that the value of StateContext is null
for a very small amount of time at creation, before a value is provided in StateContext.Provider.
However, it's relatively safe since you're immediately passing a value in the provider.
import React, { createContext, useState } from 'react';
type StateContextType = {
activeMenu: boolean;
setActiveMenu: React.Dispatch<React.SetStateAction<boolean>>;
};
export const StateContext = createContext<StateContextType>(
null as unknown as StateContextType,
);
type ContextProviderProps = {
children: React.ReactNode;
};
export const ContextProvider = ({ children }: ContextProviderProps) => {
const [activeMenu, setActiveMenu] = useState(true);
const value = {
activeMenu,
setActiveMenu,
};
return (
<StateContext.Provider value={value}>{children}</StateContext.Provider>
);
};
Option 3
Credit to Steve Kinney's course on Frontend Masters on React and TypeScript for this one.
import React, { useState } from 'react';
export function createContext<T>() {
const context = React.createContext<T | undefined>(undefined);
const useContext = () => {
const value = React.useContext(context);
if (value === undefined) {
throw new Error(
`useContext must be used inside a Provider with a value that's not undefined`,
);
}
return value;
};
return [useContext, context.Provider] as const;
}
type StateContextType = {
activeMenu: boolean;
setActiveMenu: React.Dispatch<React.SetStateAction<boolean>>;
};
export const [useContext, Provider] = createContext<StateContextType>();
type ContextProviderProps = {
children: React.ReactNode;
};
export const ContextProvider = ({ children }: ContextProviderProps) => {
const [activeMenu, setActiveMenu] = useState(true);
const value = {
activeMenu,
setActiveMenu,
};
return <Provider value={value}>{children}</Provider>;
};
const Component = () => {
// usage inside ponent
const context = useContext();
return <div></div>;
};
export const App = () => {
return (
<ContextProvider>
<Component />
</ContextProvider>
);
};
change this:
import React, {createContext, useContext, useState } from 'react';
const StateContext = createContext();
export const ContextProvider = ({ children }) => {
const [activeMenu, setActiveMenu] = useState(true);
return (
<StateContext.Provider value={{activeMenu, setActiveMenu}}>
{children}
</StateContext.Provider>
)
}
export const useStateContext = () => useContext(StateContext)
to this:
import React, {createContext, useContext,
useState } from 'react';
interface Props {
children : ReactNode
}
const StateContext = createContext();
export const ContextProvider = ({ children }:Props) => {
const [activeMenu, setActiveMenu] = useState(true);
return (
<StateContext.Provider value={{activeMenu, setActiveMenu}}>
{children}
</StateContext.Provider>
)
}
export const useStateContext = () => useContext(StateContext)
本文标签: javascriptTypeScript on useContextStack Overflow
版权声明:本文标题:javascript - TypeScript on useContext - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745406831a2657287.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论