我可以使用没有React的jsx来在脚本中内联html吗?

时间:2015-05-25 03:56:34

标签: javascript reactjs react-jsx

我是否可以使用jsx:

这样的库在脚本中内联HTML
<script src="jsx-transform.js"></script>
<script type="text/jsx">
define('component', function () {
   return (<div>test html code</div>);
});
</script>

8 个答案:

答案 0 :(得分:21)

我能够编写JSX文件并使用&#39;假冒&#39;将它们注入HTML页面。反应文件。

无react.js

/**
 * Include this script in your HTML to use JSX compiled code without React.
 */

const React = {
    createElement: function (tag, attrs, children) {
        var element = document.createElement(tag);

        for (let name in attrs) {
            if (name && attrs.hasOwnProperty(name)) {
                let value = attrs[name];
                if (value === true) {
                    element.setAttribute(name, name);
                } else if (value !== false && value != null) {
                    element.setAttribute(name, value.toString());
                }
            }
        }
        for (let i = 2; i < arguments.length; i++) {
            let child = arguments[i];
            element.appendChild(
                child.nodeType == null ?
                    document.createTextNode(child.toString()) : child);
        }
        return element;
    }
};

然后编译你的jsx。

test.jsx

const title = "Hello World";
document.getElementById('app').appendChild(
    <div>
        <h1>{title}</h1>
        <h2>This is a template written in TSX, then compiled to JSX by tsc (the Typescript compiler), and finally
            injected into a web page using a script</h2>
    </div>
);

产生已编译的&#39; test.js&#39;

var title = "Hello World";
document.querySelector('#app').appendChild(React.createElement("div", null,
    React.createElement("h1", null, title),
    React.createElement("h2", null, "This is a template written in TSX, then compiled to JSX by tsc (the Typescript compiler), and finally" + " " + "injected into a web page")));

最后,HTML页面包含两个脚本。

的index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>no-react</title>
    <script src="no-react.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>

<script src="test.js"></script>

答案 1 :(得分:8)

JSX不是基于字符串的模板语言;它编译为实际的JavaScript函数调用。例如,

<div attr1="something" attr2="other">
  Here are some <span>children</span>
</div>

转化为

React.createElement("div", {attr1: "something", attr2: "other"}, 
  "Here are some ", React.createElement("span", null, "children")
)

答案 2 :(得分:6)

我自己也在寻找类似的东西。 一种为简单项目编写组件和JSX的方法。 没找到我喜欢的,所以我建了这个: https://github.com/SagiMedina/Aviya#aviya 看看,也许它也会回答你的问题。

答案 3 :(得分:4)

React使用React.createElement之类的功能(包括Fragments等)将JSX html语法呈现给JS。但这一切都归结为@ babel / plugin-transform-react-jsx插件,它可以进行以下编译:

return(<div id="hello">Hello World</div>)

进入这个...

return React.createElement('div', {id: 'hello'}, 'Hello World');

但是,您可以使用自己的函数替换React.createElement来执行此操作。您可以在这里了解更多信息:https://babeljs.io/docs/en/next/babel-plugin-transform-react-jsx.html

您还应该查看完全做到这一点的库,例如nervjsjsx-renderdeku。所有这些都使用JSX html语法而没有任何反应。有些(例如jsx-render)仅专注于将JSX转换为最终的JS,这可能正是您要寻找的。

该软件包的作者在此处写了一篇文章:https://itnext.io/lessons-learned-using-jsx-without-react-bbddb6c28561

如果您使用Typescript,也可以做到这一点...但是我没有亲身经历。

总结

您可以在没有React的情况下做到这一点,但不能没有Babel或Typescript。

答案 4 :(得分:2)

看起来dom-chef包可以做到这一点。从自述文件:

  • 没有API,JSX会自动转换为实际的DOM元素。

// babel.config.js

const plugins = [
  [
    '@babel/plugin-transform-react-jsx',
    {
      pragma: 'h',
      pragmaFrag: 'DocumentFragment',
    }
  ]
];

// ...

const {h} = require('dom-chef');

const handleClick = e => {
    // <a> was clicked
};

const el = (
    <div class="header">
        <a href="#" class="link" onClick={handleClick}>Download</a>
    </div>
);

document.body.appendChild(el);

答案 5 :(得分:1)

您可以查看文档:{​​{3}}, 另见in-browser JSX transform

你可以达到你想要的效果,但在生产中却不鼓励......

答案 6 :(得分:1)

您将需要一些东西来将JSX转换为JS函数调用。 React使用Babel来做到这一点-您可能最好也这样做。

Preact的创建者提供了一个库,该库实际上可以完成您所追求的vhtml。口号是“将JSX /超脚本渲染为HTML字符串,而无需VDOM”。

以下是撰写本文时自述文件的副本:

用法

// import the library:
import h from 'vhtml';

// tell babel to transpile JSX to h() calls:
/** @jsx h */

// now render JSX to an HTML string!
let items = ['one', 'two', 'three'];

document.body.innerHTML = (
  <div class="foo">
    <h1>Hi!</h1>
    <p>Here is a list of {items.length} items:</p>
    <ul>
      { items.map( item => (
        <li>{ item }</li>
      )) }
    </ul>
  </div>
);

新功能:“排序”组件!

vhtml不会将JSX转换为虚拟DOM,而是将其直接序列化为HTML。但是,仍然可以将基本的纯功能组件用作一种“部分模板”。

当给vhtml一个函数作为JSX标记名称时,它将调用该函数并将其传递给{children,... props}。这是与react / preact中的Pure Functional Component相同的签名,除了child是已经序列化的HTML字符串数组。

这实际上意味着可以使用这些简单的Components甚至更高阶的component来构建成分模板修改器。

这是上一个示例的更复杂的版本,该示例使用组件封装迭代项:

let items = ['one','two'];

const Item = ({ item, index, children }) => (
  <li id={index}>
    <h4>{item}</h4>
    {children}
  </li>
);

console.log(
  <div class="foo">
    <h1>Hi!</h1>
    <ul>
      { items.map( (item, index) => (
        <Item {...{ item, index }}>
          This is item {item}!
        </Item>
      )) }
    </ul>
  </div>
);

上面输出了以下HTML:

<div class="foo">
  <h1>Hi!</h1>
  <ul>
    <li id="0">
      <h4>one</h4>This is item one!
    </li>
    <li id="1">
      <h4>two</h4>This is item two!
    </li>
  </ul>
</div>

答案 7 :(得分:0)

Jsx将return (<div>test html code</div>);解析为类似return React.createElement('div', {...});

的内容

然后,如果您没有使用react.js,那么浏览器将无法知道React是什么并触发错误。