IdoPesok / zsa

Home Page:https://zsa.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Replicate useActionState API?

karlhorky opened this issue · comments

Hi, thanks for this library, looks cool!

For useServerAction, would you consider replicating the API of React's useActionState hook to make it easier to migrate / understand?

Hi @karlhorky , no problem and thank you!

I just added to the docs an example of using this library with useActionState / useFormState. The main "trick" here is to set your server action's input type to be formData. In doing so, using those hooks becomes really easy and I don't see a need to replicate it. Although, do let me know if there is something missing from those hooks that you would want.

To me, useServerAction is meant as an even lighter-weight version of those hooks, with the main point just having the isPending value and not worrying about any state. Also, the execute can take in JSON and not form data.

Lmk if you would like something more than what is in these new docs. Hopefully they help out. For now I will close this issue.

Ah, thanks for the docs! But that's not really what I mean.

(also, those docs should probably be updated, as useActionState is different and offers more)

What I mean is that useServerAction could replicate the API (3-item tuple) and naming of useActionState:

const
- { isPending, execute, data }
+ [state, action, isPending]
  = useServerAction(incrementNumberAction);

This would make it easier to migrate to zsa and make it more relevant longer term.

Sorry it took a minute to get to this, but just opened a PR that I think now addresses your suggestion #64 .

Nice, thanks!

Took a quick look, and one small point of feedback: as a user, I would not be 100% sure why I would have to pass useActionState in to zsa-react:

import { useActionState } from "react"
import { createActionStateHookFrom } from "zsa-react"

const useAction = createActionStateHookFrom(useActionState)

export default function UseActionStateExample() {
  const [{ data, error }, submitAction, isPending] =
    useAction(produceNewMessage)

I would expect something more like this:

import { useAction } from "zsa-react"

export default function UseActionStateExample() {
  const [{ data, error }, submitAction, isPending] =
    useAction(produceNewMessage)

It's a good point. Debating whether or not to add the canary version of react as a dep to zsa-react as currently useActionState is "only available in React’s Canary and experimental channels" source. It is important to note that you would only need to do const useAction = createActionStateHookFrom(useActionState) once in your code base and then you can use your hook anywhere without having to reinstantiate it every time. The benefit of it is it also works with both useFormState and useActionState.

whether or not to add the canary version of react as a dep to zsa-react

The v19 beta and RC versions already have useActionState, IIRC.

Maybe a (relaxed) peer dependency? eg. something like "react": ">=19.0.0-beta-26f2496093-20240514" ? Then consumers can have newer versions without zsa-react installing a separate version. If you want to restrict it to a major, an alternative would be "react": "^19.0.0-beta-26f2496093-20240514" - but then the version number would need to be maintained.

The benefit of it is it also works with both useFormState and useActionState.

useFormState has been replaced by useActionState, so it won't be necessary to support useFormState

Hi, after much thought I have decided to go with the latest proposal mentioned in #64. This is different from a new hook -- rather just makes using useActionState very simple. In addition, it enables progressive enhancement that is mentioned in #70 since the (prevState, formData) func is being exported from the server file.

Oh interesting, that seems like a more minimal layer on top of useActionState, nice!