Closed7

Next.js 14.1.1 から 'use server' をつけてexport したものは強制的に Promiseを返す?

HTMLGOHTMLGO

サーバーアクション内で、 hogeを読み込んで、呼び出す。
hoge は非同期関数でもなんでもないが、とりあえず、'use server' をつけていた

v14.1.0

hoge.ts

'use server'

export const hoge = () => {
   return 'hoge'
}

checkLogin.ts
'use server'

import { hoge } from './hoge'

export async function checkLogin() {
  console.log(hoge()) // 'hoge' を返す

~~~~~

hogeを返す

HTMLGOHTMLGO

next.jsのバージョンを上げたらpromiseを返すようになった。
awaitつけたら、従来の値を取得出来た。何故。。

v14.1.1

hoge.ts

'use server'

export const hoge = () => {
   return 'hoge'
}

checkLogin.ts
'use server'

import { hoge } from './hoge'

export async function checkLogin() {
  console.log(hoge()) // Promiseを返す

  console.log(await hoge()) // hogeを返す

~~~~~
HTMLGOHTMLGO

どうやら14.1.1から'use server'がついていると、強制的にpromiseを返すようになった様子

v14.1.1

hoge.ts

'use server'

export const hoge = () => {
   return 'hoge'
}

↓↓↓↓↓↓↓↓↓

v14.1.1

hoge.ts

export const hoge = () => {
   return 'hoge'
}

use serverを取ったら、普通にhogeを返すようになった。

HTMLGOHTMLGO

今回のミスとしては、以下の関数式の書き方だと
エラーになってくれないこと。

v14.1.1

hoge.ts

'use server'

export const hoge = () => {
   return 'hoge'
}

関数宣言だとasyncをつけろ、とエラーになってくれるので、
事前にミスが防げる。

v14.1.1

hoge.ts
'use server'

export function hoge() {
   return 'hoge'
}

↓↓↓↓↓↓↓↓↓

app-index.js:35 ./hoge.ts
Error: 
  × Server actions must be async functions
   ╭─[/hoge.ts:1:1]
 1 │ 'use server'
 2 │ 
 3 │ export function hoge() {
   ·                 ────
 4 │   return 'hoge'
 5 │ }
   ╰────
HTMLGOHTMLGO

v14.1.1

今回は、

  • 非同期処理じゃないので、不必要な 'use server'を取る。
  • 念の為、関数宣言にする。
  • 念の為 'server-only'を読み込む

とした。

hoge.ts

import 'server-only'

export function hoge() {
  return 'hoge'
}

バージョンアップした時に焦ったので、
メモしておく。

HTMLGOHTMLGO

でもこれを読み込んでると、use server をつけないと怒られる。

import { cookies } from 'next/headers'
  x You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/
  | react-essentials#server-components
  | 

なので、Server Actionsの中で読み込んでいる、moduleの関数も
全部asyncつけといた方がいいのかな。。

このスクラップは2ヶ月前にクローズされました