# Usage with React

## Introduction

Aragon Connect provides a series of utilities that simplify the usage of Aragon Connect in a React environment.

It consists of the `<Connect />` component, through which a connection to an organization is described, and a series of hooks: `useApp()`, `useApps()`, `useOrganization()`, `usePermissions()`.

To get started, add the `@aragon/connect-react` package to your project. It contains all the exports of the `@aragon/connect`, so you don’t have to install both.

## Usage

```jsx
import {
  Connect,
  useApps,
  useOrganization,
  usePermissions,
} from '@aragon/connect-react'

function App() {
  const [org, orgStatus] = useOrganization()

  const [apps, appsStatus] = useApps()
  const [permissions, permissionsStatus] = usePermissions()

  const loading =
    orgStatus.loading || appsStatus.loading || permissionsStatus.loading
  const error = orgStatus.error || appsStatus.error || permissionsStatus.error

  if (loading) {
    return <p>Loading…</p>
  }

  if (error) {
    return <p>Error: {error.message}</p>
  }

  return (
    <>
      <h1>{org.name}</h1>

      <h2>Apps</h2>
      <ul>
        {apps.map((app, i) => (
          <li key={i}>{app.name}</li>
        ))}
      </ul>

      <h2>Permissions</h2>
      <ul>
        {permissions.map((permission, i) => (
          <li key={i}>{String(permission)}</li>
        ))}
      </ul>
    </>
  )
}

ReactDOM.render(
  <Connect location="myorg.aragonid.eth" connector="thegraph">
    <App />
  </Connect>,
  document.querySelector('main')
)
```

## API

### \<Connect />

This component is required in order to use the provided hooks.

| Props              | Type                                                                    | Description                                                                                              |
| ------------------ | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `location`         | `String`                                                                | The Ethereum address or ENS domain of an Aragon organization.                                            |
| `connector`        | `Connector` or `[String, Object]` or `String`                           | Accepts a `Connector` instance, and either a string or a tuple for embedded connectors and their config. |
| `options`          | `Object`                                                                | The optional configuration object.                                                                       |
| `options.ethereum` | `EthereumProvider`                                                      | An [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) compatible object.                                |
| `options.network`  | [`Networkish`](/developers/tools/aragon-connect/api-reference/types.md) | The network to connect to. Defaults to `1`.                                                              |

### useOrganization()

| Props   | Type                                                                                  | Description                                                                                                                         |
| ------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| returns | `[Organization \| null, { loading: boolean, error: null \| Error, retry: Function }]` | An array containing the [organization](/developers/tools/aragon-connect/api-reference/organization.md) and a loading status object. |

### useApp(appFilters)

| Name                | Type                                                                         | Description                                                                                                                                                                                                                                                   |
| ------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `appFilter`         | `String` or `Object` (optional)                                              | When a string is passed, the app will get searched by address if it starts by `0x`, and by `appName` otherwise. See `appFilter.address` and `appFilter.appName` to set them explicitly. For the time being, only one type of filter can get passed at a time. |
| `appFilter.address` | `String`                                                                     | Same as `appFilter`, but makes the selection by `address` explicit.                                                                                                                                                                                           |
| `appFilter.appName` | `String`                                                                     | Same as `appFilter`, but makes the selection by `appName` explicit.                                                                                                                                                                                           |
| returns             | `[App \| null, { loading: boolean, error: null \| Error, retry: Function }]` | An array containing a single [app](/developers/tools/aragon-connect/api-reference/app.md) from the organization and a loading status object.                                                                                                                  |

### usePermissions()

| Name    | Type                                                                          | Description                                                                                                                                   |
| ------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| returns | `[Permission[], { loading: boolean, error: null \| Error, retry: Function }]` | An array containing the organization [permissions](/developers/tools/aragon-connect/api-reference/permission.md) and a loading status object. |

### createAppHook()

This utility function makes app connectors available in your React app.

This is how it works at the most basic level:

```jsx
import { createAppHook, useApp } from '@aragon/connect-react'
import connectVoting from '@aragon/connect-voting'

// We create a hook corresponding to the app connector. This is usually enough,
// since the app connector will inherit from the connection set on <Connect />.
const useVoting = createAppHook(connectVoting)

function Votes() {
  const [voting] = useApp('voting')

  // And this is how we can use it, by passing the app instance and a callback.
  const [votes] = useVoting(voting, (app) => app.votes())

  return (
    <ul>
      {votes ? (
        votes.map((vote) => <li key={vote.id}>{formatVote(vote)}</li>)
      ) : (
        <li>Loading votes…</li>
      )}
    </ul>
  )
}
```

#### Dependency array

By default, the callback will be called once, and never update afterwards. This can be a problem if you want to reload data depending on the current state. This is why the hook also accept a dependency parameter. It behaves in a very similar way to the `useEffect()` or `useMemo()` hooks, except that it doesn’t update the callback when omitted.

This is how you can use it:

```jsx
import connect from '@aragon/connect'
import connectVoting from '@aragon/connect-voting'
import { createAppHook, useApp } from '@aragon/connect-react'

const useVoting = createAppHook(connectVoting)

function App() {
  const [page, setPage] = useState(0)
  const [voting] = useApp('voting')

  const [votes] = useVoting(
    voting,
    (app) => app.votes({ first: 10, skip: 10 * page }),
    [page]
  )

  return (
    <div>
      <ul>
        {votes ? (
          votes.map((vote) => <li key={vote.id}>{formatVote(vote)}</li>)
        ) : (
          <li>Loading votes…</li>
        )}
      </ul>
      <button onClick={() => setPage(page + 1)}>prev</button>
      <button onClick={() => setPage(page - 1)}>next</button>
    </div>
  )
}
```

#### Subscriptions

An issue with the previous examples is that we only fetch the data once, instead of receiving updates from it. For example, someone might create a new vote, and it is reasonable to expect an app to reflect that. With the app connectors API, you generally have `onX` equivalents of the async methods, like `votes(filters)` and `onVotes(filters, callback)`.

Using them with `createAppHook()` hooks requires to call the `onX` equivalent of the async method you want to use, but without passing a callback. App connectors return a partially applied function when the callback is omitted, which `createAppHook()` takes advantage of by entirely managing the subscription.

```jsx
import connect from '@aragon/connect'
import connectVoting from '@aragon/connect-voting'
import { createAppHook, useApp } from '@aragon/connect-react'

const useVoting = createAppHook(connectVoting)

function App() {
  const [page, setPage] = useState(0)
  const [voting] = useApp('voting')

  // votes will now get updated automatically
  const [votes] = useVoting(
    voting,

    // Note that we are now using onVotes() rather than votes()
    (app) => app.onVotes({ first: 10, skip: 10 * page }),

    // When page changes, a new subscription will replace the previous one
    [page]
  )

  return (
    <div>
      <ul>
        {votes ? (
          votes.map((vote) => <li key={vote.id}>{formatVote(vote)}</li>)
        ) : (
          <li>Loading votes…</li>
        )}
      </ul>
      <button onClick={() => setPage(page + 1)}>prev</button>
      <button onClick={() => setPage(page - 1)}>next</button>
    </div>
  )
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://legacy-docs.aragon.org/developers/tools/aragon-connect/guides/usage-with-react.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
