Der Zauber von React-basierten Mehrschrittformularen

Avatar of Nathan Sebhastian
Nathan Sebhastian am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Eine Möglichkeit, mit langen, komplexen Formularen umzugehen, besteht darin, sie in mehrere Schritte aufzuteilen. Sie wissen schon, eine Reihe von Fragen beantworten, zur nächsten übergehen, dann vielleicht zu einer weiteren und so weiter. Wir bezeichnen diese oft als Mehrschrittformulare (aus offensichtlichen Gründen), aber andere nennen sie auch "Wizard"-Formulare.

Mehrschrittformulare können eine großartige Idee sein! Indem nur wenige Eingaben gleichzeitig auf einem Bildschirm angezeigt werden, kann das Formular verdaulicher erscheinen und verhindern, dass Benutzer von einer Flut von Formularfeldern überwältigt werden. Obwohl ich es nicht nachgeschlagen habe, bin ich bereit zu sagen, dass niemand Spaß daran hat, ein riesiges Formular auszufüllen – hier können Mehrschrittformulare nützlich sein.

Das Problem ist, dass sich Mehrschrittformulare – obwohl sie die wahrgenommene Komplexität im Frontend reduzieren – in der Entwicklung komplex und überwältigend anfühlen können. Aber ich bin hier, um Ihnen zu sagen, dass dies nicht nur erreichbar, sondern auch relativ einfach ist, wenn React als Basis verwendet wird. Das werden wir also heute gemeinsam bauen!

Hier ist das Endergebnis:

Lasst es uns bauen!

Der einfachste Weg, ein Mehrschrittformular zu erstellen, besteht darin, ein Container-Formularelement zu erstellen, das alle Schritte als Komponenten darin enthält. Hier ist eine visuelle Darstellung dieses Containers (), der darin enthaltenen Komponenten (, , ) und der Art und Weise, wie Zustände und Props zwischen ihnen übergeben werden.

A diagram showing the master form component above three rectangles representing the three steps of the form, from left to right. Between the master form and the steps is a constructor, setState, and render.
dient als Container, während drei Kindkomponenten darin als jeder Schritt des Formulars fungieren.

Obwohl es komplexer erscheint als ein reguläres Formular, verwendet ein Mehrschrittformular immer noch die gleichen Prinzipien wie ein React-Formular

  • Zustand wird zum Speichern von Daten und Benutzereingaben verwendet.
  • Komponente wird zum Schreiben von Methoden und der Benutzeroberfläche verwendet.
  • Props werden zum Übergeben von Daten und Funktionen an Elemente verwendet.

Anstatt einer Formular-Komponente werden wir eine Eltern-Komponente und drei Kind-Komponenten haben. In der obigen Abbildung sendet Daten und Funktionen über Props an die Kind-Komponenten, und im Gegenzug lösen die Kind-Komponenten eine handleChange()-Funktion aus, um Werte im Zustand von festzulegen. Das ist eine große glückliche Familie hier! Wir brauchen auch eine Funktion, um das Formular von einem Schritt zum nächsten zu bewegen, und dazu kommen wir etwas später.
Die Schritt-Kind-Komponenten (verstehen Sie?) erhalten Props von der Eltern-Komponente für die Props value und onChange.

  • -Komponente rendert eine E-Mail-Adressen-Eingabe
  • rendert eine Benutzernamen-Eingabe
  • rendert eine Passwort-Eingabe und eine Senden-Schaltfläche

liefert sowohl Daten als auch Funktionen in Kind-Komponenten, und Kind-Komponenten geben Benutzereingaben über seine props an die Eltern zurück.

Erstellen der Schritt-Kind-Komponenten

Zuerst erstellen wir die Kind-Komponenten des Formulars. Wir halten die Dinge für dieses Beispiel recht einfach, indem wir nur eine Eingabe pro Schritt verwenden, aber jeder Schritt könnte wirklich so komplex sein, wie wir möchten. Da die Kind-Komponenten untereinander fast gleich aussehen, zeige ich hier nur eine davon. Aber schauen Sie sich unbedingt die Demo für den vollständigen Code an.

class Step1 extends React.Component {render() {
  if (this.props.currentStep !== 1) { // Prop: The current step
    return null
  }
  // The markup for the Step 1 UI
  return(
    <div className="form-group">
      <label htmlFor="email">Email address</label>
      <input 
        className="form-control"
        id="email"
        name="email"
        type="text"
        placeholder="Enter email"
        value={this.props.email} // Prop: The email input data
        onChange={this.props.handleChange} // Prop: Puts data into state
      />
    </div>
  )}
}

Jetzt können wir diese Kind-Komponente in die render()-Funktion des Formulars einfügen und die notwendigen Props übergeben. Genau wie in der Formular-Dokumentation von React können wir immer noch handleChange() verwenden, um die vom Benutzer gesendeten Daten mit setState() in den Zustand zu bringen. Eine handleSubmit()-Funktion wird beim Absenden des Formulars ausgeführt.

Als nächstes die Eltern-Komponente

Lassen Sie uns die Eltern-Komponente erstellen – die wir alle, wie wir jetzt wissen, nennen – und ihren Zustand und ihre Methoden initialisieren.

Wir verwenden einen currentStep-Zustand, der mit einem Standardwert von 1 initialisiert wird, was den ersten Schritt () des Formulars anzeigt. Wir werden den Zustand aktualisieren, während das Formular fortschreitet, um den aktuellen Schritt anzuzeigen.

