blog icon indicating copy to clipboard operation
blog copied to clipboard

Add React to a Website

Open qingquan-li opened this issue 2 years ago • 0 comments

References:

  • https://reactjs.org/docs/add-react-to-a-website.html
  • https://babeljs.io/docs/en/babel-cli

1. React Component with HTML

./index.html:

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>Add React in One Minute</title>
</head>

<body>

  <h2>Add React in One Minute</h2>
  <p>This page demonstrates using React with no build tooling.</p>
  <p>React is loaded as a script tag.</p>

  <!-- We will put our React component inside this div. -->
  <div id="like_button_container"></div>

  <!-- Load React. -->
  <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
  <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>

  <!-- Load our React component. -->
  <script src="like_button.js"></script>

</body>

</html>

./src/like_button.js:

'use strict';

// const e = React.createElement;

class LikeButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = { liked: false };
  }

  render() {
    if (this.state.liked) {
      return 'You liked this.';
    }

    // Display a "Like" <button>
    // return e(
    //   'button',
    //   { onClick: () => this.setState({ liked: true }) },
    //   'Like'
    // );
    // use React JSX
    return (
      <button onClick={() => this.setState({ liked: true })}>
        Like
      </button>
    );
  }
}

// These three lines of code find the <div> we added to our HTML in the first step,
// create a React app with it,
// and then display our “Like” button React component inside of it.
// const domContainer = document.querySelector('#like_button_container');
// const root = ReactDOM.createRoot(domContainer);
// root.render(e(LikeButton));

let domContainer = document.querySelector('#like_button_container');
ReactDOM.render(<LikeButton />, domContainer);

2. Run JSX Preprocessor (JavaScript XML -> JavaScript)

The only requirement is to have Node.js installed on your computer.

2.1:

$ npm init -y 

Generate package.json:

{
  "name": "add-react-to-site",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

2.2:

$ npm install babel-cli@6 babel-preset-react-app@3

Generate package-lock.json and node_modules.

2.3:

$ npx babel --watch src --out-dir . --presets react-app/prod

Don’t wait for it to finish — this command starts an automated watcher for JSX.

The watcher will create a preprocessed ./like_button.js from ./src/like_button.js with the plain JavaScript code suitable for the browser. When you edit the source file with JSX, the transform will re-run automatically.

./like_button.js:

'use strict';

// const e = React.createElement;

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var LikeButton = function (_React$Component) {
  _inherits(LikeButton, _React$Component);

  function LikeButton(props) {
    _classCallCheck(this, LikeButton);

    var _this = _possibleConstructorReturn(this, (LikeButton.__proto__ || Object.getPrototypeOf(LikeButton)).call(this, props));

    _this.state = { liked: false };
    return _this;
  }

  _createClass(LikeButton, [{
    key: 'render',
    value: function render() {
      var _this2 = this;

      if (this.state.liked) {
        return 'You liked this.';
      }

      // Display a "Like" <button>
      // return e(
      //   'button',
      //   { onClick: () => this.setState({ liked: true }) },
      //   'Like'
      // );
      // use React JSX
      return React.createElement(
        'button',
        { onClick: function onClick() {
            return _this2.setState({ liked: true });
          } },
        'Like'
      );
    }
  }]);

  return LikeButton;
}(React.Component);

// These three lines of code find the <div> we added to our HTML in the first step,
// create a React app with it,
// and then display our “Like” button React component inside of it.
// const domContainer = document.querySelector('#like_button_container');
// const root = ReactDOM.createRoot(domContainer);
// root.render(e(LikeButton));

var domContainer = document.querySelector('#like_button_container');
ReactDOM.render(React.createElement(LikeButton, null), domContainer);

3. Optional: process CORS error

If you wanna quickly try JSX by using babel.js and adding type="text/babel" attribute to <script> tag (it makes your website slow and isn’t suitable for production):

./index.html:

<!-- ... existing HTML ... -->

<!-- Load our React component. -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel" src="src/like_button.js"></script>

<!-- ... existing HTML ... -->

If you open the ./index.html directly, there will be a CORS error when requesting ./src/like_button.js.

Open index-html

This problem would go away if you request the code with HTTP. Ex:

~/add-react-to-site $ python3 -m http.server 8001
HTTP-request

qingquan-li avatar May 30 '22 22:05 qingquan-li