admin管理员组文章数量:1398814
I need to access data that is specific to a request in a few different places (all server-side) in a next.js app -- for example, the Host header or a request ID. For now, my team has been using the headers function and other request-specific state management functions from next.js.
This has worked OK so far. However, with next.js 15 those functions (headers
, cookies
, etc) have become async, and I have a few non-async functions that currently call them and must remain non-async (because they're passed as arguments to synchronous third-party APIs).
Eg.:
// combine expects a sync callback
combine(getCustomerSlug);
// with nextjs 15, this function will need to be async
getCustomerSlug()
{
let host = headers();
//...
}
This could easily be solved by first calling eg. headers
on an async context (eg. middleware), then storing the result somewhere globally accessible for the lifetime of the request, but I'm failing to find a way to do that on next.js; In fact, this is actually what we wanted to do in the first place before we gave up and decided to just use those functions directly elsewhere.
One solution I've tried is using Node.js' AsyncLocalStorage
: start a context when the middleware starts running, and end it when the middleware ends... except since next.js 12 middleware doesn't look much like middleware anymore, and AFAIK there's no way you can wait for your route's response. On this same vein, I also though about decorating every single route with a call to AsyncLocalStorage.run
but that's clearly not ideal.
I've also thought about simply using global variables, but I guess that wouldn't work unless next.js searializes and runs each request synchronously, which I'm guessing it doesn't, or if it spawns a new process for every request.
A third similar option would be to have a global Map<RequestId, State>
, but as there doesn't seem to be a way to define code in a single place to safely and reliably execute logic right before a response is sent in next.js (ahem middleware), that map could grow indefinitely as the server receives more requests.
I need to access data that is specific to a request in a few different places (all server-side) in a next.js app -- for example, the Host header or a request ID. For now, my team has been using the headers function and other request-specific state management functions from next.js.
This has worked OK so far. However, with next.js 15 those functions (headers
, cookies
, etc) have become async, and I have a few non-async functions that currently call them and must remain non-async (because they're passed as arguments to synchronous third-party APIs).
Eg.:
// combine expects a sync callback
combine(getCustomerSlug);
// with nextjs 15, this function will need to be async
getCustomerSlug()
{
let host = headers();
//...
}
This could easily be solved by first calling eg. headers
on an async context (eg. middleware), then storing the result somewhere globally accessible for the lifetime of the request, but I'm failing to find a way to do that on next.js; In fact, this is actually what we wanted to do in the first place before we gave up and decided to just use those functions directly elsewhere.
One solution I've tried is using Node.js' AsyncLocalStorage
: start a context when the middleware starts running, and end it when the middleware ends... except since next.js 12 middleware doesn't look much like middleware anymore, and AFAIK there's no way you can wait for your route's response. On this same vein, I also though about decorating every single route with a call to AsyncLocalStorage.run
but that's clearly not ideal.
I've also thought about simply using global variables, but I guess that wouldn't work unless next.js searializes and runs each request synchronously, which I'm guessing it doesn't, or if it spawns a new process for every request.
A third similar option would be to have a global Map<RequestId, State>
, but as there doesn't seem to be a way to define code in a single place to safely and reliably execute logic right before a response is sent in next.js (ahem middleware), that map could grow indefinitely as the server receives more requests.
1 Answer
Reset to default -1Storing state on the server is an antipattern. AsyncLocalStorage has its uses but can bloat your server pretty quick. Use after
if you're doing post processing.
Using a local global variable, ie a singleton, won't work either since nextjs
runs multiple context at once.
本文标签: reactjsHow to share requestwide serverside state in nextjsStack Overflow
版权声明:本文标题:reactjs - How to share request-wide server-side state in next.js - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744122124a2591789.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
headers()
, or are you just unable to convert synchronous code to asynchronous code? If it's the latter, please share your code. – Duannx Commented Apr 1 at 6:35header()
call for you. This means the next call toheader()
will get the data directly from the cache. It’s similar to manually implementing a separate shared state. However, if you want more customization in sharing state, you can use React'scache
API. It is the recommended way to share state between components in SSR. – Duannx Commented Apr 3 at 11:05