class MasterForm extends Component {
  constructor(props) {
    super(props)
    // Set the initial input values
    this.state = {
      currentStep: 1, // Default is Step 1
      email: '',
      username: '',
      password: '', 
    }

    // Bind the submission to handleChange() 
    this.handleChange = this.handleChange.bind(this)
  }

  // Use the submitted data to set the state
  handleChange(event) {
    const {name, value} = event.target
    this.setState({
      [name]: value
    }) 
  }

  // Trigger an alert on form submission
  handleSubmit = (event) => {
    event.preventDefault()
    const { email, username, password } = this.state
    alert(`Your registration detail: \n 
    Email: ${email} \n 
    Username: ${username} \n
    Password: ${password}`)
  }

  // Render UI will go here...
}

OK, das ist die Basisfunktionalität, die wir suchen. Als Nächstes möchten wir die Shell-Benutzeroberfläche für das eigentliche Formular erstellen und die Kind-Komponenten darin aufrufen, einschließlich der erforderlichen Zustand-Props, die von über handleChange() übergeben werden.

render() { 
  return (
    <React.Fragment>
      <h1>A Wizard Form!</h1>

      Step {this.state.currentStep} 
 
      <form onSubmit={this.handleSubmit}>

        // Render the form steps and pass in the required props
        <Step1 
          currentStep={this.state.currentStep} 
          handleChange={this.handleChange}
          email={this.state.email}
        />
        <Step2 
          currentStep={this.state.currentStep} 
          handleChange={this.handleChange}
          username={this.state.username}
        />
        <Step3 
          currentStep={this.state.currentStep} 
          handleChange={this.handleChange}
          password={this.state.password}
        /> 
      </form>
    </React.Fragment>
  )
}

Ein Schritt nach dem anderen

Bisher haben wir den Benutzern erlaubt, die Formularfelder auszufüllen, aber wir haben keine tatsächliche Möglichkeit geboten, zum nächsten Schritt zu gelangen oder zum vorherigen zurückzukehren. Das erfordert Vorwärts- und Rückwärtsfunktionen, die prüfen, ob der aktuelle Schritt einen vorherigen oder nächsten Schritt hat; und wenn ja, wird die currentStep-Prop entsprechend hoch- oder runtergeschoben.

class MasterForm extends Component {
  constructor(props) {
    super(props)
    // Bind new functions for next and previous
    this._next = this._next.bind(this)
    this._prev = this._prev.bind(this)
  }
  // Test current step with ternary
  // _next and _previous functions will be called on button click
  _next() {
    let currentStep = this.state.currentStep
    // If the current step is 1 or 2, then add one on "next" button click
    currentStep = currentStep >= 2? 3: currentStep + 1
    this.setState({
      currentStep: currentStep
    })
  }

  _prev() {
    let currentStep = this.state.currentStep
    // If the current step is 2 or 3, then subtract one on "previous" button click
    currentStep = currentStep <= 1? 1: currentStep - 1
    this.setState({
      currentStep: currentStep
    })
  }
}

Wir werden eine get-Funktion verwenden, die prüft, ob der aktuelle Schritt 1 oder 3 ist. Das liegt daran, dass wir ein dreistufiges Formular haben. Natürlich können wir diese Prüfungen ändern, wenn weitere Schritte zum Formular hinzugefügt werden. Wir wollen auch die nächsten und vorherigen Schaltflächen nur anzeigen, wenn es tatsächlich nächste und vorherige Schritte gibt, zu denen navigiert werden kann.

// The "next" and "previous" button functions
get previousButton(){
  let currentStep = this.state.currentStep;
  // If the current step is not 1, then render the "previous" button
  if(currentStep !==1){
    return (
      <button 
      className="btn btn-secondary" 
      type="button" 
      onClick={this._prev}>
          Previous
      </button>
    )
  }
  // ...else return nothing
  return null;
}

get nextButton(){
  let currentStep = this.state.currentStep;
  // If the current step is not 3, then render the "next" button
  if(currentStep <3){
    return (
      <button 
      className="btn btn-primary float-right" 
      type="button" 
      onClick={this._next}>
        Next
      </button> 
    )
  }
  // ...else render nothing
  return null;
}

Alles, was übrig bleibt, ist, diese Schaltflächen zu rendern

// Render "next" and "previous" buttons
render(){
  return(
    <form onSubmit={this.handleSubmit}>
    {/* 
      ... other codes
    */}

    {this.previousButton}
    {this.nextButton}
    </form>
  )
}

Glückwunsch, Sie sind ein Formular-Zauberer! 🧙

Das war der letzte Schritt in diesem Mehrschritt-Tutorial zu Mehrschrittformularen. Wow, wie meta! Obwohl wir nicht tief in die Gestaltung eingedrungen sind, hoffe ich, dass Ihnen dies einen soliden Überblick darüber gibt, wie Sie komplexe Formulare weniger ... komplex machen können!

Hier ist noch einmal die endgültige Demo, damit Sie den gesamten Code in seinem vollen und gloriousen Kontext sehen können

React wurde für solche Dinge entwickelt, da es Zustände, Eigenschaftsänderungen, wiederverwendbare Komponenten und dergleichen nutzt. Ich weiß, dass React für manche Leute eine hohe Einstiegshürde sein kann, aber ich habe ein Buch geschrieben, das es zu einer viel niedrigeren Hürde macht. Ich hoffe, Sie schauen es sich an!