|
9 | 9 | - scopes |
10 | 10 | - disposal |
11 | 11 | - tracking |
12 | | -version: '1.0' |
| 12 | +version: "1.0" |
13 | 13 | description: >- |
14 | 14 | Create non-tracked owner scopes in SolidJS for manual memory management. |
15 | 15 | Essential for nested tracking scopes and preventing auto-disposal. |
16 | 16 | --- |
17 | 17 |
|
| 18 | +The `createRoot` function creates a new owned context, which requires explicit disposal of computations it owns. |
| 19 | + |
| 20 | +## Import |
| 21 | + |
| 22 | +```ts |
| 23 | +import { createRoot } from "solid-js"; |
| 24 | +``` |
| 25 | + |
| 26 | +## Type |
| 27 | + |
| 28 | +```ts |
| 29 | +function createRoot<T>( |
| 30 | + fn: (dispose: () => void) => T, |
| 31 | + detachedOwner?: Owner |
| 32 | +): T; |
| 33 | +``` |
| 34 | + |
| 35 | +## Parameters |
| 36 | + |
| 37 | +### `fn` |
| 38 | + |
| 39 | +- **Type:** `(dispose: () => void) => T` |
| 40 | +- **Required:** Yes |
| 41 | + |
| 42 | +The function executes within a newly created owned context. |
| 43 | +The computations created within this function are managed by the root and will only be disposed of when the provided `dispose` function is called. |
| 44 | + |
| 45 | +If a function is passed without a `dispose` parameter, an unowned root is created. |
| 46 | +In this case, the computations are not managed for disposal, which may lead to memory leaks. |
| 47 | + |
| 48 | +This function itself does not track dependencies and only runs once. |
| 49 | + |
| 50 | +### `detachedOwner` |
| 51 | + |
| 52 | +- **Type:** `Owner` |
| 53 | +- **Required:** No |
| 54 | + |
| 55 | +An optional owner that establishes the root's position in the ownership hierarchy. |
| 56 | +When provided, the root becomes owned by this owner and inherits its contextual state (such as [contexts](/concepts/context)). |
| 57 | + |
| 58 | +## Return Value |
| 59 | + |
| 60 | +`createRoot` returns the value returned by the `fn` function. |
| 61 | + |
| 62 | +## Examples |
| 63 | + |
| 64 | +### Basic Usage |
| 65 | + |
| 66 | +```ts |
| 67 | +import { createSignal, createEffect, createRoot } from "solid-js"; |
| 68 | + |
| 69 | +function createCounter(initial = 0) { |
| 70 | + const [count, setCount] = createSignal(initial); |
| 71 | + |
| 72 | + createEffect(() => { |
| 73 | + console.log(`Count changed, new value: ${count()}`); |
| 74 | + }); |
| 75 | + |
| 76 | + function increment() { |
| 77 | + setCount((c) => c + 1); |
| 78 | + } |
| 79 | + |
| 80 | + function reset() { |
| 81 | + setCount(initial); |
| 82 | + } |
| 83 | + |
| 84 | + return { count, increment, reset }; |
| 85 | +} |
| 86 | + |
| 87 | +test("createCounter works correctly", () => { |
| 88 | + createRoot((dispose) => { |
| 89 | + const { count, increment, reset } = createCounter(10); |
| 90 | + |
| 91 | + expect(count()).toBe(10); |
| 92 | + increment(); |
| 93 | + expect(count()).toBe(11); |
| 94 | + reset(); |
| 95 | + expect(count()).toBe(10); |
| 96 | + |
| 97 | + dispose(); |
| 98 | + }); |
| 99 | +}); |
| 100 | +``` |
| 101 | + |
| 102 | +### Returning Values |
| 103 | + |
18 | 104 | ```ts |
19 | | -import { createRoot } from "solid-js" |
| 105 | +import { createRoot, createSignal, onCleanup } from "solid-js"; |
| 106 | + |
| 107 | +const counter = createRoot((dispose) => { |
| 108 | + const [count, setCount] = createSignal(0); |
| 109 | + |
| 110 | + onCleanup(() => { |
| 111 | + console.log("Dispose was called!"); |
| 112 | + }); |
20 | 113 |
|
21 | | -function createRoot<T>(fn: (dispose: () => void) => T): T |
| 114 | + return { |
| 115 | + value: count, |
| 116 | + increment: () => setCount((c) => c + 1), |
| 117 | + dispose, |
| 118 | + }; |
| 119 | +}); |
22 | 120 |
|
| 121 | +console.log(counter.value()); // 0 |
| 122 | +counter.increment(); |
| 123 | +console.log(counter.value()); // 1 |
| 124 | +counter.dispose(); // Logs "Dispose was called!" |
23 | 125 | ``` |
24 | 126 |
|
25 | | -Creates a new non-tracked owner scope that doesn't auto-dispose. |
26 | | -This is useful for nested tracking scopes that you do not wish to release when the parent re-evaluates. |
| 127 | +## Related |
27 | 128 |
|
28 | | -All Solid code should be wrapped in one of these top level as they ensure that all memory/computations are freed up. |
29 | | -Normally you do not need to worry about this as createRoot is embedded into all render entry functions. |
| 129 | +- [`render`](/reference/rendering/render) |
0 commit comments