# Coming from React or Solid

Source: https://signy.dev/documentation/1/overview/coming-from-react/

The Signy version of what you already know.

Signy has fine grained reactivity like Solid and class components like older React. Two ideas carry over from Solid and surprise React users: `render()` runs once, and only functions bound in the template update. See [How Signy works](https://signy.dev/documentation/1/overview/how-signy-works/index.html.md).

## From React

| React | Signy |
| --- | --- |
| `function App() { ... }` | `class App extends Component { render() { ... } }`, and `render()` runs once |
| `const [count, setCount] = useState(0)` | `count = new Signal(0)`, then `this.count.value` and `this.count.value = 1` |
| `setCount((c) => c + 1)` | `this.count.set((c) => c + 1)` |
| `{count}` in JSX | `${() => this.count.value}` in `html`, or `{this.count.value}` in [compiled JSX](https://signy.dev/documentation/1/overview/jsx-and-typescript/index.html.md) |
| `useMemo(() => a * b, [a, b])` | `new Computed(() => this.a.value * this.b.value)`, no dependency list |
| `useEffect(fn, [dep])` | `effect(fn)` in `setup()`, it tracks what it reads |
| `useEffect(() => ..., [])` | `this.onMount(() => ...)` |
| The cleanup returned from `useEffect` | `onCleanup()` in an effect, or the function returned from `onMount` |
| `useRef()` for an element | `createRef()` and `ref=${this.input}` |
| `useRef()` for a value | A plain class field |
| `createContext`, `useContext` | `createContext()`, `Ctx.provide(this, value)`, `Ctx.inject(this)` |
| `{ok && <Panel />}` | `Show({ when: () => ok.value, children: ... })` |
| `items.map((item) => <Row key={item.id} />)` | `For({ each: () => items.value, keyBy: 'id', children: ... })` |
| `React.lazy`, `<Suspense>` | `lazy()`, `Suspense` |
| `createPortal` | `Portal` |
| Error boundary class | `ErrorBoundary({ fallback, children })` |
| `useTransition` | `useTransition()`, which batches writes into the next microtask and does not interrupt rendering, see [Transitions](https://signy.dev/documentation/1/reactivity/transitions/index.html.md) |
| `className`, `htmlFor` | `class`, `for` |
| `ReactDOM.createRoot(el).render(<App />)` | `application(App).mount(el)` |

### Habits to drop

- **Re-rendering.** Nothing re-renders a component. A value read outside a function binding stays as it was at render time.
- **Dependency arrays.** Effects and computeds track what they read. A signal read in an effect is a dependency, so read the ones you do not want with `untrack()`.
- **Controlled inputs.** `value=${() => ...}` sets the attribute. Read input in `onInput` and reset the field through a ref, see [Refs and forms](https://signy.dev/documentation/1/components/refs-and-forms/index.html.md#forms).
- **Props that change.** Props are read once. Pass a function and call it in a binding, see [Props that change](https://signy.dev/documentation/1/components/props-and-children/index.html.md#props-that-change).
- **Synchronous updates.** The DOM updates in a microtask after a write. In tests, call `flushAll()`.

## From Solid

| Solid | Signy |
| --- | --- |
| `const [count, setCount] = createSignal(0)` | `const count = signal(0)`, read `count.value`, write `count.value = 1` |
| `createMemo(fn)` | `computed(fn)` |
| `createEffect(fn)` | `effect(fn)`, first run in a microtask |
| `on(dep, fn)` | `on(dep, fn)`, but `fn` is tracked too, see [on()](https://signy.dev/documentation/1/reactivity/effects/index.html.md#on) |
| `createRoot`, `onCleanup`, `untrack`, `batch` | The same names |
| `onMount` | `this.onMount()` on a component |
| `createSelector` | `createSelector`, which returns a signal: `isSelected(id).value` |
| `createStore`, `produce`, `unwrap` | `store()` with `.state` and `.set()`, `produce`, `unwrap` |
| `createResource` | `resource()`, which does not suspend |
| `Show`, `For`, `Index`, `Switch`, `Match`, `Portal`, `ErrorBoundary` | The same, callable as functions or used as tags |
| `lazy`, `Suspense` | The same |
| `createContext`, `useContext` | `createContext()`, then `provide(this, value)` and `inject(this)` on a component |
| Function components | Class components, with signals as fields |
| Solid Router | The built in [router](https://signy.dev/documentation/1/router/routes/index.html.md) |
| JSX through `babel-preset-solid` | The `html` template with no build, or JSX through `babel-plugin-jsx-dom-expressions` |

### Differences to watch

- **Accessors.** A signal is an object with `.value`, not a getter function. Pass `() => count.value` where Solid takes `count`.
- **Timing.** An `effect()` first runs in a microtask, after `mount()` has returned. Template bindings render synchronously, as in Solid.
- **Resources and Suspense.** A resource never triggers `Suspense`. Only `lazy()` does.
- **Store writes.** Assigning to `store.state` works and notifies. Solid stores are read only outside the setter.
