#use react context in next project?

42 messages · Page 1 of 1 (latest)

icy garden
#

is it wise to use react context in a next application?
I doubt that, because apps rely on server components.

What should I use to manage current user?

winter oasisBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

tawdry venture
#

I have the same question!

I need to somehow update the state through certain scroll event listeners when my scroll is at a certain point and also update the same state from other components. What's the best way to do this?

#

I'm guessing using a useContext and wrapping the server components with a client side context provider would make everything be clientside?

idle sail
#

For me it comes down to what the child components are doing with that data. Are they going to end up needing client side interaction anyways?

hollow raptor
#

As you seem to know already, context only works in client components. However, nextjs apps will include client components for things that need client-side functionality. So, yes, you will end up using context where it makes sense: transient, client-sided context that needs to be shared among some components.

This could be a form, where you want to do some validation on the client before sending to the server, or a graph component where the user needs to be able to change some viewing options but they are not presisted server side, etc.

React contexts have their place in Nextjs apps. You just need to understand when they would be used: client side deeply nested context.

#

These client contexts can be global as well. You just cannot create and consume contexts from within server components. So, as an example, you could create a context providing client component, import it in your root layout, wrap the entire app in it, and then consume the context in deeply nested client components.

MyContext.jsx

"use client"
import { createContext } from "react"

const MyContext = createContext();
export const useMyContext = useContext(MyContext);
export function MyContextProvider({value, children}) {
  return (
    <MyContext.Provider value={value}>
      {children}
    </MyContext.Provider>
  )
}

_layout.jsx

export default async function AppLayout() {
  const value = await computeContextValueOnServer();
  return (
    <MyContextProvider value={value}>
      {/* Rest of component tree, client or server components */}
    </MyContextProvider>
  )
}```
#

MyClientComponent.jsx

"use client"

/* Imagine this component rendered deeply nested in the tree */
export function MyClientComponent() {
  const myValue = useMyContext();
  /* ... the rest of the component ... */
}```
hollow raptor
tawdry venture
#

Thank you so much for the detailed response! This makes much more sense now @hollow raptor

fathom ledge
#

It depends for what are you using the React context... to share data across multiple client component? Yes, is a good idea. To prevent prop drilling? No.

tawdry venture
#

what would be the perferred method than to prevent prop drilling?

fathom ledge
#

As many say, is nothing wrong using prop drilling on server-side.

#

If you think that having too many props is 'ugly', you can group them under some objects.

glacial token
#

Using React Context in a Next.js application can work, but it’s not always the best approach, especially because Next.js heavily relies on server components. With server-side rendering (SSR) and static generation, the state managed by React Context might not sync well between the server and the client, and React Context is purely client-side.

For managing the current user, I’d recommend handling authentication and user data on the server. One of the best tools for this in Next.js is NextAuth.js. It simplifies authentication, handles sessions, and integrates seamlessly with both server-side and client-side rendering. Alternatively, you could use React Query or SWR to fetch user data from the server and then store it in a global state, like Redux or Zustand, for client-side use.

So, instead of relying solely on React Context, it’s better to manage the user state through server-side authentication and then sync it with client-side state as needed.

tawdry venture
fathom ledge
glacial token
fathom ledge
#

PayloadCMS managed to do this (you can check their repo).

glacial token
# fathom ledge The purpose of Next.js is to reduce the client-side and do as much as possible o...

you're absolutely right, it shows the main differences between Next.js and React but i think this approach might not scale well.
For complex or frequently updated state, managing it on the server (for instance, via APIs) and then fetching it using a client-side library like React Query or SWR is often cleaner and more scalable.
while useContext works well for sharing client-side state across components, it has limitations. if the state changes frequently, every consuming component will re-render, potentially causing performance issues. in such cases, using a global state management library like Zustand or Redux provides better performance with fine-grained control over state updates. what do u think about this?

fathom ledge
#

I think, instead of looking to Reactish way of solving this problem, we should also look to Software Design Patterns and try to keep with Next.js way-of-doing-things.

#

Again, PayloadCMS (using Next.js as fundation) is also a complex application and does a lot server-side. They're grouping everything under deep objects.

hollow raptor
#

@fathom ledge I think server sided prop-drilling and client sided context both have their use cases, and should be used where appropriate. For example, PayloadCMS uses tons of global/root level context providers for their admin:

  • RootLayout is rendered on the server and is the root-level layout for the admin app. It is a server component, and wraps the entire app in:
  • RootProvider which is a client component, having 16 context providers by my count.

