React - Formulier gegevens versturen
Home

React - Formulier gegevens versturen

React - Formulier gegevens versturen

We kunnen gegevens opslaan in en verwijderen uit state. Dat hebben we gezien in React - State. Maar wat als we nieuwe gegevens willen toevoegen aan de state? In een echte toepassing zal je eerder met een lege state beginnen en er items aan toe willen voegen, zoals een takenlijst of een winkelwagentje.

Een nieuwe react app maken

  1. Zorg ervoor dat je openstaande Node.js servers afsluit met Ctrl-C.
  2. Vooraleer de create-react-app op te starten ga je naar de map waarin je het project wil maken. We gaan op Cloud9 een project maken met de naam react-submit-form. En dat project plaatsen we in de root van onze workspace. Zorg er dus voor dat je in de root staat:
    jefinghelbrecht:~/workspace $
    In plaats van JefInghelbrecht zie je natuurlijk de naam van je eigen workspace.
  3. Om een create-react-app te maken, voer je de volgende instructie in je terminal uit (zorg ervoor dat je de laatste versie van Node hebt geïnstalleerd, zie Een React App maken):
    npx create-react-app react-submit-form
    Meer info over npx: Introducing npx: an npm package runner
  4. Als de installatie goed verlopen is, ga dan naar de nieuw aangemaakte map en start het project:
    cd react-submit-form
    npm start
  5. We maken onze eigen standaardtekst en kieperen de voorgeprogrammeerde code overboord. We behouden alleen:
    1. index.js
    2. index.css
  6. We deleten alle overige bestanden in de /src.
  7. In index.css plakken we de Primitive CSS van Tania Rascia. Je kan dat vervangen door je eigen CSS of door Bootstrap of om het even welk ander CSS framework.
  8. Verwijder de verwijzingen naar serviceWorker in index.js. Delete de gemarkeerde lijnen:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import * as serviceWorker from './serviceWorker';
    
    ReactDOM.render(<App />, document.getElementById('root'));
    
    // If you want your app to work offline and load faster, you can change
    // unregister() to register() below. Note this comes with some pitfalls.
    // Learn more about service workers: http://bit.ly/CRA-PWA
    serviceWorker.unregister();
    

