La libreria Formspree React
Installazione
Questa libreria presuppone che React sia già installato nel tuo ambiente come peer dependency. I nostri helper si basano sugli Hook di React, quindi devi avere la versione 16.8.0 o superiore.
npm install @formspree/react
Sorgente su GitHub | pacchetto npm
Puoi usare questa libreria con o senza la Formspree CLI. Questo articolo presuppone che tu stia creando i moduli nella dashboard. Per assistenza con i progetti CLI, consulta il nostro articolo sull’uso della Formspree CLI.
Utilizzo
L’hook di React useForm è il modo più semplice per configurare un modulo React con Formspree. Basta importare @formspree/react e poi chiamare useForm con l’hashid del modulo ottenuto creando un modulo nella dashboard di Formspree.
import { useForm } from '@formspree/react';
function MyForm() {
const [state, handleSubmit, reset] = useForm('{your-form-id}');
if (state.succeeded) {
return <div>Thank you for signing up!</div>;
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">Email</label>
<input id="email" type="email" name="email" />
<button type="submit" disabled={state.submitting}>Sign up</button>
</form>
)
}
Oggetto state
Il primo valore nell’array restituito da questo hook è un oggetto state:
const [state, handleSubmit, reset] = useForm('{your-form-id}');
L’oggetto state contiene le seguenti proprietà:
| Chiave | Descrizione |
|---|---|
submitting | Un valore booleano che indica se il modulo è attualmente in fase di invio (il valore predefinito è false) |
succeeded | Un valore booleano che indica se il modulo è stato inviato con successo (il valore predefinito è false) |
errors | Un’istanza della classe SubmissionError contenente gli errori di validazione lato server (il valore predefinito è null) |
result | Un oggetto con un’unica proprietà next, che è l’URL di reindirizzamento quando l’invio ha esito positivo (il valore predefinito è null) |
Lo stato cambia nel tempo nei seguenti modi:
- Quando viene chiamato
handleSubmit,submittingdiventatrue - Se l’invio non supera le validazioni lato server, viene creata una nuova istanza di
errorscon gli errori specifici - Se l’invio ha esito positivo,
succeededdiventatrueeresultnon ènull - Dopo che la richiesta di invio è terminata,
submittingdiventa semprefalse
L’oggetto errors dispone dei seguenti metodi:
| Chiave | Descrizione |
|---|---|
getFormErrors() | Restituisce un array di errori a livello di modulo |
getFieldErrors(field) | Restituisce un array di errori per il field |
getAllFieldErrors() | Restituisce un array di coppie chiave-valore degli errori a livello di campo di tutti i campi ([field, errors][]) |
Gli elementi di errore nell’oggetto errors hanno le seguenti proprietà:
| Chiave | Descrizione |
|---|---|
message | Un frammento di messaggio di errore leggibile (ad esempio “is required”) |
code | Un codice di errore comprensibile dalla macchina (vedi i codici di errore qui sotto) |
details | Un oggetto contenente varie proprietà aggiuntive sull’errore. Ad esempio, quando usato con Stripe, conterrà un campo stripeCode che contiene l’errore esatto restituito da Stripe |
Reset
Il terzo valore nell’array restituito dall’hook è una funzione di reset.
const [state, handleSubmit, reset] = useForm('{your-form-id}');
Questa funzione viene usata per reimpostare l’oggetto state dopo che una richiesta di invio del modulo è stata completata. Cancella le proprietà result ed errors e imposta le proprietà booleane submitting e succeeded al loro stato predefinito (cioè false). Puoi usare questo metodo nella pagina di ringraziamento che mostri dopo che la richiesta di invio del modulo è stata completata, per consentire all’utente di reimpostare il modulo e inviarlo nuovamente.
Ecco un esempio che mostra come usare la funzione reset() in un modulo:
function TestForm() {
const [state, submit, reset] = useForm('{your-form-id}');
if (state.submitting) {
return <p>Submitting…</p>;
}
if (state.succeeded) {
return (
<div>
<p>Thanks!</p>;<button onClick={reset}>Reset</button>
</div>
);
}
return (
<div>
<h1>Form</h1>
<form onSubmit={submit}>
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
name="email"
defaultValue="test@example.com"
/>
<button type="submit">Sign up</button>
</form>
</div>
);
}
Errori di validazione
Ecco un esempio di modulo che usa il componente ValidationError per mostrare gli errori dei campi:
import { ValidationError, useForm } from '@formspree/react';
function MyForm() {
const [state, handleSubmit] = useForm('{your-form-id}');
if (state.succeeded) {
return <div>Thank you for signing up!</div>;
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">Email</label>
<input id="email" type="email" name="email" required />
<ValidationError field="email" prefix="Email" errors={state.errors} />
<button type="submit" disabled={state.submitting}>Sign up</button>
</form>
)
}
Il componente ValidationError accetta le seguenti proprietà speciali:
field— il nome del campo per cui mostrare gli errori. Se non viene fornito alcun attributofield, verranno segnalati gli errori generali (non relativi a un campo). (Vedi i codici di errore qui sotto)errors— l’oggetto contenente gli errori di validazione (obbligatorio)prefix— il nome leggibile del campo (facoltativo, il valore predefinito è “This field”)
Tutte le altre props (come className) vengono passate al wrapper <div>. Se il campo specificato non è valido, questo componente renderizza un <div> contenente il messaggio di errore:
<div {...props}>
{prefix} {message}
</div>
Opzioni aggiuntive
Questo hook accetta due argomenti: la chiave del modulo e un oggetto contenente le opzioni.
const [state, handleSubmit, reset] = useForm('{your-form-key}', options);
Ecco le opzioni accettabili:
| Chiave | Tipo | Descrizione |
|---|---|---|
data | object | Un oggetto contenente stringhe o funzioni da unire ai dati del tuo modulo |
client | Formspree | Un’istanza del client Formspree |
Esempio di utilizzo
const [state, handleSubmit, reset] = useForm('{your-form-id}', {
data: {
subject: 'Someone joined the newsletter',
pageTitle: function() {
// This function will be evaluated at submission time
return document.title;
}
}
});
Utilizzo con Stripe
La libreria Formspree React include il supporto per i pagamenti tramite Stripe. La libreria gestisce gran parte della gestione dello stato lato front end necessaria per creare pagamenti ed eseguire la Strong Customer Authentication (SCA). Il backend di Formspree si occupa poi di inviare i pagamenti a Stripe. Insieme, Formspree riduce drasticamente l’impegno di sviluppo necessario per creare un modulo di pagamento.
La funzionalità Stripe viene caricata in modo lazy. Ciò significa che solo un wrapper Stripe minimale (appena 6k compressi) viene incluso in @formspree/react. La maggior parte della libreria Stripe viene caricata solo se e quando gli elementi Stripe vengono renderizzati per la prima volta.
Per usare Stripe, avvolgi prima la tua app con il componente FormspreeProvider e includi la prop stripePK con la tua chiave pubblicabile di Stripe.
import { FormspreeProvider } from '@formspree/react';
function MyApp() {
return (
<FormspreeProvider
stripePK={'{your-stripe-publishable-key}'}
>
<PaymentForm />
</FormspreeProvider>
)
}
Poi, quando crei il tuo modulo, usa il componente CardElement esportato da @formspree/react.
import { useForm, CardElement, ValidationError } from '@formspree/react';
function PaymentForm() {
const [state, handleSubmit] = useForm('{your-form-id}');
if (state.succeeded) {
return <div>Payment has been handled successfully!</div>;
}
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email</label>
<input id="email" type="email" name="email" />
</div>
<div>
<label>Card details</label>
<CardElement />
<ValidationError
field="paymentMethod"
errors={state.errors}
/>
</div>
<button type="submit" disabled={state.submitting}>
{state.submitting ? 'Handling payment...' : 'Pay'}
</button>
</form>
)
}
Il componente CardElement viene passato direttamente da @stripe/react-stripe-js. Viene esportato da Formspree React solo per garantire la coerenza delle versioni. La documentazione per il componente CardElement è disponibile qui.
Nota il nome del campo “paymentMethod” su ValidationError. Questo è il nome del campo usato per inviare i dati da Stripe a Formspree e deve essere passato a ValidationError per intercettare i relativi errori di Stripe.
Utilizzo con una libreria di moduli esterna
L’hook di React useSubmit è un modo semplice per integrare un’altra libreria di moduli con Formspree. Basta importare @formspree/react e poi chiamare useSubmit con l’hashid del modulo ottenuto creando un modulo nella dashboard di Formspree.
import { useSubmit } from '@formspree/react';
import { useForm } from 'react-hook-form';
type Inputs = {
email: string;
message: string;
name: string;
};
export function WithReactHookForm() {
const {
formState: { errors, isSubmitSuccessful, isSubmitting },
handleSubmit,
register,
setError,
} = useForm<Inputs>();
const submit = useSubmit<Inputs>(
process.env.REACT_APP_REACT_HOOK_FORM_ID as string,
{
onError(errs) {
const formErrs = errs.getFormErrors();
for (const { code, message } of formErrs) {
setError(`root.${code}`, {
type: code,
message,
});
}
const fieldErrs = errs.getAllFieldErrors();
for (const [field, errs] of fieldErrs) {
setError(field, {
message: errs.map((e) => e.message).join(', '),
});
}
},
}
);
return (
<div>
{isSubmitSuccessful ? (
<h2>Your message has been sent successfully!</h2>
) : (
<form onSubmit={handleSubmit(submit)}>
<div className="block">
<label htmlFor="email">Email</label>
<input {...register('email')} id="email" type="email" />
{errors.email && <p className="error">{errors.email.message}</p>}
</div>
<div className="block">
<label htmlFor="name">Name</label>
<input {...register('name')} id="name" />
{errors.name && <p className="error">{errors.name.message}</p>}
</div>
<div className="block">
<label htmlFor="message">Message</label>
<textarea {...register('message')} id="message" rows={10} />
</div>
{errors.root && (
<div className="block">
<ul className="error">
{Object.values(errors.root).map((err) => {
if (typeof err !== 'object') {
return <li key={err}>{err}</li>;
}
const { type, message } = err;
return <li key={type}>{message}</li>;
})}
</ul>
</div>
)}
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? 'Submitting...' : 'Submit'}
</button>
</form>
)}
</div>
);
}
Codici di errore
I seguenti codici di errore possono comparire nell’array errors dell’oggetto state:
| Codice | Errore di campo | Descrizione |
|---|---|---|
INACTIVE | Il modulo è stato disabilitato | |
BLOCKED | Il modulo è stato bloccato | |
EMPTY | Non è stato inviato alcun dato | |
PROJECT_NOT_FOUND | È stata usata una chiave di progetto non valida per inviare il modulo | |
FORM_NOT_FOUND | È stato usato un hashid del modulo non valido per inviare il modulo | |
NO_FILE_UPLOADS | I caricamenti file non sono supportati per questo modulo | |
TOO_MANY_FILES | Il modulo è stato inviato con troppi allegati | |
FILES_TOO_BIG | Uno o più file caricati hanno superato la dimensione massima del file | |
REQUIRED_FIELD_MISSING | ✓ | Un campo è obbligatorio, ma non è stato fornito alcun valore |
REQUIRED_FIELD_EMPTY | ✓ | Un campo è obbligatorio, ma è stata fornita una stringa vuota o priva di contenuto |
TYPE_EMAIL | ✓ | Un campo deve contenere un’email |
TYPE_NUMERIC | ✓ | Un campo deve contenere un numero |
TYPE_TEXT | ✓ | Un campo deve contenere del testo |
STRIPE_CLIENT_ERROR | ✓ | Chiave Stripe mancante |
STRIPE_SCA_ERROR | ✓ | Errore SCA di Stripe. Vedi details |