Utiliser React directement sur un fichier html, sans webpack

Utiliser React directement sur un fichier html, sans webpack

Introduction

Avant de commencer à développer une application qui se respecte avec React on est obligé de passer par une première étape de configuration pour cela vous avez principalement 3 options :

  • Utiliser un générateur de code comme create-react-app
  • Configurer sois même le process de build avec webpack, babel …
  • démarrer à partir d’un exemple d’application React comme on en peut en trouver sur github.

cependant il existe une façon bien plus simple d’utiliser React directement sur votre page html, oui, comme on faisait avec jQuery dans le temps.

Pourquoi ?

Cette approche peut s’avérer pratique pour démarrer des prototypes très rapidement, cependant n’utilisez pas cette approche pour votre produit final, en effet l’utilisation de webpack nous offres beaucoup plus d’avantages ( plugins, utilisation de saass/scss, optimisation du bundle javascript final, tests unitaires, ….)

Comment

Très simple, rajouter les scripts suivants sur votre page, voici un exemple :

<html>
  ...
  <body>
    <div id="app"></div>

    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0/umd/react.development.js"
      crossorigin
    ></script>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0/umd/react-dom.development.js"
      crossorigin
    ></script>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"
      crossorigin
    ></script>

    ...

    <script type="text/babel">
      const MyButton = <button>Heyyy !</button>;

      ReactDOM.render(<MyButton />, document.getElementById("app"));
    </script>
  </body>
</html>

Un exemple plus complet

Pour donner un exemple plus complet, j’ai créé une todo list qui tient sur un seul fichier html, pour exécuter l’exemple copier le contenu dans un fichier html puis ouvrez le sur votre navigateur :

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>React directly in html</title>

    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
    />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0/umd/react.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0/umd/react-dom.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
  </head>
  <body>
    <div id="app"></div>

    <script type="text/babel">
      function App() {
        return (
          <div className="container pt-3">
            <TodoList />
          </div>
        );
      }

      class TodoList extends React.Component {
        constructor() {
          super();
          this.state = {
            items: []
          };
          this.addItemToList = this.addItemToList.bind(this);
        }

        addItemToList(newItem) {
          this.setState({
            items: [...this.state.items, newItem]
          });
        }

        render() {
          return (
            <div className="card">
              <div className="card-body">
                <h5 className="card-title">My todo list</h5>
                <TodoListNewItemForm onAddItem={this.addItemToList} />
                <TodoListAllItems items={this.state.items} />
              </div>
            </div>
          );
        }
      }

      class TodoListNewItemForm extends React.Component {
        constructor(props) {
          super(props);
          this.itemName = React.createRef();
          this.handleSubmit = this.handleSubmit.bind(this);
        }

        handleSubmit(event) {
          event.preventDefault();
          if (this.itemName.current.value) {
            this.props.onAddItem(this.itemName.current.value);
            this.itemName.current.value = "";
          }
        }

        render() {
          return (
            <form onSubmit={this.handleSubmit}>
              <input
                className="form-control form-control-lg"
                type="text"
                placeholder="New item name ..."
                ref={this.itemName}
              />
            </form>
          );
        }
      }

      function TodoListAllItems({ items }) {
        return (
          <ul className="list-group">
            {items &&
              items.map(i => (
                <li key={i} className="list-group-item">
                  {i}
                </li>
              ))}
          </ul>
        );
      }
      ReactDOM.render(<App />, document.getElementById("app"));
    </script>
  </body>
</html>