Skip to content

Commit d6b3e0c

Browse files
committed
fix: useActionData now ignores Response
1 parent d07150e commit d6b3e0c

File tree

6 files changed

+54
-6
lines changed

6 files changed

+54
-6
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# react-router-typesafe
22

3+
## 1.3.4
4+
5+
### Patch Changes
6+
7+
- `useActionData` now ignores Response objects as expected
8+
39
## 1.3.3
410

511
### Patch Changes

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ Feel free to improve the code and submit a pull request. If you're not sure abou
6060
| Status | Utility | Before | After |
6161
| ------ | -------------------- | ---------- | ------------------------------------------------------------ |
6262
|| `defer` | `Response` | Generic matching the first argument |
63+
| | `json` | `Response` | Serialized data passed in |
6364
|| `useLoaderData` | `unknown` | Generic function with the type of the loader function passed |
6465
|| `useActionData` | `unknown` | Generic function with the type of the action function passed |
6566
|| `useRouteLoaderData` | `unknown` | Generic function with the type of the loader function passed |
66-
| NEW | `makeLoader` | `unknown` | Wrapper around `satisfies` for ergonomics |
67-
| NEW | `makeAction` | `unknown` | Wrapper around `satisfies` for ergonomics |
67+
| NEW | `makeLoader` | | Wrapper around `satisfies` for ergonomics |
68+
| NEW | `makeAction` | | Wrapper around `satisfies` for ergonomics |
6869

6970
## Patched components
7071

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-router-typesafe",
3-
"version": "1.3.3",
3+
"version": "1.3.4",
44
"repository": {
55
"type": "git",
66
"url": "https://github.com/stargaze-co/react-router-typesafe.git"

src/__tests__/action.typetest.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { test } from 'bun:test';
2+
import { ActionFunction, LoaderFunction, redirect } from 'react-router-dom';
3+
import { useActionData } from '..';
4+
/** TODO: wait for feedback on issue about act-compat importing deprecated "react-dom/test-utils" */
5+
import { renderHook } from '@testing-library/react';
6+
import { expectTypeOf } from 'expect-type';
7+
8+
test('works with non-promises', () => {
9+
const testAction = (() => {
10+
return { foo: 'bar' };
11+
}) satisfies ActionFunction;
12+
13+
const { result } = renderHook(useActionData<typeof testAction>);
14+
expectTypeOf(result.current).toEqualTypeOf<{ foo: string } | undefined>();
15+
});
16+
17+
test('works with promises', () => {
18+
const testAction = (async () => {
19+
return { foo: 'bar' };
20+
}) satisfies ActionFunction;
21+
22+
const { result } = renderHook(useActionData<typeof testAction>);
23+
expectTypeOf(result.current).toEqualTypeOf<{ foo: string } | undefined>();
24+
});
25+
26+
test('ignores redirects or responses', () => {
27+
const testAction = (() => {
28+
if (Math.random() > 0.5) {
29+
return redirect('/foo');
30+
}
31+
if (Math.random() > 0.5) {
32+
return new Response(null, {});
33+
}
34+
return { foo: 'bar' };
35+
}) satisfies ActionFunction;
36+
37+
const { result } = renderHook(useActionData<typeof testAction>);
38+
expectTypeOf(result.current).toEqualTypeOf<{ foo: string } | undefined>();
39+
});

src/__tests__/loader.typetest.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { test } from 'bun:test';
2-
import { LoaderFunction, redirect } from 'react-router-dom';
2+
import { LoaderFunction, json, redirect } from 'react-router-dom';
33
import { useLoaderData } from '..';
44
/** TODO: wait for feedback on issue about act-compat importing deprecated "react-dom/test-utils" */
55
import { renderHook } from '@testing-library/react';
@@ -57,7 +57,7 @@ test('works with redirects', () => {
5757
expectTypeOf(result.current).toEqualTypeOf<{ foo: string }>();
5858
});
5959

60-
test.skip('routeLoaderData works the same way as useLoaderData', () => {
60+
test('routeLoaderData works the same way as useLoaderData', () => {
6161
const testLoader = (() => {
6262
if (Math.random() > 0.5) {
6363
return redirect('/foo');

src/action.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { ActionFunction, useActionData as rrUseActionData } from 'react-router-dom';
22

3-
export type ActionData<TActionFn extends ActionFunction> = Awaited<ReturnType<TActionFn>> | undefined;
3+
export type ActionData<TActionFn extends ActionFunction> = Awaited<ReturnType<TActionFn>> extends Response | infer D
4+
? D | undefined
5+
: never;
46

57
/** Returns the action data for the nearest ancestor Route action
68
* @example

0 commit comments

Comments
 (0)