Connect ๐
Setup
First, let's create a file for defining the context (let's call it app-context.ts
):
import React from "react";
export interface ContextState {
name: string;
}
export interface ContextDispatch {
setName: React.Dispatch<React.SetStateAction<string>>;
}
type ContextProps = ContextState & ContextDispatch;
const defaultState: ContextState = {
name: "Hello",
};
const defaultDispatch: ContextDispatch = {
setName: () => {},
};
const defaultContext: ContextProps = {
...defaultState,
...defaultDispatch,
};
const AppContext = React.createContext<ContextProps>(defaultContext);
export default AppContext;
Now, let's create a file for the provider component (let's call it app-context-provider.tsx
):
"use client";
import React, { useState } from "react";
import AppContext, { ContextState, ContextDispatch } from "./appContext";
interface AppProviderProps {
children: React.ReactNode;
}
const AppProvider: React.FC<AppProviderProps> = ({ children }) => {
const [name, setName] = useState<string>("Hello");
const contextState: ContextState = {
name,
};
const contextDispatch: ContextDispatch = {
setName,
};
return (
<AppContext.Provider value={{ ...contextState, ...contextDispatch }}>
{children}
</AppContext.Provider>
);
};
export default AppProvider;
Finally, let's create a custom hook for using the context (you can put this in a separate file or in the index.ts
file):
import { useContext } from "react";
import AppContext from "./appContext";
export function useAppContext() {
return useContext(AppContext);
}
Now you can use it in your application like this:
Wrap your app or a part of it with the AppProvider
: layout.tsx
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={`${inter.className} bg`}>
<AppProvider>{children}</AppProvider>
</body>
</html>
);
}
Use the context in your components:
a-component.tsx
"use client";
import React from "react";
import { useAppContext } from "@/context";
const AComponent = () => {
const { setName } = useAppContext();
return (
<div>
<button
className="default-button"
onClick={() => {
setName("Subham Maity");
}}
>
Change The Name
</button>
</div>
);
};
export default AComponent;
b-component.tsx
"use client";
import React from "react";
import { useAppContext } from "@/context";
const BComponent = () => {
const { name } = useAppContext();
return (
<div>
<p>{name}</p>
</div>
);
};
export default BComponent;
This structure provides better type safety, separates concerns, and is more scalable. It's easier to add new state variables and update functions as your app grows.
ย