Skip to content

Commit fdab552

Browse files
committed
data-api wip
1 parent 60e0611 commit fdab552

5 files changed

Lines changed: 330 additions & 283 deletions

File tree

Lines changed: 62 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,18 @@
11
---
22
title: action
33
use_cases: >-
4-
forms, user input, data mutations, optimistic updates, form submissions,
5-
server actions, post requests
4+
actions, form actions, mutations, submissions
65
tags:
76
- actions
87
- forms
98
- mutations
10-
- post
11-
- validation
12-
- optimistic-updates
13-
- server
9+
- submissions
1410
version: "1.0"
1511
description: >-
16-
Learn how to handle form submissions and data mutations in SolidJS with
17-
actions, including optimistic updates and server-side processing.
12+
action wraps an async function as a router action.
1813
---
1914

20-
The `action` function wraps an asynchronous function and returns an [action](/solid-router/concepts/actions).
21-
22-
When an action is triggered, it creates a submission object that tracks its execution status.
23-
This state can be accessed with the [`useSubmission`](/solid-router/reference/data-apis/use-submission) and [`useSubmissions`](/solid-router/reference/data-apis/use-submissions) primitives.
24-
25-
After an action completed successfully, all queries active in the same page are revalidated, unless revalidation is configured using [response helpers](/solid-router/concepts/actions#managing-navigation-and-revalidation).
15+
`action` wraps an async function and returns an action function with router submission tracking. Matching submissions can be read with [`useSubmission`](/solid-router/reference/data-apis/use-submission) and [`useSubmissions`](/solid-router/reference/data-apis/use-submissions).
2616

2717
## Import
2818

@@ -40,116 +30,121 @@ function action<T extends Array<any>, U = void>(
4030

4131
function action<T extends Array<any>, U = void>(
4232
fn: (...args: T) => Promise<U>,
43-
options?: { name?: string; onComplete?: (s: Submission<T, U>) => void }
44-
): Action<T, U>;
45-
46-
function action<T extends Array<any>, U = void>(
47-
fn: (...args: T) => Promise<U>,
48-
options:
49-
| string
50-
| { name?: string; onComplete?: (s: Submission<T, U>) => void } = {}
33+
options?: {
34+
name?: string;
35+
onComplete?: (submission: Submission<T, U>) => void;
36+
}
5137
): Action<T, U>;
5238
```
5339

5440
## Parameters
5541

56-
### `handler`
42+
### `fn`
5743

5844
- **Type:** `(...args: T) => Promise<U>`
5945
- **Required:** Yes
6046

61-
An asynchronous function that performs the action's logic.
62-
When the action is used with a [`<form>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/form), the function receives a [`FormData` object](https://developer.mozilla.org/en-US/docs/Web/API/FormData) as its first parameter.
47+
Async function called when the action runs.
6348

64-
### `options`
49+
When native form handling calls the action, the argument is `FormData` for `multipart/form-data` forms and `URLSearchParams` otherwise.
6550

66-
- **Type:** `string | { name?: string; onComplete?: (s: Submission<T, U>) => void }`
67-
- **Required**: No
6851

69-
A unique string used to identify the action in Server-Side Rendering (SSR) environments.
70-
This is required when using the action with a `<form>` element.
7152

72-
Alternatively, a configuration object can be passed with the following properties.
53+
### `options`
54+
55+
- **Type:** `{ name?: string; onComplete?: (submission: Submission<T, U>) => void }`
56+
- **Required:** No
57+
58+
Action options.
7359

7460
#### `name`
7561

7662
- **Type:** `string`
7763
- **Required:** No
7864

79-
The unique string to identify the action in SSR environments.
80-
Required for `<form>` usage.
65+
Name used to create the action URL.
66+
67+
The name provides a stable URL for form actions and server rendering.
8168

82-
#### `onComplete` (optional):
69+
#### `onComplete`
8370

84-
- **Type:** `(s: Submission<T, U>) => void`
71+
- **Type:** `(submission: Submission<T, U>) => void`
8572
- **Required:** No
8673

87-
A function that runs after the action completes.
88-
It receives a submission object as its parameter.
74+
Function called after the action response is handled.
8975

9076
## Return value
9177

92-
`action` returns an action with the following properties.
78+
`action` returns a function with the following properties:
79+
80+
### `url`
81+
82+
- **Type:** `string`
83+
84+
String used when the action is rendered as a form `action` and when submissions are matched back to this action. The optional `name` provides a stable value for this string.
9385

9486
### `with`
9587

96-
A method that wraps the original action and returns a new one.
97-
When this new action is triggered, the arguments passed to `with` are forwarded to the original action.
98-
If this new action is used with a `<form>`, the `FormData` object is passed as the last parameter, after any other forwarded parameters.
88+
- **Type:** `(...args: any[]) => Action<any[], U>`
89+
90+
Function that creates an action with leading arguments prefilled.
91+
92+
## Behavior
93+
94+
- Calling an action adds a submission to the router submissions signal.
95+
- Each submission exposes `input`, `url`, `result`, `error`, `pending`, `clear`, and `retry`.
96+
- `with` creates another action that calls the original action with leading arguments already supplied.
97+
- `onComplete` receives a submission snapshot after the response is handled.
98+
- `Response` objects with an `X-Revalidate` header supply the keys passed to `revalidate`; without that header, action response handling passes `undefined`.
99+
- Returned `Response` objects with a `Location` header trigger client navigation to that location.
100+
- On the client, actions are registered by URL in the action map and removed during cleanup when an owner exists.
101+
- If an action has no URL, converting it to a string throws.
99102

100103
## Examples
101104

102-
### Form submission
105+
### Basic usage
103106

104107
```tsx
105108
import { action } from "@solidjs/router";
106109

107-
const addTodoAction = action(async (formData: FormData) => {
108-
// Adds a new todo to the server.
110+
const addTodo = action(async (data: URLSearchParams) => {
111+
return data.get("title")?.toString();
109112
}, "addTodo");
110113

111114
function TodoForm() {
112115
return (
113-
<form action={addTodoAction} method="post">
114-
<input name="name" />
116+
<form action={addTodo} method="post">
117+
<input name="title" />
115118
<button>Add todo</button>
116119
</form>
117120
);
118121
}
119122
```
120123

121-
### Passing additional arguments
124+
### Prefilled arguments
122125

123126
```tsx
124127
import { action } from "@solidjs/router";
125128

126-
const addTodoAction = action(async (userId: number, formData: FormData) => {
127-
// ... Adds a new todo for a specific user.
129+
const addTodo = action(async (userId: string, data: URLSearchParams) => {
130+
return {
131+
userId,
132+
title: data.get("title")?.toString(),
133+
};
128134
}, "addTodo");
129135

130-
function TodoForm() {
131-
const userId = 1;
136+
function TodoForm(props: { userId: string }) {
132137
return (
133-
<form action={addTodoAction.with(userId)} method="post">
134-
<input name="name" />
138+
<form action={addTodo.with(props.userId)} method="post">
139+
<input name="title" />
135140
<button>Add todo</button>
136141
</form>
137142
);
138143
}
139144
```
140145

141-
### Triggering actions programmatically
146+
## Related
142147

143-
```tsx
144-
import { action, useAction } from "@solidjs/router";
145-
146-
const markDoneAction = action(async (id: string) => {
147-
// ... Marks a todo as done on the server.
148-
});
149-
150-
function NotificationItem(props: { id: string }) {
151-
const markDone = useAction(markDoneAction);
152-
153-
return <button onClick={() => markDone(props.id)}>Mark as done</button>;
154-
}
155-
```
148+
- [`useAction`](/solid-router/reference/data-apis/use-action)
149+
- [`useSubmission`](/solid-router/reference/data-apis/use-submission)
150+
- [`useSubmissions`](/solid-router/reference/data-apis/use-submissions)

src/routes/solid-router/reference/data-apis/cache.mdx

Lines changed: 27 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -2,136 +2,58 @@
22
title: cache
33
isDeprecated: true
44
use_cases: >-
5-
api calls, data fetching, deduplication, preloading routes, caching responses,
6-
preventing waterfalls
5+
deprecated query alias, cached functions, route data
76
tags:
87
- cache
98
- deprecated
10-
- data-fetching
11-
- deduplication
12-
- preload
9+
- query
1310
version: "1.0"
1411
description: >-
15-
Deprecated caching API for deduplicating requests and preloading data. Use
16-
query instead for better performance and invalidation.
12+
cache is a deprecated alias for query.
1713
---
1814

19-
:::caution[Deprecation Warning]
20-
This API is deprecated since `v0.15.0` of Solid Router. Use [query](/solid-router/reference/data-apis/query) instead. It will be removed in an upcoming release.
21-
:::
15+
`cache` is a deprecated alias for [`query`](/solid-router/reference/data-apis/query).
2216

23-
`cache` is a [higher-order function](https://en.wikipedia.org/wiki/Higher-order_function) designed to create a new function with the same signature as the function passed to it.
24-
When this newly created function is called for the first time with a specific set of arguments, the original function is run, and its return value is stored in a cache and returned to the caller of the created function.
25-
The next time the created function is called with the same arguments (as long as the cache is still valid), it will return the cached value instead of re-executing the original function.
17+
## Import
2618

27-
:::note
28-
`cache` can be defined anywhere and then used inside your components with [`createAsync`](/solid-router/reference/data-apis/create-async).
29-
30-
However, using `cache` directly in [`createResource`](/reference/basic-reactivity/create-resource) will not work since the fetcher is not reactive and will not invalidate properly.
31-
32-
:::
33-
34-
## Usage
35-
36-
```js
37-
const getUser = query(
38-
(id, options = {}) =>
39-
fetch(`/api/users/${id}?summary=${options.summary || false}`).then((r) =>
40-
r.json()
41-
),
42-
"usersById"
43-
);
44-
45-
getUser(123); // Causes a GET request to /api/users/123?summary=false
46-
getUser(123); // Does not cause a GET request
47-
getUser(123, { summary: true }); // Causes a GET request to /api/users/123?summary=true
48-
setTimeout(() => getUser(123, { summary: true }), 999000); // Eventually causes another GET request to /api/users/123?summary=true
19+
```tsx
20+
import { cache } from "@solidjs/router";
4921
```
5022

51-
### With preload functions
52-
53-
Using it with a [preload function](/solid-router/reference/preload-functions/preload):
54-
55-
```js
56-
import { lazy } from "solid-js";
57-
import { Route } from "@solidjs/router";
58-
import { getUser } from ... // the cache function
59-
60-
const User = lazy(() => import("./pages/users/[id].js"));
61-
62-
// preload function
63-
function preloadUser({params, location}) {
64-
void getUser(params.id)
65-
}
23+
## Type
6624

67-
// Pass it in the route definition
68-
<Route path="/users/:id" component={User} preload={preloadUser} />;
25+
```tsx
26+
const cache: typeof query;
6927
```
7028

71-
### Inside a route's component
72-
73-
Using it inside a route's component:
74-
75-
```jsx
76-
// pages/users/[id].js
77-
import { getUser } from ... // the cache function
78-
79-
export default function User(props) {
80-
const user = createAsync(() => getUser(props.params.id));
81-
return <h1>{user().name}</h1>;
82-
}
83-
```
84-
85-
## Cache function capabilities
86-
87-
`cache` accomplishes the following:
88-
89-
1. Deduping on the server for the lifetime of the request.
90-
2. Preloading the cache in the browser - this lasts 5 seconds.
91-
When a route is preloaded on hover or when preload is called when entering a route it will make sure to dedupe calls.
92-
3. A reactive refetch mechanism based on key.
93-
This prevents routes that are not new from retriggering on action revalidation.
94-
4. Serve as a back/forward cache for browser navigation for up to 5 minutes.
95-
Any user based navigation or link click bypasses it.
96-
Upon revalidation or new fetch the cache is updated.
97-
98-
## Cache keys
29+
## Parameters
9930

100-
To ensure that the cache keys are consistent and unique, arguments are deterministically serialized using JSON.stringify.
101-
Before serialization, key/value pairs in objects are sorted so that the order of properties does not affect the serialization.
102-
For instance, both `{ name: 'Ryan', awesome: true }` and `{ awesome: true, name: 'Ryan' }` will serialize to the same string so that they produce the same cache key.
31+
`cache` has the same parameters as [`query`](/solid-router/reference/data-apis/query).
10332

10433
## Return value
10534

106-
The return value is a `CachedFunction`, a function that has the same signature as the function you passed to `cache`.
107-
This cached function stores the return value using the cache key.
108-
Under most circumstances, this temporarily prevents the passed function from running with the same arguments, even if the created function is called repeatedly.
35+
- **Type:** `CachedFunction<T>`
10936

110-
## Arguments
37+
`cache` returns the same value as [`query`](/solid-router/reference/data-apis/query).
11138

112-
| argument | type | description |
113-
| -------- | ----------------------- | ------------------------------------------------------------------------- |
114-
| `fn` | `(...args: any) => any` | A function whose return value you'd like to be cached. |
115-
| `name`\* | string | Any arbitrary string that you'd like to use as the rest of the cache key. |
39+
## Behavior
11640

117-
\*Since the internal cache is shared by all the functions using `cache`, the string should be unique for each function passed to `cache`.
118-
If the same key is used with multiple functions, one function might return the cached result of the other.
41+
- `cache` and `query` reference the same function.
42+
- Cache keys, reuse behavior, static methods, and revalidation behavior are the same as [`query`](/solid-router/reference/data-apis/query).
11943

120-
## Methods
44+
## Examples
12145

122-
### `.key` and `.keyFor`
46+
### Basic usage
12347

124-
Cached functions provide `.key` and `.keyFor`, are useful when retrieving the keys used in cases involving invalidation:
48+
```tsx
49+
import { cache } from "@solidjs/router";
12550

126-
```ts
127-
let id = 5;
128-
getUser.key; // returns "users"
129-
getUser.keyFor(id); // returns "users[5]"
51+
const getUser = cache(async (id: string) => {
52+
const response = await fetch(`/api/users/${id}`);
53+
return response.json();
54+
}, "user");
13055
```
13156

132-
### `revalidate`
57+
## Related
13358

134-
The cache can be revalidated using the `revalidate` method or the `revalidate` keys that are set on the response from the actions.
135-
If the entire key is passed, it will invalidate all entries for the cache (ie. `users` in the example above).
136-
If only a single entry needs to be invalidated, `keyFor` is provided.
137-
To revalidate everything in the cache, pass `undefined` as the key.
59+
- [`query`](/solid-router/reference/data-apis/query)

0 commit comments

Comments
 (0)