TheEdoRan / next-safe-action

Type safe and validated Server Actions in your Next.js project.
https://next-safe-action.dev
MIT License
2.08k stars 33 forks source link

[BUG] Using params directly does break action #130

Open enisze opened 4 months ago

enisze commented 4 months ago

Are you using the latest version of this library?

Is there an existing issue for this?

Describe the bug

Hey I found out that using params of a page directly in an action does not work with next-safe action.

Reproduction steps

Reproduction:

const action = action(
    z.object({
        test: z.number(),
    }),
    async ({ test }) => {
        console.log(test)
    },
)

❌ Does not work, the action is not running nor the middleware.

export default async function Page({
    params: { test },
}: {
    params: { test: number }
}) {
    return (
        <div>
            <form
                action={async () => {
                    'use server'

                       await action({test})     
        }}
            >
                <button type='submit'>test</button>
            </form>
        </div>
    )
}

✅ Does work when instantiating it

export default async function Page({
    params: { test },
}: {
    params: { test: number }
}) {
const testInstance = test
    return (
        <div>
            <form
                action={async () => {
                    'use server'

                       await action({test:testInstance})        
        }}
            >
                <button type='submit'>test</button>
            </form>
        </div>
    )
}

Expected behavior

both should work

Minimal reproduction example

see reproduction steps

Operating System

macOs

Library version

6.2.0

Next.js version

14.2.3

Additional context

No response

TheEdoRan commented 4 months ago

Why are you inlining "use server" inside form's action prop? Why does the action action have the same name as the action client? I need a link to a minimal reproduction example, as the issue template requests, to investigate this, thanks.

enisze commented 4 months ago

@TheEdoRan my bad:

Hope this is better:

import { z } from 'zod'
import { action } from '~/server/save-actions'

const someAction = action(z.string(), async (test) => {
    'use server'
    console.log(test)
})

const Page = ({ test }: { test: string }) => {
    return (
        <div>
            <form
                action={async () => {
                    'use server'

                    someAction(test)
                }}
            >
                <button type='submit'>test</button>
            </form>
        </div>
    )
}

export default Page

import { z } from 'zod'
import { action } from '~/server/save-actions'

const someAction = action(z.string(), async (test) => {
    'use server'
    console.log(test)
})

const Page = ({ test }: { test: string }) => {
const testInstance = test
    return (
        <div>
            <form
                action={async () => {
                    'use server'

                    someAction(testInstance)
                }}
            >
                <button type='submit'>test</button>
            </form>
        </div>
    )
}

export default Page