Data via een form versturen

  1. We hebben net App.js verwijderd. Maak een nieuw App.cs bestand in de /src map.
  2. Vermits we met een lege lijst beginnen en die zullen vullen met de gegevens, die de gebruiker met behulp van een form element verstuurt, voorzien we in state een lege array om de ingegeven albums in op te slaan:
    import React, { Component } from 'react';
    
    class App extends Component {
        state = {
            albums: []
        }
    }
  3. We maken nu een formuliercomponent in een nieuw bestand met de naam Form.js in de /src map. We gaan een klassecomponent maken en binnenin zullen we een constructor() gebruiken, wat we tot nu toe nog niet hebben gedaan. We hebben de constructor() nodig om this te kunnen gebruiken en om de props van de ouder-component te kunnen benaderen.

    We gaan de beginstatus van het formulier instellen als een object met enkele lege eigenschappen en die initiële status toewijzen aan this.state:

    import React, { Component } from 'react';
    
    class Form extends Component {
        constructor(props) {
            super(props);
    
            this.initialState = {
                nummer: '',
                titel: '',
                kaft: '',
                prijs: ''
            };
    
            this.state = this.initialState;
        }
    }
  4. Met ons formulier willen we de state van het formulier bijwerken elke keer dat een veld in de form wordt gewijzigd, en wanneer we op de submit knop drukken zullen al de ingevoerde gegevens worden doorgegeven aan de App state, die de tabel vervolgens zal updaten.

    Eerst maken we de functie die wordt uitgevoerd als er een input element op de form wordt gewijzigd. Het evenement wordt doorgegeven en we zullen de state van formulier updaten om het name attribuut (sleutel) en het value attribuut van het gewijzigde HTML invoerelement in de state op te slaan:

    handleChange = event => {
        const { name, value } = event.target;
    
        this.setState({
            [name]: value
        });
    }
    
  5. We gaan dit eerst laten werken vooraleer verder te gaan met het verzenden van het formulier. In de render methode halen we vier eigenschappen uit de state en wijzen die toe als de waarden van de elementen met een name attribuut die overeenkomen met de sleutel uit de state. We voeren de handleChange methode uit wanneer de onChange event van de input velden wordt afgevuurd. Ten slotte exporteren we de formuliercomponent:

    render() {
        const { nummer, titel, kaft, prijs } = this.state;
    
        return (
            <form>
                <label>Nummer</label>
                <input
                    type="text"
                    name="nummer"
                    value={nummer}
                    onChange={this.handleChange} />
                <label>Titel</label>
                <input
                    type="text"
                    name="titel"
                    value={titel}
                    onChange={this.handleChange}/>
                <label>Kaft</label>
                <input
                    type="text"
                    name="kaft"
                    value={kaft}
                    onChange={this.handleChange}/>
                <label>Prijs</label>
                <input
                    type="text"
                    name="prijs"
                    value={prijs}
                    onChange={this.handleChange}/>
            </form>
        );
    }
    
    
  6. Voeg de Table component toe die we in React - State gemaakt hebben (src/Table.js):

    import React, { Component } from 'react';
    
    const TableBody = props => {
        const rows = props.albumData.map((row, index) => {
            return (
                <tr key={index}>
                    <td>{row.nummer}</td>
                    <td>{row.titel}</td>
                    <td>{row.kaft}</td>
                    <td>{row.prijs}</td>
                    <td><button onClick={() => props.removeAlbum(index)}>Delete</button></td>
               </tr>
            );
        });
    
        return <tbody>{rows}</tbody>;
    }
    
    class Table extends Component {
        render() {
            const {albumData, removeAlbum} = this.props;
            
            return (
                <table>
                    <TableBody
                        albumData={albumData}
                        removeAlbum = {removeAlbum}
                    />
                </table>
            );
        }
    }
    
    export default Table;
    
    
  7. In App.cs geven we de Table met daaronder de Form component weer:
    import React, { Component } from 'react';
    import Table from './Table';
    import Form from './Form';
    
    class App extends Component {
        state = {
            albums: []
        };
        
        render() {
            // const { albums } = this.state;
            return (
               <div className="container">
                  <Table
                    albumData={this.state.albums}
                    removeAlbum={this.removeAlbum}
                  />
               <Form />
              </div>
            )
        };
    }
    
    export default App;
    
    
  8. Als we naar de front-end van onze app gaan zien we een formulier zonder submit knop. Maar omdat we een methode hebben toegewezen aan de onchange event van de input html elementen, kunnen we in de debugger zien dat wanneer we de input elementen updaten, dat de lokale state van de form geüpdated wordt:
    React Submitting Form Data with no submit button
    React Submitting Form Data with no submit button
  9. Nu moeten we het mogelijk maken om de gegevens, die in de form worden ingetypt, te verzenden en aan de App state toe te voegen. Daarvoor maken we een methode met de naam handleSubmit in de App component die de state zal bijwerken. Deze methode voegt het nieuwe album, die als parameter wordt meegegeven, toe aan de bestaande this.state.albums array met behulp van de ES6 spread operator:
    handleSubmit = album => {
        this.setState({albums: [...this.state.albums, album]});
    }
  10. We geven deze methode mee als parameter in de Form component:
    <Form handleSubmit={this.handleSubmit} />
    
  11. Vervolgens maken we een methode met de naam submitForm in de Form component die de eventhandelaar oproept en de album parameter, die we net gedefiniëerd hebben, aan de Form state doorgeeft. Deze methode zal ook initiële state opnieuw instellen om de Form leeg te maken na de submit:
    submitForm = () => {
        this.props.handleSubmit(this.state);
        this.setState(this.initialState);
    }
  12. Tenslotte voegen we een submit knop toe aan de form. We gebruiken de onClick event i.p.v. de onSubmit vermits we niet de standaard submit functionaliteit van de form gebruiken. De onClick event wordt afgehandeld door de submitForm methode:
    <input
        type="button"
        value="Submit"
        onClick={this.submitForm} />
  13. Als we App uitvoeren kunnen we albums toevoegen en deleten. De Table component en TableBody kunnen data uit de state halen en dus worden de gegevens van album correct weergegeven:
    React Submitting Form Data with submit button
    React Submitting Form Data with submit button
  14. Om deze oefening af te ronden voegen we nog enkele eenvoudige componenten toe, namelijk de thead en tfoot van de tabel en een caption.
    1. We beginnen met een component waarin de headings staan van zowel van het thead en tfoot element. In de Table component in het Table.js bestand voegen we de volgende component toe:
      const TableHeadings = () => {
          return (
              <tr>
                  <th scope="col">Nummer</th>
                  <th scope="col">Titel</th>
                  <th scope="col">Kaft</th>
                  <th scope="col">&euro;</th>
              </tr>
          );
      }
    2. We gebruiken die component als onderdeel van de TableHeader component:
      const TableHeader = () => {
          return (
              <thead>
                  <TableHeadings />
              </thead>
          );
      }
    3. We doen het zelfde voor de TableFooter component:
      const TableFooter = () => {
          return (
              <tfoot>
                  <TableHeadings />
              </tfoot>
          );
      }
    4. En een component voor de caption:
      const TableCaption = () => {
          return (
              <caption>
                  Jommeke strips
              </caption>
          );
      }
    5. Tenslotte voegen die eenvoudige componenten toe aan de Table component:
      class Table extends Component {
          render() {
              const {albumData, removeAlbum} = this.props;
              
              return (
                  <table>
                      <TableCaption />
                      <TableHeader />
                      <TableBody
                          albumData={albumData}
                          removeAlbum = {removeAlbum}
                      />
                      <TableFooter />
                  </table>
              );
          }
      }
    6. En dit is het resultaat:
      React Submitting Form Data with Simple Components
      React Submitting Form Data with Simple Components
  15. Let erop dat we niet de standaard submit functionaliteit van het form element hebben gebruikt.

JI
2018-11-18 11:32:33