# React

> Draw an answer with the Answer component in React 18 or later. It reads the text as it grows, so you can pass your streamed text straight in.

```sh
npm install @morphscreen/web
```

`<Answer>` takes the core and the answer's text so far. When `text` grows, only the new part is read, so you can set it on every chunk. Set `done` when the answer is complete.

```tsx
import { useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
import { loadCore, type Core } from "@morphscreen/web";
import { Answer } from "@morphscreen/web/react";
import "@morphscreen/web/morphscreen.css";
import wasm from "@morphscreen/web/morphscreen.wasm?url";
import { SAMPLE } from "./sample";

function App() {
  const [core, setCore] = useState<Core | null>(null);
  const [text, setText] = useState("");
  useEffect(() => {
    loadCore(wasm).then(setCore);
  }, []);
  // Your server's stream goes here; this grows a saved answer piece by piece.
  useEffect(() => {
    if (!core) return;
    let n = 0;
    const t = setInterval(() => {
      n += 24;
      setText(SAMPLE.slice(0, n));
      if (n >= SAMPLE.length) clearInterval(t);
    }, 10);
    return () => clearInterval(t);
  }, [core]);
  const done = text.length >= SAMPLE.length;
  useEffect(() => {
    if (done) document.body.dataset.done = "yes";
  }, [done]);
  return core ? <Answer core={core} text={text} done={done} /> : null;
}

createRoot(document.getElementById("root")!).render(<App />);
```

With Vite, `?url` turns the package's `morphscreen.wasm` into an address it serves with your app.

## Its props

| Prop | What it is |
|---|---|
| `core` | from `loadCore` |
| `text` | the answer so far; or `stream`, an async iterable of chunks |
| `done` | the answer is complete |
| `packs`, `custom`, `components` | the packs and your own components ([Your own components](/docs/format/custom-components)) |
| `onAction` | what the reader did ([Actions and state](/docs/format/actions)) |
| `imageHosts`, `maps`, `maplibre` | where pictures and map tiles load from ([Pictures, icons and maps](/docs/format/media)) |
| `className` | your classes for the answer's element |

For a whole conversation, use `connectAgent` in an effect ([Quick start](/docs/quickstart)), or `<Answer>` once per message.