I think there's confusion/fear of using client components in general, that they somehow poison the speed and savings you get from nextjs. There is no intrinsic harm in using them as long as you are separating the provider into a client component and not unnecessarily marking something with "use client" that could otherwise be a server component (i.e, your context providers should live in client components, and should be imported into server components).

When you do this appropriately, and don't have mismatches/hydration errors due to context initialization on server vs client (client-sided theme implementations, I'm looking at you), you shouldn't have negative performance impacts.

#

Basically, context should be used for things that need to be handled on the client (and, of course, where context would be more useful than stuff like useState, useReducer, or other hooks). Examples would include: client-sided form validation, scroll-effects, audio/video playback, mouse movement/gestures, UI components with client-sided functionality (dropdowns, popovers, combo-boxes).

For everything else, it should be kept on the server to prevent unnecessary client sided JS execution. How you will do so will vary based on what exactly your application is doing.

warped oracle
#

The fact that now you get server components that doesn’t mean it is bad practice to have client conponents. You still need interactivity in the majority of web apps. A lot of people just try to force everything server side. Well just use server components for what they are meant. If you need to share state between client components use context. If you need to share form data in nested components using a library like react-hook-form with the FormProvider is what you are after or why not if you want to get fancy use tanstack query wich is actually an async state management solution actually not a data fetching library like everyone thinks

glacial token
glacial token
warped oracle
#

Well, he has a point. For example, I like NextJS, and every time I have to build something I try to do it using Next. The thing is it depends on the usecase, for some tasks there are probably other tools more suitable. Like me, people who use React whithout a franework like Next, just got used to the patterns in React like context, and other stuff and they tend to use them even if they don’t need to. It’s like implementing state management for incrementing a counter.

fathom ledge
# hollow raptor <@1276154564982210683> I think server sided prop-drilling and client sided conte...

They are also using a lot of things on client-side. But usually, they stick on server-side and prop drills a lot informations (i18n, payload utils, collections, globals, database, etc).

Next.js and many frameworks came with the right question. If I want to render <h1>test</h1>, why I should extra javascript code if is a static HTML element? That's the whole point of my arguments to stick to Next way-of-doing-things.

If you're rendering static things, without using some React hooks or Browser API, what is the point of increasing static files size / initial page load time?

#

For context, I am working in Angular since 2017. Angular lacks this server-side rendering (I mean, it can render the HTML on server-side, but it will hydrate everything with Javascript later).

Basically, if you want to have 100 components rendering an image and a text, you will have a Javascript code for that component. Therefore, you increase the memory size of webpage (100 * component mem size), static files size, initial loading time. And for what? You don't use Javascript at all, the solution is don't use a component (having a lot of static HTML code).

React is similar with Angular, therefore you will have a Javascript for that component and the same down-sides.

Next.js solves this issue, if can be rendered on server-side, keep it on server.

#

I can understand that for some, it's harder to keep with this paradigm, and the easiest solution is to use useContext to keep everything more organized.

If you don't care so much about optimization or that you will send extra things on client, go ahead.

If you care about optimization and want to be lighting-fast, keep with Next.js way-of-doing-things.

#

As I said, it's a complex problem that depends on many variables... time, deadline, your experience, etc.

If you are a new developer, trying to implement a Software Design Pattern may be a nightmare.
If you have a close deadline, you may not have enough time to analyze the problem and implement a Design Pattern.

Everyone will choose based on their knowledge and time.

empty kernel
#

managing react context for top level layout and needing to update it for every page.js access is a nightmare for me.

hollow raptor
# fathom ledge They are also using a lot of things on client-side. But usually, they stick on s...

Of course! I 100% agree. If it can be kept on the server, it should be. That doesn't mean that context and other client sided hooks are dead and gone/should be avoided at all costs. They (client hooks) should be used where necessary, i.e. when client sided reactivity is needed.

I'm not pointing to payload to say "they use it, so all use cases are fine!" I'm just trying to point out that client components and client sided reactivity still have their place. You should of course keep things on the server whenever possible so-as to minimize JavaScript delivered to the client and minimize execution time on the client. Of course, context should not be used simply to eliminate prop drilling on the server. Memoization and caching can help achieve the same effect without the negative performance impacts.