首页 > 解决方案 > 无法在 React 组件中编写 HTML

问题描述

我正在使用没有 Node 的 React 或任何其他东西(我不能使用它,他们要求我在工作中以这种方式使用 react ......我对此无能为力),我正在使用一个 HTML 文件,其中引用了不同的脚本。

所以,我设法使这段代码工作:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Add React in One Minute</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
  </head>
  <body>
    <h1>HTML with multiple scripts using React.js</h1>
    <p>React.js without Node.js or any other thing</p>
    <p>React.js is loaded as script tags.</p>
    <div id="like_button_container"></div>
    <div id="like_button_container2"></div>
    <script src="like_button.js"></script>
    <script src="like_button2.js"></script>
  </body>
</html>

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.';
    }

    return e(
      'button',
      { onClick: () => this.setState({ liked: true }) },
      'Like'
    );
  }
}

const domContainer = document.querySelector('#like_button_container');
ReactDOM.render(e(LikeButton), domContainer);

like_button2.js(是的,是 H1,不是按钮,只是测试):

'use strict';

const f = React.createElement;

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

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

    return f(
      'h1',
      { onClick: () => this.setState({ liked: true }) },
      'Like'
    );
  }
}

const domContainer2 = document.querySelector('#like_button_container2');
ReactDOM.render(f(LikeButton2), domContainer2);

但是,我不能在组件的返回中编写“正常”HTML,因为它不会呈现并且会给我一个错误:

return f(
      <div>LOL</div>
    );

错误图片: https ://i.imgur.com/VqxaQof.png

我该如何解决这个问题?在引号内写 HTMl 真的很有限而且很糟糕......记住,不能使用 Node 或任何其他东西。

而且,¿如何在同一个 div 中渲染所有内容?如果我尝试在同一个 div 上渲染两个组件,它只会渲染第一个脚本,但奇怪的是一个脚本“知道”另一个脚本的存在(例如,变量不能使用相同的名称)。

提前谢谢你,我真的很痛苦。

标签: javascripthtmlreactjs

解决方案


最大的问题是对import语句的支持仅限于更现代的浏览器。因此,如果您想将元素保持在同一div id="root"文件中,那么您要么必须在同一个文件中定义它们,要么使用第三方库。也就是说,JSX不是有效的 HTML,因此您要么被迫强迫用户在每次访问时将 JSX 转换为有效的 JS (糟糕——性能缓慢、代码未优化和带宽浪费),要么您将想要将你的 JSX编译成一个缩小/优化的 js 文件:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Add React in One Minute</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="application/javascript">
    "use strict";function _instanceof(e,t){return null!=t&&"undefined"!=typeof Symbol&&t[Symbol.hasInstance]?!!t[Symbol.hasInstance](e):e instanceof t}function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _classCallCheck(e,t){if(!_instanceof(e,t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function _createClass(e,t,n){return t&&_defineProperties(e.prototype,t),n&&_defineProperties(e,n),e}function _possibleConstructorReturn(e,t){return!t||"object"!==_typeof(t)&&"function"!=typeof t?_assertThisInitialized(e):t}function _getPrototypeOf(e){return(_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function _assertThisInitialized(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&_setPrototypeOf(e,t)}function _setPrototypeOf(e,t){return(_setPrototypeOf=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}var H1LikeButton=function(e){function t(e){var n;return _classCallCheck(this,t),(n=_possibleConstructorReturn(this,_getPrototypeOf(t).call(this,e))).state={isLiked:!1},n.handleClick=n.handleClick.bind(_assertThisInitialized(n)),n}return _inherits(t,React.Component),_createClass(t,[{key:"handleClick",value:function(){this.setState(function(e){return{isLiked:!e.isLiked}})}},{key:"render",value:function(){return React.createElement(React.Fragment,null,this.state.isLiked&&React.createElement("p",null,"This is liked."),React.createElement("h1",{onClick:this.handleClick},!this.state.isLiked?"Like":"Dislike"))}}]),t}(),LikeButton=function(e){function t(e){var n;return _classCallCheck(this,t),(n=_possibleConstructorReturn(this,_getPrototypeOf(t).call(this,e))).state={isLiked:!1},n.handleClick=n.handleClick.bind(_assertThisInitialized(n)),n}return _inherits(t,React.Component),_createClass(t,[{key:"handleClick",value:function(){this.setState(function(e){return{isLiked:!e.isLiked}})}},{key:"render",value:function(){return React.createElement("div",null,this.state.isLiked&&React.createElement("p",null,"This is liked."),React.createElement("button",{onClick:this.handleClick},!this.state.isLiked?"Like":"Dislike"),React.createElement("br",null),React.createElement(H1LikeButton,null))}}]),t}();ReactDOM.render(React.createElement(LikeButton,null),document.getElementById("root"));
</script>
  </body>
</html>

所以...将所有内容编译到一个文件中,或者...您必须使用允许导入/导出 js 文件的第三方库。

工作回购示例(使用requirejs):https ://github.com/mattcarlotta/standalone-requirejs-example

一些可以帮助您的工具:

简而言之,不使用某种捆绑程序(webpack、rollup、gulp、parcel、browserify 等)是不常见的,因此虽然可以在开发中使用 JSX,但您仍然需要编译它以用于生产. 由于无法使用节点和捆绑器,预计会在整个开发/生产过程中受到阻碍。


推荐阅读