# React

> VimineProvider, useVimine e SignInButton da @vimine/sdk/react.

URL: https://developers.vimine.network/sdk/react/

```jsx
import { VimineProvider, useVimine, SignInButton } from '@vimine/sdk/react';
```

Un provider che possiede **un** client `Vimine`, gestisce il ritorno dall'accesso al montaggio ed espone la
sessione all'albero; un hook; un bottone. React ≥ 18 (peer dependency opzionale: l'SDK non la installa).

## Esempio

```jsx title="main.jsx"
import { Vimine } from '@vimine/sdk';
import { VimineProvider } from '@vimine/sdk/react';

const vimine = new Vimine({ clientId: 'vmc_…', redirectUri: `${location.origin}/vimine/callback` });

createRoot(document.getElementById('root')).render(
    <VimineProvider client={vimine} onSignedIn={({ returnTo }) => navigate(returnTo || '/')}>
        <App />
    </VimineProvider>
);
```

```jsx title="Tessera.jsx"
import { useEffect, useState } from 'react';
import { useVimine, SignInButton } from '@vimine/sdk/react';

export function Tessera() {
    const { client, isSignedIn, loading, signOut } = useVimine();
    const [tessera, setTessera] = useState(null);

    useEffect(() => {
        if (isSignedIn) client.membership.get().then(setTessera);
    }, [client, isSignedIn]);

    if (loading) return <p>Accesso in corso…</p>;
    if (!isSignedIn) return <SignInButton returnTo={location.pathname}>Accedi con Vimine</SignInButton>;
    return (
        <>
            <p>Tessera {tessera?.verdict === 'valid' ? 'valida' : tessera?.verdict}</p>
            <button onClick={() => signOut()}>Esci</button>
        </>
    );
}
```

Il provider va montato **anche** nella pagina di callback (`redirectUri`): è lì che scambia il codice.

## `<VimineProvider>`

| Prop | | |
|---|---|---|
| `client` | `Vimine` | l'istanza (creala fuori dal render) |
| `handleRedirect` | `boolean`, default `true` | scambia il codice quando la pagina si carica con i parametri di un accesso |
| `onSignedIn` | `(result: RedirectResult) => void` | dopo lo scambio: `result.returnTo` è quello passato a `signIn()` |
| `onRedirectError` | `(error: VimineError) => void` | `access_denied`, `state_mismatch`, … |

## `useVimine()`

Restituisce:

| | |
|---|---|
| `client` | il `Vimine` |
| `session` | la sessione corrente o `null`, aggiornata a ogni accesso, rinnovo e uscita |
| `isSignedIn` | `!!session` |
| `loading` | `true` mentre il codice del ritorno viene scambiato |
| `signIn(options?)` | come `client.signIn` |
| `signOut(options?)` | come `client.signOut` |

Lancia se usato fuori dal provider.

## `<SignInButton>`

Un `<button>` semplice che avvia l'accesso **dal click** (la pagina di accesso deve essere raggiunta da un gesto
dell'utente). Accetta `scopes`, `prompt`, `returnTo` e qualsiasi attributo di un bottone; è disabilitato durante
`loading`. Testo di default: «Accedi con Vimine».
