Context
Framework Next.js 13 Data Sharing: Context
Categories:
Next.js 13 Context API
After Next.js 13
, the js components
are ALL treated as the server-side component by default
.
So if you want to use the client-side function such as createContext
, useContext
, useState
that you have to write 'use client';
on the top of the file to tell the Next.js 13
that this component is the client-side component
1. Create Global Context Store File
Write the 'use client';
on the top of the context file to tell the Next.js 13
that this component is the client-side component
// app/Context/GlobalContext.tsx
'use client';
import { createContext, useContext, Dispatch, SetStateAction, useState } from "react";
type DataType = {
firstName: string
}
interface ContextProps {
userId: string,
setUserId: Dispatch<SetStateAction<string>>,
data: DataType[],
setData: Dispatch<SetStateAction<DataType[]>>
}
const GlobalContext = createContext<ContextProps>({
userId: '',
setUserId: (): string => '',
data: [],
setData: (): DataType[] => []
})
export const GlobalContextProvider = ({ children }) => {
const [userId, setUserId] = useState('');
const [data, setData] = useState<[] | DataType[]>([]);
return (
<GlobalContext.Provider value={{ userId, setUserId, data, setData }}>
{children}
</GlobalContext.Provider>
)
};
export const useGlobalContext = () => useContext(GlobalContext);
2. Add Global Context to the app/layout.tsx
Because app/layout.tsx
is the server-side component by default
so you CAN NOT use the client-side function in the app/layout.tsx
But it can import
the client-side context component then use it.
// app/layout.tsx
import './globals.css';
import { GlobalContextProvider } from './Context/GlobalContext';
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
{/*
<head /> will contain the components returned by the nearest parent
head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
*/}
<head />
<body>
<GlobalContextProvider>
{children}
</GlobalContextProvider>
</body>
</html>
)
}
3. Use Global Context on the app/page.tsx
Now we can use the context on the children client-side component
// app/page.tsx
'use client';
import { useEffect } from 'react';
import { useGlobalContext } from './Context/GlobalContext';
import styles from './page.module.css';
export default function Home() {
const { userId, setUserId, data, setData } = useGlobalContext();
useEffect(() => {
setUserId('2');
setData([
{ firstName: 'Tim' },
{ firstName: 'Kyle' },
{ firstName: 'Michael' }
]);
}, [])
return (
<div className={styles.container}>
<p>{userId}</p>
<p>List:</p>
{data.map((e, i) => <p key={i}>{e.firstName}</p>)}
</div>
)
}