# Foresight component

`Foresight` is the component form of [`useForesight`](/docs/react/useForesight.md): one instance, one registration. It renders in one of two ways.

## Rendering an element with `as`[​](#rendering-an-element-with-as "Direct link to rendering-an-element-with-as")

With `as`, `Foresight` renders that element itself and registers it. All other props are forwarded to the element:

```
import { Foresight } from "@foresightjs/react"

function CheckoutButton() {
  return (
    <Foresight as="button" callback={() => prefetch("/checkout")} onClick={checkout}>
      Checkout
    </Foresight>
  )
}
```

`as` accepts any element tag (`"button"`, `"a"`, `"div"`, ...) or a component that forwards its ref to a DOM element.

You can pass your own `ref` (object or callback) to the rendered element. It is merged with the internal registration ref, so you keep direct access to the DOM node while `Foresight` still registers it.

### Reading state in `as` form[​](#reading-state-in-as-form "Direct link to reading-state-in-as-form")

To use the [reactive state](/docs/react/useForesight.md#reactive-state) in this form, pass a function as `children`, `className` or `style` — it receives the state. `Foresight` only subscribes to state-driven re-renders when one of them is a function:

```
<Foresight
  as="button"
  callback={() => prefetch("/checkout")}
  className={({ isPredicted }) => (isPredicted ? "predicted" : "")}
  style={({ isCallbackRunning }) => ({ opacity: isCallbackRunning ? 0.5 : 1 })}
>
  {({ hitCount }) => <>Checkout ({hitCount})</>}
</Foresight>
```

For full control over the rendered markup, use the render-prop form below or [`useForesight`](/docs/react/useForesight.md).

## Render-prop form[​](#render-prop-form "Direct link to Render-prop form")

With a function as children, `Foresight` renders nothing itself. The function receives the [reactive state](/docs/react/useForesight.md#reactive-state) plus the `elementRef` to attach, which gives full control over the markup:

```
import { Foresight } from "@foresightjs/react"

function CheckoutButton() {
  return (
    <Foresight foresightName="checkout" callback={() => prefetch("/checkout")}>
      {({ elementRef, isPredicted }) => (
        <button ref={elementRef} className={isPredicted ? "predicted" : ""}>
          Checkout
        </button>
      )}
    </Foresight>
  )
}
```

Whichever element you attach `elementRef` to gets registered, so the manager still mirrors its prediction state onto `data-*` attributes (unless you turn off the global [`setDataAttributes`](/docs/react/configuration/global-settings.md#setdataattributes)). Style it with plain CSS via those attributes, or read the reactive state directly as shown above.

## Options[​](#options "Direct link to Options")

`Foresight` takes the same options as [`useForesight`](/docs/react/useForesight.md), passed as props. The only renamed option is `name`, on the component it is `foresightName`, so the HTML `name` attribute (on `input`, `button`, `select`, ...) falls through to the element like any other prop.

## Dynamic lists[​](#dynamic-lists "Direct link to Dynamic lists")

`Foresight` can be rendered in a loop, registering one element per item.

```
import { Foresight } from "@foresightjs/react"

function Nav({ links }: { links: { href: string; label: string }[] }) {
  return (
    <nav>
      {links.map(link => (
        <Foresight
          as="a"
          key={link.href}
          href={link.href}
          foresightName={link.label}
          callback={() => prefetch(link.href)}
        >
          {link.label}
        </Foresight>
      ))}
    </nav>
  )
}
```
