Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions documentation/solid-2.0/05-async-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ const user = createMemo(() => {
// `Promise.resolve(value)` inside the compute is the fake too, and never settles either.
```

A cached dynamic `import()` hangs the same way ([#4332](https://github.com/solidjs/solid/issues/4332)). In a Vite build every `import()` goes through `__vitePreload`, which starts from `Promise.resolve()` read off the global at call time, so the module promise stored in a de-duplication map during the tracking run is the fake. The memo itself hydrates from the server's value, so the page looks right; the next caller that hits the map (a later mount, a navigation) waits forever and no request for the chunk is made. Use `lazy()` for components (it already refuses to cache a load made during a trace), and keep a module cache out of hydrated computes or apply the rule below.

The rule for a cache seeded from hydration data: while `isHydrating()` (`solid-js`) is true, treat the seeded value as fresh, and do not populate the cache by running the fetcher. To wrap a hydrated value in a real promise, capture the constructor at module load. The fakes only replace the global inside the window.

```js
Expand Down
2 changes: 2 additions & 0 deletions packages/babel-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Solid 2.0's Babel compiler integration. Configure this plugin once in a Babel pi

The native Oxc compiler — [`@solidjs/compiler`](../compiler) — is the default in `vite-plugin-solid`. Use this plugin when you need a Babel pipeline (or as the JavaScript fallback).

It runs on `@babel/core` 7 (7.20.12 or later) and 8.

> **Solid 2.0 (Release Candidate).** Pin exact versions.

## Features
Expand Down
17 changes: 16 additions & 1 deletion packages/solid/CHEATSHEET.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
untrack,
flush,
onSettled,
onFlush,
createContext,
useContext,
children,
Expand Down Expand Up @@ -140,7 +141,19 @@ onSettled(() => {
});
```

`onSettled` works in component bodies (after first reactive settle) **and** in event handlers (defer work until the triggered transition settles). For component-level setup-and-teardown, **use `onSettled` with a returned cleanup, not `onCleanup` directly** — `onCleanup` is reserved for reactive cleanup inside computations (see Advanced).
`onSettled` works in component bodies (after first reactive settle) **and** in event handlers (defer work until the triggered transition settles).

```ts
// Keep a write out of another update's hold: runs once right after the
// pending flush, never waits on async. For event handlers and effect
// callbacks (dev warns ON_FLUSH_IN_OWNED_SCOPE in a body or computation).
const select = (id: string) => {
onFlush(() => setOpen(false)); // closes now even if onSelect navigates
props.onSelect?.(id);
};
```

For component-level setup-and-teardown, **use `onSettled` with a returned cleanup, not `onCleanup` directly** — `onCleanup` is reserved for reactive cleanup inside computations (see Advanced).

---

Expand Down Expand Up @@ -573,6 +586,8 @@ return <li class={cls} />;
import { renderToString, renderToStream, isServer, isDev } from "@solidjs/web";
```

Hydration adopts each async read the server answered (value or error) and never asks again; a hydrated `<Errored>` keeps the server's fallback until an input changes or `reset()`. Adopted computes still run once to track reads, with the global `Promise` and `fetch` faked (never settle): don't cache promises or `import()`s created in a compute.

`Portal` throws on the server. `Reveal` `order="together"` and `collapsed` require streaming (`renderToStream` — awaiting it yields the fully settled HTML string).

---
Expand Down
8 changes: 8 additions & 0 deletions packages/solid/skills/solid-2.0/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ Also:
The memo's `equals` (default `===`) stops the re-run.
- No writes inside a memo, effect compute, or component body (dev throws).
Write from event handlers, `onSettled`, or actions.
- Writes in one synchronous frame land together: if one starts async work
(a navigation, a refetch), the rest are held with it. To land a write on
its own (close a menu before calling `props.onSelect`), wrap it in
`onFlush(() => setOpen(false))`. Not `queueMicrotask` or `setTimeout`.
- Hydration adopts server answers without re-asking, but runs each adopted
compute once to track reads with fake `Promise`/`fetch` that never settle.
Never store a promise or `import()` created inside a compute in a cache
that outlives it; cache resolved values, or start the load outside.
- No reactive reads at the top of a component body; read in JSX, a memo, or
`untrack`. Flow callbacks (`<For>`, `<Show>`, `<Match>`) are owners, not
tracking scopes: read their accessor arguments in JSX, not at the top.
Expand Down
Loading