CJSX试用 – 使用React靠谱的新姿势

背景

React真是个好东西,不过JS语法有时候还是难免显得臃肿。ES6虽然改进了许多,不过还是有很多槽点。比起来我感觉CoffeeScript就舒服了许多。

React魔改了一番JS,使其能在JS代码中直接插入HTML代码,这样魔改之后的JS叫做JSX。本文对JSX就不做过多的赘述了,我们直接来说CoffeeScript版本的“JSX”——CJSX。虽然说是新姿势,不过其实cjsx已经有一段时间了。不过接下来,我先不介绍CJSX,先行介绍一些的其他的在React中使用CoffeeScript的姿势。

react-coffee

为了让CoffeeScript能舒服的用上React,最简单的方法莫过于把React DOM封装成一个库,然后直接调用。这么做的不止coffee-react一家,不过coffee-react挺具有代表性的,所以我们就拿他来说。以及这个名字和我们主要要介绍的那个库很像,不要搞错了!先来看看官方给出的一段代码示例:

{div}= React.DOM

module.exports= React.Component.toComponent class MyComponent

 render: ->
 (div null,
 "My Component!"
 )

不评论风格美丑,但是要论优雅程度,我觉得还差那么点w

coffee-react

这篇文章的主角就是这个了。直接来看看官方的示例吧:

NeatComponent = React.createClass
  render: ->
    <div className="neat-component">
      {<h1>A Component is I</h1> if @props.showTitle}
      <hr />
      {<p key={n}>This line has been printed {n} times</p> for n in [1..5]}
    </div>

简直就是Coffee中的JSX啊!不过可惜的是,这样就需要再编译了。不过其实也无所谓,毕竟cs本身也要编译成js的。不过这里要说明下,因为这篇文章的写作开始的很早,一切都发生了变化……首先就是,这个库停止维护了。目前能达到此功能且依旧在维护的是:https://github.com/jsdf/cjsx-codemod。

cjsx-in-browser

这个库是用来在浏览器中直接调试cjsx的,把官网的例子重新写一下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>233333333333</title>
</head>
<body>
<div id="example">
</div>

<script type="text/cjsx">
HelloWorldApp = React.createClass
  getInitialState: ->
    clock: 0
    
  componentWillMount: ->
    setInterval =>
        @setState clock: @state.clock+1
    , 1000
  
  resetClock: ->
    @setState clock: 0
    
  render: ->
    <div className="hi">
      <h1>Hello, world!</h1>
      <p>Seconds elapsed: {@state.clock}</p>
      <button 
        onClick={@resetClock} 
        disabled={if @state.clock < 2 then 'disabled' else ''}>
      Reset
      </button>
      <ul>
        { <li>{i}</li> for i in [0...@props.listLength]  }
      </ul>
    </div>

React.renderComponent <HelloWorldApp listLength=9 />, document.getElementById('example')
</script>
<script type="text/javascript" src="react-0.11.1.js"></script>
<script type="text/javascript" src="https://rawgit.com/iamdanfox/cjsx-in-browser/master/cjsx-in-browser.js"></script>
</body>
</html>

运行效果大致如下:

这是编译时的中间结果:

HelloWorldApp = React.createClass
  getInitialState: ->
    clock: 0
    
  componentWillMount: ->
    setInterval =>
        @setState clock: @state.clock+1
    , 1000
  
  resetClock: ->
    @setState clock: 0
    
  render: ->
    React.DOM.div({"className": "hi"}, 
      React.DOM.h1(null, "Hello, world!"), 
      React.DOM.p(null, "Seconds elapsed: ", (@state.clock)), 
      React.DOM.button({  \
        "onClick": (@resetClock),   \
        "disabled": (if @state.clock < 2 then 'disabled' else '')}, """
      Reset
"""), 
      React.DOM.ul(null, 
        ( React.DOM.li(null, (i)) for i in [0...@props.listLength]  )
      )
    )

React.renderComponent HelloWorldApp({"listLength": 9}), document.getElementById('example')

这是最后的状态:

(function() {
  var HelloWorldApp;

  HelloWorldApp = React.createClass({
    getInitialState: function() {
      return {
        clock: 0
      };
    },
    componentWillMount: function() {
      return setInterval((function(_this) {
        return function() {
          return _this.setState({
            clock: _this.state.clock + 1
          });
        };
      })(this), 1000);
    },
    resetClock: function() {
      return this.setState({
        clock: 0
      });
    },
    render: function() {
      var i;
      return React.DOM.div({
        "className": "hi"
      }, React.DOM.h1(null, "Hello, world!"), React.DOM.p(null, "Seconds elapsed: ", this.state.clock), React.DOM.button({
        "onClick": this.resetClock,
        "disabled": (this.state.clock < 2 ? 'disabled' : '')
      }, "Reset"), React.DOM.ul(null, (function() {
        var _i, _ref, _results;
        _results = [];
        for (i = _i = 0, _ref = this.props.listLength; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
          _results.push(React.DOM.li(null, i));
        }
        return _results;
      }).call(this)));
    }
  });

  React.renderComponent(HelloWorldApp({
    "listLength": 9
  }), document.getElementById('example'));

}).call(this);

后记:CS2

在半个多月之前,CS2发布了其第一个正式版本。其中一个重大更新就是——CS原生支持像JSX这样的写法了。于是这篇文章就彻底的作废了。这里是官方传送门:http://coffeescript.org/v2/#jsx。关于CS2的其他更新,我会撰写新的博文。

分享到

KAAAsS

喜欢二次元的程序员,喜欢发发教程,或者偶尔开坑。(←然而并不打算填)

相关日志

  1. 没有图片
  2. 没有图片
  3. 没有图片
  4. 没有图片
  5. 没有图片

评论

  1. 开发者头条 2017.08.28 1:32下午

    感谢分享!已推荐到《开发者头条》:https://toutiao.io/posts/dg5jou 欢迎点赞支持!
    欢迎订阅《KAAAsS的J&A教室》https://toutiao.io/subjects/69380

  2. 上海seo 2017.10.06 6:15下午

    代码很复杂的感觉。。

在此评论中不能使用 HTML 标签。