How to write context API with TypeScript and next.JS
Why we need context?
In a typical React application, data is passed top-down (parent to child) via props, but such usage can be cumbersome for certain types of props (e.g. locale preference, UI theme) that are required by many components within an application. Context provides a way to share values like these between components without having to explicitly pass a prop through every level of the tree. read more
What is contextAPI?
Context provides a way to pass data through the component tree without having to pass props down manually at every level.
So, now we know why we need context and what is context let's dive into the coding part.
Before starting, set up a basic version of the nextJS app with typescript
npx create-next-app context-api
npm install --save-dev typescript @types/react
Create a folder called context, here we will store all the different contexts. For now, create an AuthContext.tsx file
Step 1:- Create context type
Inside AuthContext.tsx.
As we are using TypeScript we have to create types for our context
type authContextType = {
user: boolean;
login: () => void;
logout: () => void;
};
Step 2:- Create context default values
const authContextDefaultValues: authContextType = {
user: null,
login: () => {},
logout: () => {},
};
Step 3:- createContext & useContext
const AuthContext = createContext<authContextType>(authContextDefaultValues);
export function useAuth() {
return useContext(AuthContext);
}
Step 4:- Create a provider function
type Props = {
children: ReactNode;
};
export function AuthProvider({ children }: Props) {
const value = {
}
return (
<>
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
</>
);
}
We will wrap this AuthProvider function, where we want to use our context, and the value prop will have the values of authContextType. We will fill up values in the next step.
Step 4:- Fill up values
export function AuthProvider({ children }: Props) {
const [user, setUser] = useState<boolean>(null);
const login = () => {
setUser(true);
};
const logout = () => {
setUser(false);
};
const value = {
user,
login,
logout,
};
return (
...
Now our context is ready to use.
Step 5:- Enable AuthProvider
First, we have to enable AuthProvider, to do so edit the default _app.js file like so
import { AuthProvider } from "../context/AuthContext";
import "../styles/globals.css";
function MyApp({ Component, pageProps }) {
return (
<>
<AuthProvider>
<Component {...pageProps} />
</AuthProvider>
</>
);
}
export default MyApp;
Step 6:- Using context
Now remove all the template nextJS generate and simply import the context
import Head from "next/head";
import styles from "../styles/Home.module.css";
import { useAuth } from "../context/AuthContext";
export default function Home() {
const { user, login, logout } = useAuth();
return (
<div className={styles.container}>
<Head>
<title>Context-api with TypeScript and nextJS</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<div>
<h1>Hello Context</h1>
<h2>User: {user ? "login" : "logout"}</h2>
<div>
<button onClick={login}>Login</button>
<button onClick={logout}>Logout</button>
</div>
</div>
</main>
</div>
);
}
Okay many things happen here let me break it down, first we import the context hook "useAuth" then inside our Home() we destructure all the values from "useAuth" then we use it as per our requirement.
Top comments (19)
A very informative article.
But having one doubt of how context persists across different pages since NextJs does not act as a SPA?
As long as the provider is wrapped in the MyApp function in _app.tsx, it basically is available across pages. The provider is basically the parent of all components including all next.js pages in the way it is specified in _app.tsx file.
I am not sure but I think NextJS handles it under the hood, I have used context in NextJS projects and It was persists across different pages.
Hi. Good day. I went through your article and it was very infomative and got me started on using context in next js and typescript. I encountered an error while setting up. Please would you help me look at it to know what i did wrong.
This is the error i am getting when assigning value in the provider
Type '(ContextType | Dispatch>)[]' is missing the following properties from type 'ContextType': currentPage, numberofItemstoDisplayts(2739)
index.d.ts(331, 9): The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & ProviderProps'
I would be helpful if you send a repo that have this issue so that I can look into it.
unfortunately it is a work repo so it is private. Please is there another way i can send it to you. Do you mind having a google meet call with me?
Okay. Let's connect on LinkedIn. My LinkedIn profile
Well articulated and helped me getting started with Typescript, NextJS and React Context API. Keep it up brother.
Nice to hear it.😄
Follow for new blogs!
Hi Nadeem,
My name is Liady fouad and I'm a junior front end developer from Italy. So I'm building a web app with Next 13, Firebase and Open Ai API.This is actually my first project on Next js. I was using Next auth to get data and encounter some problems retrieving the UID. So i switch to firebaseAuth but got blocked there also. I read your article about how to authenticate with with google and Next js and found it very interesting .
So i have several problems with my project:I want to get the UID first and i want to integrate stripe to get subscription plans.
I was wondering if you can take a look at my code and help me out with these problems. I can pay 5$ to 10$ per hour.
Please let me know if you’re interested(I really need help🤗).
Thanks again
How do you pass properties to the logout methods?
As we are using typescript first set the type of arguments
then pass make use of your properties
And finally pass it to the function, where you are using it.
It was informative.
Thanks
Glad it helps ☺️
Great!
Thanks! 😇
This is an excellent article.
thanks a lot but If we have a lot of context files
put all of them in myApp file?
Many thanks