# React

> VimineProvider, useVimine und SignInButton aus @vimine/sdk/react.

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

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

Ein Provider, der **einen** `Vimine`-Client besitzt, die Rückkehr von der Anmeldung beim Einhängen verarbeitet und die Sitzung
dem Baum bereitstellt; ein Hook; eine Schaltfläche. React ≥ 18 (optionale Peer-Abhängigkeit: Das SDK installiert es nicht).

## Beispiel

```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="MembershipCard.jsx"
import { useEffect, useState } from 'react';
import { useVimine, SignInButton } from '@vimine/sdk/react';

export function MembershipCard() {
    const { client, isSignedIn, loading, signOut } = useVimine();
    const [card, setCard] = useState(null);

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

    if (loading) return <p>Anmeldung läuft…</p>;
    if (!isSignedIn) return <SignInButton returnTo={location.pathname}>Mit Vimine anmelden</SignInButton>;
    return (
        <>
            <p>Ausweis {card?.verdict === 'valid' ? 'gültig' : card?.verdict}</p>
            <button onClick={() => signOut()}>Abmelden</button>
        </>
    );
}
```

Der Provider muss **auch** auf der Callback-Seite (`redirectUri`) eingehängt sein: Dort tauscht er den Code ein.

## `<VimineProvider>`

| Prop | | |
|---|---|---|
| `client` | `Vimine` | die Instanz (legen Sie sie außerhalb des Renderns an) |
| `handleRedirect` | `boolean`, Standard `true` | den Code eintauschen, wenn die Seite mit Anmeldeparametern lädt |
| `onSignedIn` | `(result: RedirectResult) => void` | nach dem Eintausch: `result.returnTo` ist, was `signIn()` übergeben wurde |
| `onRedirectError` | `(error: VimineError) => void` | `access_denied`, `state_mismatch`, … |

## `useVimine()`

Liefert:

| | |
|---|---|
| `client` | den `Vimine` |
| `session` | die aktuelle Sitzung oder `null`, aktualisiert bei jeder Anmeldung, Erneuerung und Abmeldung |
| `isSignedIn` | `!!session` |
| `loading` | `true`, während der Rückkehr-Code eingetauscht wird |
| `signIn(options?)` | wie `client.signIn` |
| `signOut(options?)` | wie `client.signOut` |

Wirft einen Fehler, wenn er außerhalb des Providers verwendet wird.

## `<SignInButton>`

Ein einfacher `<button>`, der die Anmeldung **aus dem Klick heraus** startet (die Anmeldeseite muss aus einer
Nutzergeste erreicht werden). Akzeptiert `scopes`, `prompt`, `returnTo` und jedes Attribut einer Schaltfläche; er ist deaktiviert, solange `loading` gilt.
Standardtext: „Accedi con Vimine“.
