https://github.com/elite174/solid-knowledge
This repo contains facts, gotchas, tips and non-obvious things about solid-js and related libs (router, start).
https://github.com/elite174/solid-knowledge
Last synced: 2 months ago
JSON representation
This repo contains facts, gotchas, tips and non-obvious things about solid-js and related libs (router, start).
- Host: GitHub
- URL: https://github.com/elite174/solid-knowledge
- Owner: elite174
- Created: 2024-07-12T03:56:15.000Z (11 months ago)
- Default Branch: master
- Last Pushed: 2024-08-14T03:27:52.000Z (9 months ago)
- Last Synced: 2024-08-14T04:44:26.816Z (9 months ago)
- Size: 6.84 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Hidden knowlege about solid-js
This repo contains non-obvious things, facts, gotchas and other useful knowledge related to `solid-js` (library itself, router, solid-start).
Feel free to contribute.
## Solid-js
### `Suspense` and accessing resources inside primitives
Accessing resource inside `createEffect` **won't trigger** `Suspense`, but accessing it inside `createComputed` or `createMemo` **will trigger** `Suspense`.
Example:
```tsx
import { render } from "solid-js/web";
import { createSignal, createResource, Suspense, createComputed, createEffect } from "solid-js";function Example() {
const [count, setCount] = createSignal(2);const [data] = createResource(
() =>
new Promise((resolve) => {
setTimeout(() => resolve(1), 3000);
})
);// `createEffect` won't trigger `Suspense`,
// but `createComputed` or `createMemo` will trigger.
createEffect(() => {
const value = data();if (value) setCount(value);
});return (
setCount((c) => c + 1)}>
{count()}
);
}render(
() => (
),
document.getElementById("app")!
);
```Possible explanation is [here](https://discord.com/channels/722131463138705510/722131463889223772/1261153998950371419)
## Solid-js router
### What is `createAsync`?
`createAsync` is just a wrapper (for now, in Solid 2.0 there'll be a change for that) over `createResource` ([source code](https://github.com/solidjs/solid-router/blob/main/src/data/createAsync.ts)). So when you call accessor from `createAsync` you **will trigger `Suspense`**:
```tsx
const data = createAsync(() => fetch(...));return
{/** This will trigger Suspense all the time when createAsync updates */
{data()}```
### How to avoid triggering `Suspense` with `createAsync`?
> [!NOTE]
> UPDATE for router `^0.14.2`: `createAsync` preserves `.latest` field (as for resources), so feel free to use this.For `createResource` we have `.latest` property which doesn't trigger `Suspense` on refetching. However there's no such thing for `createAsync`, what should we do in this case?
There's a small [hack](https://discord.com/channels/722131463138705510/1260246424508170321):
```tsx
function latest(signal: Accessor) {
const [latest, setLatest] = createSignal(createRoot(signal));createRoot(() => {
createMemo(() => setLatest(signal));
});if (latest() === undefined) return signal();
return latest();
}
```The point is that we're moving suspense tracking to another root, thus avoiding triggering suspense for the current root.
And you can use it inside JSX:
```tsx
const data = createAsync(() => fetch(...));return
{/** This won't trigger Suspense when createAsync updates */
{latest(data)}```