JSX 这么6?

时间: 2018-08-06阅读: 2132标签: jsx作者: 转载

本文会先解释一下jsX的工作原理,再介绍一下如何用“不寻常”的方式来使用jsX。如果你已经了解了JSX的工作原理,可以跳过第一部分。如果你只想学一些实用的东西,那可以跳过第二部分。上周,我发了一条这样的动态:


可以看出大家都很喜欢,他们评论区里纷纷留言:“呕”,“这都做了些什么啊”,“天!XML 又回来了”,“又是黑暗的一天” 。我写这篇文章就是为了回报他们的爱。(当然我也和Lorenzo Palmes 打赌,如果这篇tweet收到100个赞我就会写这篇文章,同时感谢 Ken Wheeler的转发).


JSX

只要你用过react,就应该大概了解过 JSX,一种用于创建 react 元素的类 XML 语法

function getGreeting(name) {
  return (
    <div>
      <h1>Hello!</h1>
      <h2>Good to see you {name}</h2>
    </div>
  );
}

因为浏览器还不支持 JSX,所以在运行前,需要将代码转换为普通的 JavaScript。从对开发者友好的代码转换成对浏览器友好的代码这项工作,通常都是用 Babel 这样的工具来做。Babel 编译后,getGreeting函数就会被编译成下面这样:

function getGreeting(name) {
  return React.createElement(
    "div",
    { className: "greeting" },
    React.createElement("h1", { foo: "bar" }, "Hello!"),
    React.createElement("h2", null, "Good to see you ", name)
  );
}

Babel REPL

在这个不同的语法中,所有的标签名、属性名、属性值以及文本内容都没有改变。那么React.createElement是什么?

React.createElement是 React 用来创建元素的方法。因为JSX通常与React同时使用,所以 Babel 默认注入这个方法,但实际情况并非如此。事实上,JSX 是从React中脱离出来的,JSX 是用于在 JS 中使用类似 XML 的语法定义树结构的规范。这个树结构可以是一个 React 组件渲染的元素,也可以是完全不同的其他的东西。

为了不只是在 React 中使用 JSX,我们需要告诉 Babel 使用其他的函数来代替React.createElement。只要在文件中添加/* @jsx 另一个函数名 /这样的注释就行了。例如:

/** @jsx foo */
var bar = <x>Hi</x>;
var bax = <Y>Hi</Y>;

// becomes:
var bar = foo("x", null, "Hi");
var bax = foo(Y, null, "Hi");

最后要说的一点是,Babel会根据元素名称的大小写使用不同的方式处理JSX。小写字母名称会以字符串参数的形式进行传递,首字母大写的名称则会作为函数进行传递,就像在代码段中一样。


数学中的JSX

免责声明:从这里开始,你可能什么都学不到,我将会在一些JSX不该出现的地方使用它。

我们可以使用Math.sqrt(a * a + b * b)来算a和b的弦等于多少,但这一点都不好玩。我们可以用JSX来计算这个:

const Sum = (...args) => args.reduce((a, b) => a + b, 0);
const Pow = ({ exponent }, base) => Math.pow(base, exponent);
const Sqrt = x => Math.sqrt(x);

const Hypotenuse = ({ a, b }) => (
  <Sqrt>
    <Sum>
      <Pow exponent={2}>{a}</Pow>
      <Pow exponent={2}>{b}</Pow>
    </Sum>
  </Sqrt>
);

/** @jsx calc */
function calc(operation, props, ...args) {
  let params = props ? [props] : [];
  params = params.concat(...args);
  return operation(...params);
}

console.log(<Hypotenuse a={3} b={4} />);

codepen

这里还有另一个版本的hypotenuse可以接收两个以上的参数:

const Hypotenuse = ({ values }) => (
  <Sqrt>
    <Sum>{values.map(v => <Pow exponent={2}>{v}</Pow>)}</Sum>
  </Sqrt>
);

console.log(<Hypotenuse values={[3, 4, 5]} />);

codepen


无所不能的JSX

接下来尝试做一些更神奇的事情,我们来试试归并排序。

我们先通过RamdaJS来给组件添加一些原始功能。下面是ramda中的FizzBuzz:

