英文:
I can't import cookies directly into server actions in Next JS 13
问题
I am working on a Next JS 13 project and I encountered an issue with server actions. Server actions can be used directly on form or button components, however, in my personal experience I found that you are most likely to define a server component in a separate file and import it into your client components. This works great until you want to access cookies or headers. If you try calling the headers()
or cookies()
function from next/headers
you get the following error: Error: Invariant: Method expects to have requestAsyncStorage, none available
. This only happens if the server action is in a separate file eg.
actions.js
"use server"
import { cookies } from "next/headers"
export default async function myFunction() {
const token = cookies().get("my-token")
return "done"
}
app/page.jsx
"use client"
import myFunction from "@/actions.js"
export default function Page() {
async function doSomething() {
await myFunction()
}
return <button onClick={doSomething}>my button</button>
}
Trying to run the following code resulted in the error above. I found a workaround which is posted as an answer below. Does anyone have an alternative solution that is a bit cleaner.
英文:
I am working on a Next JS 13 project and I encountered an issue with server actions. Server actions can be used directly on form or button components, however, in my personal experience I found that you are most likely to define a server component in a separate file and import it into your client components. This works great until you want to access cookies or headers. If you try calling the headers()
or cookies()
function from next/headers
you get the following error: Error: Invariant: Method expects to have requestAsyncStorage, none available
. This only happens if the server action is in a separate file eg.
actions.js
"use server"
import { cookies } from "next/headers"
export default async function myFunction() {
const token = cookies().get("my-token")
return "done"
}
app/page.jsx
"use client"
import myFunction from "@/actions.js"
export default function Page() {
async function doSomething() {
await myFunction()
}
return <button onClick={doSomething}>my button</button>
}
Trying to run the following code resulted in the error above. I found a workaround which is posted as an answer below. Does anyone have an alternative solution that is a bit cleaner.
答案1
得分: 1
这是我实施的解决方法。
actions.js
"use server"
export default async function myFunction(cookies) {
const token = await cookies.get("my-token")
return "done"
}
app/layout.jsx
import { cookies } from "next/headers"
export default async function RootLayout({ children, params }) {
params.cookies = {
get: async function(cookie) {
"use server"
return cookies().get(cookie)
},
set: async function(cookie) {
"use server"
return cookies().set(cookie)
}
}
return children
}
app/page.jsx
"use client"
import myFunction from "@/actions.js"
export default function Page({ params: { cookies }}) {
async function doSomething() {
await myFunction(cookies)
}
return <button onClick={doSomething}>my button</button>
}
类似的操作也可以用于headers
。
英文:
This is the workaround I implemented.
actions.js
"use server"
export default async function myFunction(cookies) {
const token = await cookies.get("my-token")
return "done"
}
app/layout.jsx
import { cookies } from "next/headers"
export default async function RootLayout({ children, params }) {
params.cookies = {
get: async function(cookie) {
"use server"
return cookies().get(cookie)
},
set: async function(cookie) {
"use server"
return cookies().set(cookie)
}
}
return children
}
app/page.jsx
"use client"
import myFunction from "@/actions.js"
export default function Page({ params: { cookies }}) {
async function doSomething() {
await myFunction(cookies)
}
return <button onClick={doSomething}>my button</button>
}
A similar thing can be done for headers
.
答案2
得分: 1
截止到v13.4.6,此错误已得到修复。要升级到较新版本的Next JS,请参考此页面:https://nextjs.org/docs/pages/building-your-application/upgrading/version-13。
英文:
As of v13.4.6, this bug has been fixed. In order to update to a newer version of Next JS refer to this page: https://nextjs.org/docs/pages/building-your-application/upgrading/version-13.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论