Skip to content

Commit

Permalink
feat(hooks): return input from hooks (#118)
Browse files Browse the repository at this point in the history
Code in this PR adds `input` property in the object returned by the three hooks.

re #116
  • Loading branch information
TheEdoRan committed May 8, 2024
1 parent a7cb006 commit 17935ad
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 11 deletions.
20 changes: 11 additions & 9 deletions packages/next-safe-action/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export const useAction = <
) => {
const [, startTransition] = React.useTransition();
const [result, setResult] = React.useState<HookResult<ServerError, S, BAS, FVE, FBAVE, Data>>(EMPTY_HOOK_RESULT);
const [input, setInput] = React.useState<S extends Schema ? InferIn<S> : void>();
const [clientInput, setClientInput] = React.useState<S extends Schema ? InferIn<S> : void>();
const [isExecuting, setIsExecuting] = React.useState(false);
const [isIdle, setIsIdle] = React.useState(true);

Expand All @@ -128,7 +128,7 @@ export const useAction = <
const execute = React.useCallback(
(input: S extends Schema ? InferIn<S> : void) => {
setIsIdle(false);
setInput(input);
setClientInput(input);
setIsExecuting(true);

return startTransition(() => {
Expand All @@ -151,18 +151,20 @@ export const useAction = <

const reset = () => {
setIsIdle(true);
setClientInput(undefined);
setResult(EMPTY_HOOK_RESULT);
};

useActionCallbacks({
result,
input: input as S extends Schema ? InferIn<S> : undefined,
input: clientInput as S extends Schema ? InferIn<S> : undefined,
status,
cb: utils,
});

return {
execute,
input: clientInput,
result,
reset,
status,
Expand Down Expand Up @@ -192,10 +194,9 @@ export const useOptimisticAction = <
) => {
const [, startTransition] = React.useTransition();
const [result, setResult] = React.useState<HookResult<ServerError, S, BAS, FVE, FBAVE, Data>>(EMPTY_HOOK_RESULT);
const [input, setInput] = React.useState<S extends Schema ? InferIn<S> : void>();
const [clientInput, setClientInput] = React.useState<S extends Schema ? InferIn<S> : void>();
const [isExecuting, setIsExecuting] = React.useState(false);
const [isIdle, setIsIdle] = React.useState(true);

const [optimisticData, setOptimisticData] = React.useOptimistic<Data, S extends Schema ? InferIn<S> : undefined>(
utils.currentData,
utils.updateFn
Expand All @@ -206,7 +207,7 @@ export const useOptimisticAction = <
const execute = React.useCallback(
(input: S extends Schema ? InferIn<S> : void) => {
setIsIdle(false);
setInput(input);
setClientInput(input);
setIsExecuting(true);

return startTransition(() => {
Expand All @@ -230,12 +231,13 @@ export const useOptimisticAction = <

const reset = () => {
setIsIdle(true);
setClientInput(undefined);
setResult(EMPTY_HOOK_RESULT);
};

useActionCallbacks({
result,
input: input as S extends Schema ? InferIn<S> : undefined,
input: clientInput as S extends Schema ? InferIn<S> : undefined,
status,
cb: {
onExecute: utils.onExecute,
Expand All @@ -247,6 +249,7 @@ export const useOptimisticAction = <

return {
execute,
input: clientInput,
result,
optimisticData,
reset,
Expand Down Expand Up @@ -281,9 +284,7 @@ export const useStateAction = <
utils?.permalink
);
const [isIdle, setIsIdle] = React.useState(true);

const [clientInput, setClientInput] = React.useState<S extends Schema ? InferIn<S> : void>();

const status = getActionStatus<ServerError, S, BAS, FVE, FBAVE, Data>({ isExecuting, result, isIdle });

const execute = React.useCallback(
Expand Down Expand Up @@ -311,6 +312,7 @@ export const useStateAction = <

return {
execute,
input: clientInput,
result,
status,
};
Expand Down
3 changes: 2 additions & 1 deletion website/docs/execution/hooks/useaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ As you can see, here we display a greet message after the action is performed, i
| Name | Type | Purpose |
| --------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `execute` | `(input: InferIn<S>) => void` | An action caller with no return. The input is the same as the safe action you passed to the hook. |
| `input` | `InferIn<S> \| undefined` | The input passed to the `execute` function. |
| `result` | [`HookResult`](/docs/types#hookresult) | When the action gets called via `execute`, this is the result object. |
| `status` | [`HookActionStatus`](/docs/types#hookresult) | The action current status. |
| `reset` | `() => void` | You can programmatically reset the `result` object with this function. |
| `reset` | `() => void` | Programmatically reset `input` and `result` object with this function. |

Explore a working example [here](<https://github.com/TheEdoRan/next-safe-action/tree/main/apps/playground/src/app/(examples)/hook>).
3 changes: 2 additions & 1 deletion website/docs/execution/hooks/useoptimisticaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,10 @@ export default function AddLikes({ likesCount }: Props) {
| Name | Type | Purpose |
| ---------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `execute` | `(input: InferIn<S>) => void` | An action caller with no return. The input is the same as the safe action you passed to the hook. |
| `input` | `InferIn<S> \| undefined` | The input passed to the `execute` function. |
| `result` | [`HookResult`](/docs/types#hookresult) | When the action gets called via `execute`, this is the result object. |
| `status` | [`HookActionStatus`](/docs/types#hookresult) | The action current status. |
| `reset` | `() => void` | You can programmatically reset the `result` object with this function. |
| `reset` | `() => void` | Programmatically reset `input` and `result` object with this function. |
| `optimisticData` | `Data` (return type of the `safeActionFn` you passed as first argument) | This is the data that gets updated immediately after `execute` is called, with the behavior you defined in the `reducer` function hook argument. The initial state is what you provided to the hook via `initialOptimisticData` argument. |

Explore a working example [here](<https://github.com/TheEdoRan/next-safe-action/tree/main/apps/playground/src/app/(examples)/optimistic-hook>).
1 change: 1 addition & 0 deletions website/docs/execution/hooks/usestateaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ You can pass an optional initial result to `useStateAction`, with the `initResul
| Name | Type | Purpose |
| ---------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `execute` | `(input: InferIn<S>) => void` | An action caller with no return. The input is the same as the safe action you passed to the hook. |
| `input` | `InferIn<S> \| undefined` | The input passed to the `execute` function. |
| `result` | [`HookResult`](/docs/types#hookresult) | When the action gets called via `execute`, this is the result object. |
| `status` | [`HookActionStatus`](/docs/types#hookresult) | The action current status. |

Expand Down

0 comments on commit 17935ad

Please sign in to comment.