Context API mystery
Answered
Barbary Lion posted this in #help-forum
Barbary LionOP
Hello. I am learning react/nextjs, and it's hard for me to understand how to use Context API. So tutorials I have watched, makes a provider, wraps children with it and then children can access it. Something Like this:
[I am working with default project]. So as I can understand, the page.tsx is in that childrens list. Because it gets loaded instantly from root url. Everything's fine here. But if I create another page in for example pages/auth folder, how they should get access to that provider? They won't be children of this provider. Or I am not getting something. If you have any wisdom you think would help me, please share, I want to know more, because it's kind of a mystery for me right now. (Coming from .NET/C# background)
Or if you can maybe give me an example how I could make another page set/get data from this provider, it would be highly appreciated.
P.S. I also got error when using context in a layout page, so I added "use client". Is this a normal solution? I just followed what the error said.
+ Yes, I know NextAuth exist, in case you want to inform me about that when you saw that I wrote "pages/auth" in my example, right now I just want to learn how to use context API.
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={openSans.className}>
<UserContext.Provider value={'Hello from Context Provider!'}>
{children}
</UserContext.Provider>
</body>
</html>
)
}[I am working with default project]. So as I can understand, the page.tsx is in that childrens list. Because it gets loaded instantly from root url. Everything's fine here. But if I create another page in for example pages/auth folder, how they should get access to that provider? They won't be children of this provider. Or I am not getting something. If you have any wisdom you think would help me, please share, I want to know more, because it's kind of a mystery for me right now. (Coming from .NET/C# background)
Or if you can maybe give me an example how I could make another page set/get data from this provider, it would be highly appreciated.
P.S. I also got error when using context in a layout page, so I added "use client". Is this a normal solution? I just followed what the error said.
+ Yes, I know NextAuth exist, in case you want to inform me about that when you saw that I wrote "pages/auth" in my example, right now I just want to learn how to use context API.
37 Replies
Asian black bear
Everything is wrapped in the root layout, all of the descendent pages.
Just export
UserContext from wherever you create it, and you can import it and do useContext(UserContext) anywhere@Asian black bear Everything is wrapped in the root layout, all of the descendent pages.
Barbary LionOP
I have tried to do just that, and I don't get the expected results.
My page.tsx:
Everything works fine in it.
My other page:
And I don't get the 'Hello From Context Provider!' in the second (Login) page.
My page.tsx:
"use client";
import { UserContext } from "@/components/auth/UserProvider"
import { useContext } from "react"
export default function Home() {
const msg = useContext(UserContext);
return (
<main className="flex min-h-screen flex-col items-center justify-center">
<h1>Hello World!</h1>
<h2>{msg}</h2>
</main>
)
}Everything works fine in it.
My other page:
import { UserContext } from '@/components/auth/UserProvider';
import React, { useContext } from 'react'
import 'tailwindcss/tailwind.css';
function Login() {
const msg = useContext(UserContext);
return (
<main className="flex min-h-screen flex-col items-center justify-center">
<p className="text-3xl">automotive.</p>
<form className="flex flex-col mt-16 w-64">
<input placeholder="Email" id="email" type="email" name="name" autoComplete="email" required
className="rounded-md text-xs bg-gray-50" />
<input placeholder="Password" id="password" type="password" name="password" required
className="rounded-md mt-4 text-xs bg-gray-50"/>
<div className="flex justify-center">
<input type="submit" value="Login"
className="mt-4 bg-[#363636] text-white rounded-md justify-center py-2 px-6 text-xs"/>
</div>
</form>
<br/>
<div className='flex flex-row justify-center'>
<p className='text-gray-500 text-sm'>Don't have an account?</p>
<a href='register' className='pl-1 text-gray-800 text-sm'>Register</a>
</div>
<h2>{msg}</h2>
</main>
)
}
export default LoginAnd I don't get the 'Hello From Context Provider!' in the second (Login) page.
Asian black bear
Where are you wrapping with the provider?
@Asian black bear Where are you wrapping with the provider?
Barbary LionOP
In the layout.tsx:
"use client";
import './globals.css'
import { Inter, Open_Sans } from 'next/font/google'
import { UserContext } from '@/components/auth/UserProvider';
const inter = Inter({ subsets: ['latin'] })
const openSans = Open_Sans({subsets: ['latin']})
export const metadata = {
title: 'title',
description: 'description',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={openSans.className}>
<UserContext.Provider value={'Hello From Context Provider!'}>
{children}
</UserContext.Provider>
</body>
</html>
)
}my context code:
import { createContext } from "react";
export const UserContext = createContext('')@Barbary Lion can you share your route structure?
Asian black bear
That looks right. The only thing I can think is if you are using a route group or something and opting out of the root layout? Not sure if that is even possible though
@alfon <@133350111504891904> can you share your route structure?
Barbary LionOP
Sorry for a newbie answer, but where do I find it/what exactly is it? You mean folder structure, because as far as I know, you can get to specific page, by using specific url, like localhost:3000/auth/login? Its considered a route? I am using default template, that I got by using
npx create-next-app@latest --tailwind if I can remember correctly and if this information helps.@alfon folder structure
Barbary LionOP
oh no
why do you have
pages dir inside your app dir 💀@Asian black bear That looks right. The only thing I can think is if you are using a route group or something and opting out of the root layout? Not sure if that is even possible though
Barbary LionOP
I can't tell you that, because I don't know what a route group is. I just created two new pages and that's it
@alfon why do you have `pages` dir inside your `app` dir 💀
Barbary LionOP
It's supposed to be outside? Sht, I might messed up here
@Barbary Lion It's supposed to be outside? Sht, I might messed up here
its not supposed to exist at the same time...
Answer
pick one for the betterment of your learning experience
app dir or pages dirAsian black bear
ohh, yeah they definitely don't share the context!
@alfon its not supposed to exist at the same time...
they can coexist at the same time
but ofc one cannot be inside the other
app/pages will be the route /pages/... and pages/app will be the route /app/...they can but i think it'll just confuse you 💀
Asian black bear
@joulev is there a place to put a common wrapping element between
/pages and /app?Barbary LionOP
Ohhh... That's confusing 😠I created a new project and already got the app dir, but I see in the tutorials that people are using pages folder, so I assumed I need it too. Routes were working correctly, so I thought everything is correct
@Barbary Lion Ohhh... That's confusing 😠I created a new project and already got the app dir, but I see in the tutorials that people are using pages folder, so I assumed I need it too. Routes were working correctly, so I thought everything is correct
pages dir is what happen if you don't select the
use App Router? option@Asian black bear <@484037068239142956> is there a place to put a common wrapping element between `/pages` and `/app`?
/app: root layout/pages: _app.tsxthey are two different react apps rendered and working independently so there is no unified place to do it
@joulev `/app`: root layout
`/pages`: _app.tsx
they are two different react apps rendered and working independently so there is no unified place to do it
Asian black bear
I assumed that, but it is excellent to know for sure
each root layout is a separate react root,
_app is also a separate react root. navigating between them requires a full reloadAsian black bear
that is a major disadvantage of mixing /app and /pages for sure
Barbary LionOP
Okayyyy. Now it's getting clearer, why I see differences on the internet. I will now know what to google - the app router. Maybe you can summarize which option is better or when to use one or another? Or how to use the provider in my case? I assume I am not using the app router
Asian black bear
For learning contexts API, they are both very similar.
@Barbary Lion Okayyyy. Now it's getting clearer, why I see differences on the internet. I will now know what to google - the app router. Maybe you can summarize which option is better or when to use one or another? Or how to use the provider in my case? I assume I am not using the app router
App router is easier bcs theres too much boilerplate on pages dir :)
Barbary LionOP
Okay, thank you very much for the information. I am continuing my nextjs/react journey on my own now, as I have received this new info about the app/pages folders and app router. Everything already looks much clearer.
I guess keeping this thread open for a little while won't be bad, if I will have question or two about the same thing? Or I should close it immediately?
I guess keeping this thread open for a little while won't be bad, if I will have question or two about the same thing? Or I should close it immediately?
@Barbary Lion Okay, thank you very much for the information. I am continuing my nextjs/react journey on my own now, as I have received this new info about the app/pages folders and app router. Everything already looks much clearer.
I guess keeping this thread open for a little while won't be bad, if I will have question or two about the same thing? Or I should close it immediately?
Just mark it as answered and if you have more question feel free to create a new post or just ask in #discussions
Barbary LionOP
Okay, thank you!