Before reading this post, that shows this implementation :
// hello.client.js"use client"import{useState}from'react';importMessagefrom'./Message.server';functionHello_Client(){const[selectedId,setSelectedId]=useState(1);return(<div><buttononClick={()=>setSelectedId(selectedId+1)}>
Next
</button><Messageid={selectedId}/></div>);}// message.server.jsimport{db}from'./db.server';functionMessage({id}){constmessage=db.messages.get(id);return(<div><h1>{message.title}</h1><p>{message.body}</p></div>);}
my idea to do the same is to implement with cookies as communication between server and client tree.
Like so:
// root.server.jsimportMessagefrom'./Message.server';importHello_Clientfrom'./hello.client';functionRoot_Server(){constselectedMessageID=getFromCookie('message-id');return(<Hello_Client><Message={selectedMessageID}/></Hello_Client>);}// hello.client.js"use client";functionHello_Client(props){consthandleSelect=()=>{constcurrentMessageID=getFromCookie('message-id');setCookie('message-id',currentMessageID+1);revalidateRoute('/');// tell server tree to rerender with new data}return(<div><buttononClick={handleSelect}>
Next
</button>{children}</div>);}// message.server.jsimport{db}from'./db.server';functionMessage({id}){constmessage=db.messages.get(id);return(<div><h1>{message.title}</h1><p>{message.body}</p></div>);}
Are both ok ?
Is there a risk of exposing server stuff with first approach ?
Both approaches are possible, but they have different tradeoffs:
React Server Components (RSC): This is the recommended approach. It allows the server and client to collaborate on rendering, improving performance and reducing the amount of JavaScript sent to the client.
Use cookies: This is unconventional and generally not recommended due to potential performance issues, security risks (such as XSS and CSRF attacks), and added complexity.
As for exposing server stuff, RSCs are designed to be secure. They run only on the server and have no direct access to the client. Any data returned by a server component is included in the HTML response, much like any other data included in an HTTP response.
// App.client.jsimport{useState,useEffect}from'react';importMessagefrom'./Message.server';functionApp(){const[selectedId,setSelectedId]=useState(()=>{// Read the initial value from the cookiereturnNumber(document.cookie.replace(/(?:(?:^|.*;\s*)selectedId\s*\=\s*([^;]*).*$)|^.*$/,"$1"))||1;});useEffect(()=>{// Update the cookie whenever selectedId changesdocument.cookie=`selectedId=${selectedId}`;},[selectedId]);return(<div><buttononClick={()=>setSelectedId(selectedId+1)}>
Next
</button><Messageid={selectedId}/></div>);}exportdefaultApp;
In this example, we'll use the useState and useEffect hooks to read the initial selectedId value from a cookie and update the cookie whenever the selectedId changes.
Note that this is a simplified example. In a real application, you would want to use a more robust method for managing cookies, such as the js-cookie library.
"use client" sits between server-only and client code. It's placed at the top of a file, above imports, to define the cut-off point where it crosses the boundary from the server-only to the client part. Once "use client" is defined in a file, all other modules imported into it, including child components, are considered part of the client bundle.
Since Server Components are the default, all components are part of the Server Component module graph unless defined or imported in a module that starts with the "use client" directive.
Good to know:
"use client" does not need to be defined in every file. The Client module boundary only needs to be defined once, at the "entry point", for all modules imported into it to be considered a Client Component.
I was assuming that this behavior is a React thing and not a Next thing.
There are some place where this is explained from a plain React side?
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Before reading this post, that shows this implementation :
my idea to do the same is to implement with cookies as communication between server and client tree.
Like so:
Are both ok ?
Is there a risk of exposing server stuff with first approach ?
Edited: added
revalidateRoute() in click handlerBoth approaches are possible, but they have different tradeoffs:
As for exposing server stuff, RSCs are designed to be secure. They run only on the server and have no direct access to the client. Any data returned by a server component is included in the HTML response, much like any other data included in an HTTP response.
Modify the App.client.js file to use cookies:
In this example, we'll use the
useStateanduseEffecthooks to read the initialselectedIdvalue from a cookie and update the cookie whenever theselectedIdchanges.Note that this is a simplified example. In a real application, you would want to use a more robust method for managing cookies, such as the js-cookie library.
This is from Next.js docs:
I was assuming that this behavior is a React thing and not a Next thing.
There are some place where this is explained from a plain React side?