Skip to content

Commit

Permalink
fix(hooks): add isTransitioning and isPending shorthand statuses …
Browse files Browse the repository at this point in the history
…to return object (#231)

This PR introduces a workaround for the issues described in #227, by adding `isTransitioning` and `isPending` shorthand statuses to the hooks return object. `isTransitioning` is the value returned from the `useTransition` hook that is used under the hood, while `isPending` has the value of `isExecuting || isTransitioning`, for convenience.
  • Loading branch information
TheEdoRan authored Aug 14, 2024
1 parent 4d8574b commit 6e23887
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 73 deletions.
4 changes: 2 additions & 2 deletions apps/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"dependencies": {
"@hookform/resolvers": "^3.3.4",
"lucide-react": "^0.378.0",
"next": "15.0.0-canary.75",
"next": "15.0.0-canary.115",
"next-safe-action": "workspace:*",
"react": "19.0.0-rc-512b09b2-20240718",
"react-dom": "19.0.0-rc-512b09b2-20240718",
Expand All @@ -26,7 +26,7 @@
"@types/react-dom": "18.3.0",
"autoprefixer": "10.4.19",
"eslint": "^8.57.0",
"eslint-config-next": "15.0.0-canary.75",
"eslint-config-next": "15.0.0-canary.115",
"postcss": "8.4.38",
"tailwindcss": "3.4.3",
"typescript": "^5.5.4"
Expand Down
12 changes: 11 additions & 1 deletion apps/playground/src/app/(examples)/hook/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export default function Hook() {
reset,
isIdle,
isExecuting,
isTransitioning,
isPending,
hasSucceeded,
hasErrored,
} = useAction(deleteUser, {
Expand All @@ -34,7 +36,15 @@ export default function Hook() {
},
});

console.dir({ status, isIdle, isExecuting, hasSucceeded, hasErrored });
console.dir({
status,
isIdle,
isExecuting,
isTransitioning,
isPending,
hasSucceeded,
hasErrored,
});

return (
<main className="w-96 max-w-full px-4">
Expand Down
22 changes: 17 additions & 5 deletions packages/next-safe-action/src/hooks-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,18 @@ export const getActionStatus = <
}
};

export const getActionShorthandStatusObject = (status: HookActionStatus) => {
export const getActionShorthandStatusObject = ({
status,
isTransitioning,
}: {
status: HookActionStatus;
isTransitioning: boolean;
}) => {
return {
isIdle: status === "idle",
isExecuting: status === "executing",
isTransitioning,
isPending: status === "executing" || isTransitioning,
hasSucceeded: status === "hasSucceeded",
hasErrored: status === "hasErrored",
};
Expand Down Expand Up @@ -102,12 +110,16 @@ export const useActionCallbacks = <
await Promise.resolve(onExecute?.({ input }));
break;
case "hasSucceeded":
await Promise.resolve(onSuccess?.({ data: result?.data, input }));
await Promise.resolve(onSettled?.({ result, input }));
await Promise.all([
Promise.resolve(onSuccess?.({ data: result?.data, input })),
Promise.resolve(onSettled?.({ result, input })),
]);
break;
case "hasErrored":
await Promise.resolve(onError?.({ error: result, input }));
await Promise.resolve(onSettled?.({ result, input }));
await Promise.all([
Promise.resolve(onError?.({ error: result, input })),
Promise.resolve(onSettled?.({ result, input })),
]);
break;
}
};
Expand Down
8 changes: 4 additions & 4 deletions packages/next-safe-action/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const useAction = <
safeActionFn: HookSafeActionFn<ServerError, S, BAS, CVE, CBAVE, Data>,
utils?: HookBaseUtils<S> & HookCallbacks<ServerError, S, BAS, CVE, CBAVE, Data>
) => {
const [, startTransition] = React.useTransition();
const [isTransitioning, startTransition] = React.useTransition();
const [result, setResult] = React.useState<HookResult<ServerError, S, BAS, CVE, CBAVE, Data>>({});
const [clientInput, setClientInput] = React.useState<S extends Schema ? InferIn<S> : void>();
const [isExecuting, setIsExecuting] = React.useState(false);
Expand Down Expand Up @@ -128,7 +128,7 @@ export const useAction = <
result,
reset,
status,
...getActionShorthandStatusObject(status),
...getActionShorthandStatusObject({ status, isTransitioning }),
};
};

Expand All @@ -155,7 +155,7 @@ export const useOptimisticAction = <
} & HookBaseUtils<S> &
HookCallbacks<ServerError, S, BAS, CVE, CBAVE, Data>
) => {
const [, startTransition] = React.useTransition();
const [isTransitioning, startTransition] = React.useTransition();
const [result, setResult] = React.useState<HookResult<ServerError, S, BAS, CVE, CBAVE, Data>>({});
const [clientInput, setClientInput] = React.useState<S extends Schema ? InferIn<S> : void>();
const [isExecuting, setIsExecuting] = React.useState(false);
Expand Down Expand Up @@ -260,7 +260,7 @@ export const useOptimisticAction = <
optimisticState,
reset,
status,
...getActionShorthandStatusObject(status),
...getActionShorthandStatusObject({ status, isTransitioning }),
};
};

Expand Down
4 changes: 2 additions & 2 deletions packages/next-safe-action/src/stateful-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const useStateAction = <
utils?.permalink
);
const [isIdle, setIsIdle] = React.useState(true);
const [, startTransition] = React.useTransition();
const [isTransitioning, startTransition] = React.useTransition();
const [clientInput, setClientInput] = React.useState<S extends Schema ? InferIn<S> : void>();
const status = getActionStatus<ServerError, S, BAS, CVE, CBAVE, Data>({
isExecuting,
Expand Down Expand Up @@ -78,6 +78,6 @@ export const useStateAction = <
input: clientInput,
result,
status,
...getActionShorthandStatusObject(status),
...getActionShorthandStatusObject({ status, isTransitioning }),
};
};
Loading

0 comments on commit 6e23887

Please sign in to comment.