Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Jonathan Gamble
Jonathan Gamble

Posted on

     

Easy Context in React Server Components (RSC)

Continuing the need to have easy context from my other posts, I wanted to find a way to share context on the server as well.

You may have noticed thatuseContext andcreateContext do not compile on the server (another millionth reason I love SvelteKit!).

So, there needs to be a way to do this easily in RSC, even though the React Team, who seems to be extremely far away from the actual userbase, decided to depreciate this feature before it was actually implemented.

You can findcreateServerContext in the latest React as an import, but there is no actualConsumer like there is in a regular context, so I couldn't get it to work. Supposedly it could be shared on the client and server, but only for small strings. The only actual mention of this is in atweet:

letLang=createServerContext("lang","en");...<Lang.Providervalue={}>...use(Lang)
Enter fullscreen modeExit fullscreen mode

Either way, I would have re-written this to work like my other context, so it is a moot point.

I should also add, the second best solution is to use theserver-only-context library (by manvalls) which usescache under the hood.


Dear React Team (and NextJS Team)

There is a reason there are so many external state libraries for React. The way React works out-of-the-box is terrible and uses too much boilerplate. We love RSC (the people on the React train who won't move to Svelte have no choice) and we love that Vercel wants to add Server Actions, but either of you can fix this problem. No more Context Hell please!

React Team... Let's add signals (or something better) as well please and not worry about memoizing state! Why are you making things hard that don't have to be!!!!? Serious question.

Ok, I digress.


The Solution

So I basically copied thecache idea from above, but simplified it for my use case with the Map from my other solutions. Thecache is actually a Map itself, so I believe this is a Map of a Map under the hood.

use-server-provider.tsx

import'server-only';import{cache}from'react';constserverContext=cache(()=>newMap());exportconstuseServerProvider=<T,>(key:string,defaultValue?:T)=>{constglobal=serverContext();if(defaultValue!==undefined){global.set(key,defaultValue);}return[global.get(key),(value:T)=>global.set(key,value)];};
Enter fullscreen modeExit fullscreen mode

Parent

const[count,setCount]=useServerProvider('count',23);
Enter fullscreen modeExit fullscreen mode

Child

const[count]=useServerProvider<number>('count');
Enter fullscreen modeExit fullscreen mode

However, it is worth noting, unlike a reactive component, if you set the component after you define thecount variable, it won't update unless you grab thecount variable again. One way to fix this is to use avalue object key like in a signal:

import'server-only';import{cache}from'react';constserverContext=cache(()=>newMap());exportconstuseServerProvider=<T,>(key:string,defaultValue?:T)=>{constglobal=serverContext();if(defaultValue!==undefined){global.set(key,defaultValue);}return{getvalue(){returnglobal.get(key)},setvalue(v:T){global.set(key,v);}}};
Enter fullscreen modeExit fullscreen mode

Then you could do this:

Parent

constcount=useServerProvider('count',23);count.value=27;
Enter fullscreen modeExit fullscreen mode

Child

exportdefaultfunctionTestChild(){constcount=useServerProvider<number>('count');return(<p>Child:{count.value}</p>)}
Enter fullscreen modeExit fullscreen mode

Nevertheless, on a server you shouldn't care about any of this... so the original react-like way still stands.

Probably the last article in this series... probably...

J

Getting back to rebuildingcode.build

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

My main job is not in IT, but I do have a CS degree and have been programming for over 20 years (only born in 1984). I hate dealing with Servers, and want Graph Databases to be the new norm.
  • Location
    Louisiana
  • Education
    LSU, Oregon State, Middlebury
  • Joined

More fromJonathan Gamble

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp