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)
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745406832a4626351.html
评论列表(0条)