> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryreason.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# React library

> Use RΞASON with React with ease

RΞASON has a React package called `tryreason-react` that is the recommend way to integrate with your backend RΞASON app.

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm i tryreason-react
  ```

  ```bash pnpm theme={null}
  pnpm i tryreason-react
  ```

  ```bash bun theme={null}
  bun i tryreason-react
  ```

  ```bash yarn theme={null}
  yarn add tryreason-react
  ```
</CodeGroup>

## `tryreason-react`

`tryreason-react` provides two hooks:

* `useReason()`: calls RΞASON and returns the results for you (be that streaming or not);
* `useChat()`: this is made for *chat-like* agents that use the [default agent streaming behaviour](/docs/essentials/agents#agent-streaming-behaviour). When interacting *chat-like* agents, this is the recommend hook to use.

## `useReason()` hook

```ts theme={null}
import { useReason } from 'tryreason-react'

export default function Component() {
  const {
    data,
    reason,
    onFinish,
    onError,
    isLoading,
    isStreaming
  } = useReason('http://reason-app-url:reasonPort/your-entrypoint')

  function callReason() {
    reason()
  }

  onFinish(() => {
    alert('End of request')
  })

  onError(() => {
    alert('Error happened')
  })
  
  return (
    <>
      <button onClick={callReason}>Call RΞASON</button>

      <pre>{JSON.stringify(data, null, 2)}</pre>
    </>
  )
}
```

* `data`: The data your app returns;
* `reason`: A function that actually makes the request to your app;
* `onFinish`: A callback to handle when RΞASON stop streaming;
* `onError`: A callback that'll get called if RΞASON errors;
* `isLoading`: Whenever a request is made but has no streaming response has arrived yet. This will be `false` as soon as the first response comes;
* `isStreaming`: This becomes `true` when the first streaming byte comes. It remains `true` while your app continues to stream more data.

### Options

The `reason()` function that `useReason()` returns accepts a parameter that can contain some options:

```ts theme={null}
import { useReason } from 'tryreason-react'

export default function Component() {
  const { data, reason } = useReason('http://reason-app-url:reasonPort/your-entrypoint')

  function callReason() {
    // 👇 Here
    reason({
      method: 'POST'
      body: {},
      headers: {},
    })
  }

  return (
    <>
      <button onClick={callReason}>Call RΞASON</button>

      <pre>{JSON.stringify(data, null, 2)}</pre>
    </>
  )
}
```

## `useChat()` hook

If your entrypoint calls a *chat-like* agent with the [default agent streaming behaviour](/docs/essentials/agents#agent-streaming-behaviour) this hook is your best-friend.

Here's how you can use the `useChat()` hook:

```ts theme={null}
'use client'
import { useChat } from 'tryreason-react'

export default function Component() {
  const { messages, input, handleInputChange, handleSubmit } = useChat('http://reason-app-url:reasonPort/your-entrypoint')

  return (
    <div>
      <div>
        {messages.map((message, idx) => (
          <pre key={idx}>
            {JSON.stringify(message, null, 2)}
          </pre>
        ))}
      </div>

      <form onSubmit={handleSubmit}>
        <input type="text" value={input} onChange={handleInputChange} />
        <button type="submit">Send</button>
      </form>
    </div>
  )
}
```

<br />

<Info>
  By the way, if the above looks similar to Vercel's [AI SDK](https://sdk.vercel.ai/docs) to you, its because we took major inspiration from their React hooks. We believe its the best syntax for developers and we congralute Vercel for being the ones who created it.
</Info>

And we'll be testing it in the `MathAgent` we created in the [Agents page](/docs/essentials/agents#creating-your-first-agent).

<Accordion title="Don't remember about the MathAgent?">
  It's a basic agent that has access to `sum()`, `subtract()`, `multiply()` and `divide()` actions.

  Its objective is to use the available actions to solve basic math problems.
</Accordion>

### Showcase

<Frame caption="useChat() in action">
  <video muted controls loop playsinline src="https://tryreason.b-cdn.net/or1.mp4" />
</Frame>

### Properties

```ts theme={null}
'use client'
import { useChat } from 'tryreason-react'

export default function Component() {
  const {
    messages,
    input,
    handleInputChange,
    handleSubmit,
    memoryID,
    clear,
    onFinish,
    onError,
    isLoading,
    isStreaming,
  } = useChat('http://reason-app-url:reasonPort/your-entrypoint')

  return (
    <div>
      // ...
    </div>
  )
}
```

* `messages`: Array containing all the chat messages;
* `input`: The input for the user to type its message;
* `handleInputChange`: The function to pass to `<input type="text" onChange={handleInputChange} value={input} />`;
* `handleSubmit`: The function to call when the user wants to send its message;
* `memoryID`: The [memory ID](/docs/essentials/agents#about-memory-id) of the chat;
* `clear`: A function that when called will clear all messages in order for the user to start a new chat;
* `onFinish`: A callback to handle when RΞASON stop streaming;
* `onError`: A callback that'll get called if RΞASON errors;
* `isLoading`: Whenever a request is made but has no streaming response has arrived yet. This will be `false` as soon as the first response comes;
* `isStreaming`: This becomes `true` when the first streaming byte comes. It remains `true` while your app continues to stream more data.

### Options

Similar to `useReason()` you can also pass some request options to `useChat()`:

```ts theme={null}
'use client'
import { useChat } from 'tryreason-react'

export default function Component() {
  const {
    messages,
    input,
    handleInputChange,
    handleSubmit 
  } = useChat('http://reason-app-url:reasonPort/your-entrypoint', {
    body: {},
    headers: {}
  })

  return (
    <div>
      // ...
    </div>
  )
}
```

<br />

<Warning>
  `useChat()` only support using `POST` requests.
</Warning>
