Skip to content

Commit 79fa8ec

Browse files
committed
docs(migration): cover STORE_WRITE_OUTSIDE_SETTER and UNCOMMITTED_INPUT_OVERWRITTEN in From React
1 parent 41370aa commit 79fa8ec

1 file changed

Lines changed: 20 additions & 18 deletions

File tree

‎src/routes/(6)migration/(5)from-react.mdx‎

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ setState((draft) => {
207207
Every reader of `state.todos` runs again, and `For` recreates the toggled row instead of updating it.
208208
With attribution enabled, development reports [`[IMMUTABLE_UPDATE_IN_STORE]`](/reference/solid-js/diagnostics/immutable-update-in-store).
209209
Change the item in place, as `toggle` does above.
210-
A write outside the setter, such as `state.todos.push(todo)`, does nothing, and nothing reports it.
210+
A write outside the setter, such as `state.todos.push(todo)`, is ignored, and development reports [`[STORE_WRITE_OUTSIDE_SETTER]`](/reference/solid-js/diagnostics/store-write-outside-setter).
211211
:::
212212

213213
## Derive values from state
@@ -509,6 +509,7 @@ return (
509509

510510
`onInput` observes each browser input event.
511511
Use `onChange` when the native change event timing is the intended behavior.
512+
With `onChange` and a bound `value`, keep the typed text in a draft signal written from `onInput`: if another attribute in the same template changes, the binding re-runs and erases text that was never committed.
512513

513514
Event handlers run outside reactive tracking.
514515
They can read current signal and store values without subscribing to them.
@@ -1203,23 +1204,24 @@ The [routing overview](/routing/overview) describes the router-independent appli
12031204
Each of these React habits compiles in Solid and then misbehaves.
12041205
Development builds report most of them by code; codes marked "attribution" appear once `attribution.enable()` from `solid-js/attribution` is running, as [Debugging reactivity](/guides/debugging-reactivity) describes.
12051206

1206-
| React habit | What happens in Solid | What reports it |
1207-
| ---------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
1208-
| Destructuring props, or reading a prop or signal at the top of the component | The value never updates | [`STRICT_READ_UNTRACKED`](/reference/solid-js/diagnostics/strict-read-untracked) |
1209-
| An early `return` that depends on props | The component stays on its first branch | [`STRICT_READ_UNTRACKED`](/reference/solid-js/diagnostics/strict-read-untracked) |
1210-
| Calling a translator in the body: `const label = t("save")` | The text keeps its first language | [`STRICT_READ_UNTRACKED`](/reference/solid-js/diagnostics/strict-read-untracked) if `t` reads a signal; nothing if it reads a plain variable |
1211-
| Passing the accessor: `value={count}` | The child receives a function | A TypeScript error |
1212-
| Building fresh objects for list items on each update | `For` recreates every row, and focus and input state are lost | [`UNSTABLE_LIST_IDENTITY`](/reference/solid-js/diagnostics/unstable-list-identity) (attribution); key by ID with `keyed={(item) => item.id}` |
1213-
| Copying a derived value into state from an effect | The copy is one update behind | [`EFFECT_RELAY_TEAR`](/reference/solid-js/diagnostics/effect-relay-tear) (attribution) |
1214-
| Setting state during render | Throws | [`REACTIVE_WRITE_IN_OWNED_SCOPE`](/reference/solid-js/diagnostics/reactive-write-in-owned-scope) |
1215-
| Translating `useEffect(fn)` to `createEffect(fn)` | Throws | [`MISSING_EFFECT_FN`](/reference/solid-js/diagnostics/missing-effect-fn) |
1216-
| Reading a signal inside the effect function | The effect does not re-run when it changes | [`STRICT_READ_UNTRACKED`](/reference/solid-js/diagnostics/strict-read-untracked) |
1217-
| Reading a signal after `await` in an async memo | The memo does not re-run when it changes | [`UNTRACKED_READ_AFTER_AWAIT`](/reference/solid-js/diagnostics/untracked-read-after-await) (V8 engines) |
1218-
| Writing a store outside its setter | Nothing happens | Nothing |
1219-
| `createContext<T \| undefined>(undefined)` for an optional context | `useContext` throws without a provider | `ContextNotFoundError`; use `null` as the default |
1220-
| `onClick={ready() ? save : wait}` | The first handler stays bound | Nothing; decide inside one handler |
1221-
| A lowercase `onclick` | The handler is never attached | [`LOWERCASE_EVENT_ATTRIBUTE`](/reference/solid-js/diagnostics/lowercase-event-attribute) |
1222-
| A controlled input whose handler rejects a keystroke | The rejected text stays in the field | Nothing; assign `event.currentTarget.value` in the handler |
1207+
| React habit | What happens in Solid | What reports it |
1208+
| ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
1209+
| Destructuring props, or reading a prop or signal at the top of the component | The value never updates | [`STRICT_READ_UNTRACKED`](/reference/solid-js/diagnostics/strict-read-untracked) |
1210+
| An early `return` that depends on props | The component stays on its first branch | [`STRICT_READ_UNTRACKED`](/reference/solid-js/diagnostics/strict-read-untracked) |
1211+
| Calling a translator in the body: `const label = t("save")` | The text keeps its first language | [`STRICT_READ_UNTRACKED`](/reference/solid-js/diagnostics/strict-read-untracked) if `t` reads a signal; nothing if it reads a plain variable |
1212+
| Passing the accessor: `value={count}` | The child receives a function | A TypeScript error |
1213+
| Building fresh objects for list items on each update | `For` recreates every row, and focus and input state are lost | [`UNSTABLE_LIST_IDENTITY`](/reference/solid-js/diagnostics/unstable-list-identity) (attribution); key by ID with `keyed={(item) => item.id}` |
1214+
| Copying a derived value into state from an effect | The copy is one update behind | [`EFFECT_RELAY_TEAR`](/reference/solid-js/diagnostics/effect-relay-tear) (attribution) |
1215+
| Setting state during render | Throws | [`REACTIVE_WRITE_IN_OWNED_SCOPE`](/reference/solid-js/diagnostics/reactive-write-in-owned-scope) |
1216+
| Translating `useEffect(fn)` to `createEffect(fn)` | Throws | [`MISSING_EFFECT_FN`](/reference/solid-js/diagnostics/missing-effect-fn) |
1217+
| Reading a signal inside the effect function | The effect does not re-run when it changes | [`STRICT_READ_UNTRACKED`](/reference/solid-js/diagnostics/strict-read-untracked) |
1218+
| Reading a signal after `await` in an async memo | The memo does not re-run when it changes | [`UNTRACKED_READ_AFTER_AWAIT`](/reference/solid-js/diagnostics/untracked-read-after-await) (V8 engines) |
1219+
| Writing a store outside its setter | The write is ignored | [`STORE_WRITE_OUTSIDE_SETTER`](/reference/solid-js/diagnostics/store-write-outside-setter) |
1220+
| `createContext<T \| undefined>(undefined)` for an optional context | `useContext` throws without a provider | `ContextNotFoundError`; use `null` as the default |
1221+
| `onClick={ready() ? save : wait}` | The first handler stays bound | Nothing; decide inside one handler |
1222+
| A lowercase `onclick` | The handler is never attached | [`LOWERCASE_EVENT_ATTRIBUTE`](/reference/solid-js/diagnostics/lowercase-event-attribute) |
1223+
| A controlled input whose handler rejects a keystroke | The rejected text stays in the field | Nothing; assign `event.currentTarget.value` in the handler |
1224+
| `value={props.name} onChange={commit}` with no draft signal | When another attribute in the same template changes, the binding re-runs and erases the typed text | [`UNCOMMITTED_INPUT_OVERWRITTEN`](/reference/solid-js/diagnostics/uncommitted-input-overwritten); write a draft signal from `onInput`, or use `defaultValue` |
12231225

12241226
## Review the translation
12251227

0 commit comments

Comments
 (0)