# Migrating to v4

In v3 there was no React package - the docs handed you a `useForesight` hook to copy into your own project. v4 replaces that with the official [`@foresightjs/react`](/docs/react/installation.md) package. Install it, delete your copied file, and update a couple of names.

Install the package and delete your hand-rolled `useForesight.ts`:

```
npm install @foresightjs/react
```

Then update the import and the return shape:

```
- import useForesight from "./hooks/useForesight"
+ import { useForesight } from "@foresightjs/react"

- const { elementRef, registerResults } = useForesight({ callback, name })
+ const { elementRef, isRegistered, isPredicted } = useForesight({ callback, name })
```

What changed:

* **The state is flattened onto the return value.** There's no `registerResults` object anymore. `registerResults.isRegistered` becomes `isRegistered`, and you also get the rest of the reactive state (`isPredicted`, `isActive`, `hitCount`, …) which re-renders when it changes. See [useForesight](/docs/react/useForesight.md#reactive-state).
* **`elementRef` is now a callback ref.** You still attach it the same way (`ref={elementRef}`), so your JSX doesn't change.
* **`registerResults.isTouchDevice` is gone.** Touch devices are handled internally by the configured [`touchDeviceStrategy`](/docs/react/configuration/global-settings.md#touch-device-settings), so the manual fallback branch is no longer needed.

## Core changes[​](#core-changes "Direct link to Core changes")

The core `js.foresight` library also has a few breaking changes. The package handles most of these for you, but they matter if you call `register()` or listen to events directly.

The `register()` call itself is unchanged, but element data is now an immutable state snapshot you can subscribe to - the foundation the wrapper packages are built on:

* **`ForesightElementData` is now `ForesightElementState`.** Your callback receives the flat state snapshot: `callback: (state: ForesightElementState) => void`. See [TypeScript](/docs/getting-started/typescript.md).
* **`register()` returns the state plus `unregister`, `subscribe` and `getSnapshot`.** `isTouchDevice` is gone from the result; touch devices are handled internally by the configured `touchDeviceStrategy` global setting.
* **The `elementDataUpdated`, `elementOptionsUpdated` and `elementReactivated` events are removed.** Per-element changes are now observed through the `subscribe`/`getSnapshot` pair returned by `register()`. The remaining events carry the state in a `state` field instead of `elementData`.
* **Detached elements are parked, not unregistered.** Removing an element from the DOM no longer emits `elementUnregistered` with reason `disconnected`; the element stays registered but inactive and resumes when it reconnects.
* **New `enabled` element option.** Set it to `false` to keep an element registered but excluded from prediction.