import R from "ramda";
var divisibleBy = R.curry(R.pipe(R.flip(R.modulo), R.equals(0)));
var fizzbuzz = R.map(
  R.cond([
    [R.both(divisibleBy(3), divisibleBy(5)), R.always("FizzBuzz")],
    [divisibleBy(3), R.always("Fizz")],
    [divisibleBy(5), R.always("Buzz")],
    [R.T, R.identity]
  ])
);
console.log(fizzbuzz(R.range(1, 16)));

Code from stackexchange codereview

我们可以使用 JSX 写出相同的代码,只需要编写与JSX元素名称匹配的函数去调用ramda函数就好了:

/** @jsx run */
function run(f, props, ...args) {
  return R[f](...args);
}

var divisibleBy = (
  <curry>
    <pipe>
      <flip>
        <modulo />
      </flip>
      <equals>{0}</equals>
    </pipe>
  </curry>
);

var fizzbuzz = (
  <map>
    <cond>
      {[
        [
          <both>
            {divisibleBy(3)}
            {divisibleBy(5)}
          </both>,
          <always>"FizzBuzz"</always>
        ],
        [divisibleBy(3), <always>"Fizz"</always>],
        [divisibleBy(5), <always>"Buzz"</always>],
        [R.T, <identity />]
      ]}
    </cond>
  </map>
);

console.log(fizzbuzz(R.range(1, 16)));

codepen

好看了?……并没有。运行的函数还可以再智能一点,这样可以增加 JSX 代码的 “纯净度”:

var FizzBuzz = (
  <map>
    <cond concat>
      <pair>
        <both>
          <DivisibleBy value={3} />
          <DivisibleBy value={5} />
        </both>
        <always value="FizzBuzz" />
      </pair>
      <pair>
        <DivisibleBy value={3} />
        <always value="Fizz" />
      </pair>
      <pair>
        <DivisibleBy value={5} />
        <always value="Buzz" />
      </pair>
      <pair>
        <t />
        <identity />
      </pair>
    </cond>
  </map>
);

console.log(
  <FizzBuzz>
    <range>
      {1}
      {16}
    </range>
  </FizzBuzz>
);

codepen

现在,你可以用ramda做的所有事情都可以用JSX来做了。你可以使用它来做任何事情,包括归并排序:


感谢阅读。


原文链接: engineering.hexacta.com 
翻译来源: www.zcfy.cc


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/985

关闭

如何在iview组件中使用jsx

最近选用的框架iview表单组件的render写法让人有点不习惯,尤其是在写比较复杂的逻辑的时候,还是感觉模 板式的写法比较方便且可读性较强。而render函数除了支持配置写法外,还支持jsx的写法。由于之前有用过react,因此对jsx并不陌生,可以直接上手。

如何在 Vue 中使用 JSX 以及使用它的原因

Vue.js 具有简单的 API 和几个选项,可用于在我们的组件中定义HTML模板。我们可以使用<template>标签选项,在根组件实例上定义template属性,或者使用单文件组件。上面的选项很棒并且可以完美地工作

编写干净的 React Components & JSX

遵循单一目的组件哲学,避免过于复杂的多行组件,并尽可能地将组件分解。请记住,在父组件内部完成条件判断操作总是比在组件本身内部完成更为干净。

jsx是什么?_JSX语法简介

JSX就是Javascript和XML结合的一种格式,利用HTML语法来创建虚拟DOM。将XML语法直接加入JS中,通过代码而非模板来高效的定义界面。之后JSX通过翻译器转换为纯JS再由浏览器执行。

React关于JSX

JSX语法是React.createElement的简写语法,要使用它需要汇入(import)react函式库,并且要透过babel工具编译才可以

JSX在render函数中的应用

JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。JSX 可能会使人联想到模版语言,但它具有 JavaScript 的全部功能。Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用。

可替代的JSX

不仅仅是在React(或受JSX启发模板),对于在各种框架中进行模板化,JSX是如今一个非常受欢迎的选择。然而,如果你不喜欢使用JSX,或者你的项目想避免使用它,又或者只是受好奇心驱使

React和JSX基础

脚手架工具:选用React官方推荐的脚手架工具create-react-app,安装npm install create-react-app -g。项目初始化步骤:

Vue中jsx的最简单用法

JSX就是Javascript和XML结合的一种格式。React发明了JSX,利用HTML语法来创建虚拟DOM。当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析.

react本质:JSX如何转化为javascript

react中基本都使用JSX来开发,但JSX其实是javascript的一种语法糖。语法糖就是提供了一种全新的方式书写代码,但是其实现原理与之前的写法相同。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!