Skip to content

Commit

Permalink
fix: useActionData now ignores Response
Browse files Browse the repository at this point in the history
  • Loading branch information
fredericoo committed Oct 28, 2023
1 parent d07150e commit d6b3e0c
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# react-router-typesafe

## 1.3.4

### Patch Changes

- `useActionData` now ignores Response objects as expected

## 1.3.3

### Patch Changes
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ Feel free to improve the code and submit a pull request. If you're not sure abou
| Status | Utility | Before | After |
| ------ | -------------------- | ---------- | ------------------------------------------------------------ |
|| `defer` | `Response` | Generic matching the first argument |
| | `json` | `Response` | Serialized data passed in |
|| `useLoaderData` | `unknown` | Generic function with the type of the loader function passed |
|| `useActionData` | `unknown` | Generic function with the type of the action function passed |
|| `useRouteLoaderData` | `unknown` | Generic function with the type of the loader function passed |
| NEW | `makeLoader` | `unknown` | Wrapper around `satisfies` for ergonomics |
| NEW | `makeAction` | `unknown` | Wrapper around `satisfies` for ergonomics |
| NEW | `makeLoader` | | Wrapper around `satisfies` for ergonomics |
| NEW | `makeAction` | | Wrapper around `satisfies` for ergonomics |

## Patched components

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-router-typesafe",
"version": "1.3.3",
"version": "1.3.4",
"repository": {
"type": "git",
"url": "https://github.com/stargaze-co/react-router-typesafe.git"
Expand Down
39 changes: 39 additions & 0 deletions src/__tests__/action.typetest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { test } from 'bun:test';
import { ActionFunction, LoaderFunction, redirect } from 'react-router-dom';
import { useActionData } from '..';
/** TODO: wait for feedback on issue about act-compat importing deprecated "react-dom/test-utils" */
import { renderHook } from '@testing-library/react';
import { expectTypeOf } from 'expect-type';

test('works with non-promises', () => {
const testAction = (() => {
return { foo: 'bar' };
}) satisfies ActionFunction;

const { result } = renderHook(useActionData<typeof testAction>);
expectTypeOf(result.current).toEqualTypeOf<{ foo: string } | undefined>();
});

test('works with promises', () => {
const testAction = (async () => {
return { foo: 'bar' };
}) satisfies ActionFunction;

const { result } = renderHook(useActionData<typeof testAction>);
expectTypeOf(result.current).toEqualTypeOf<{ foo: string } | undefined>();
});

test('ignores redirects or responses', () => {
const testAction = (() => {
if (Math.random() > 0.5) {
return redirect('/foo');
}
if (Math.random() > 0.5) {
return new Response(null, {});
}
return { foo: 'bar' };
}) satisfies ActionFunction;

const { result } = renderHook(useActionData<typeof testAction>);
expectTypeOf(result.current).toEqualTypeOf<{ foo: string } | undefined>();
});
4 changes: 2 additions & 2 deletions src/__tests__/loader.typetest.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { test } from 'bun:test';
import { LoaderFunction, redirect } from 'react-router-dom';
import { LoaderFunction, json, redirect } from 'react-router-dom';
import { useLoaderData } from '..';
/** TODO: wait for feedback on issue about act-compat importing deprecated "react-dom/test-utils" */
import { renderHook } from '@testing-library/react';
Expand Down Expand Up @@ -57,7 +57,7 @@ test('works with redirects', () => {
expectTypeOf(result.current).toEqualTypeOf<{ foo: string }>();
});

test.skip('routeLoaderData works the same way as useLoaderData', () => {
test('routeLoaderData works the same way as useLoaderData', () => {
const testLoader = (() => {
if (Math.random() > 0.5) {
return redirect('/foo');
Expand Down
4 changes: 3 additions & 1 deletion src/action.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ActionFunction, useActionData as rrUseActionData } from 'react-router-dom';

export type ActionData<TActionFn extends ActionFunction> = Awaited<ReturnType<TActionFn>> | undefined;
export type ActionData<TActionFn extends ActionFunction> = Awaited<ReturnType<TActionFn>> extends Response | infer D
? D | undefined
: never;

/** Returns the action data for the nearest ancestor Route action
* @example
Expand Down

0 comments on commit d6b3e0c

Please sign in to comment.