React.js in future

クリスマス・イヴですね！
今日はあと2日ということでReact.jsの今後について紹介してみたいと思います。

React.jsをこれからどうしていきたいかについては、facebook/reactとは別のrepositoryで議論されています。

https://github.com/reactjs/react-future

ここにあるものはあくまでアイデアレベルですが具体的なコードで説明されているのでイメージしやすいです。

また昨日も紹介しましたが「React Through the Ages」というスライドでもReact.jsのこれまでとこれからについてが紹介されているのでこちらも注目です。

https://speakerdeck.com/zpao/react-through-the-ages


## これまでのReact.js

React.jsは元々はfacebookがPHP + XMLとして作っていたXHPというプロジェクトから始まっています。

https://github.com/facebook/xhp

それをJavaScriptに持ってきたのがReact.jsで、アプリケーション全体をrerenderする構造はサーバーサイドでのrenderingと似ていることからもその流れを感じます。

また、React.jsは最初は[Standard ML](http://ja.wikipedia.org/wiki/Standard_ML)で作られていて、その後Haxeになって、今のPureなJavaScriptになりました。

## 1.0とその先

1.0やそれ先に向けてどうしていきたいのかというと、「React Through the Ages」を見るとAPIの安定化と削減に加えES6,7に沿った仕様にしたいという意図が感じられます。

* ES 6,7に沿った仕様

ES 6,7などで使えるfeatureをなるべく活用するようにしてReact.js自体では余計なことをやらないような方向性を感じます。

```js
class Button extends React.Component {
  getInitialState() {
    return {count: 0};
  },
  render() {
    return (
      <button onClick={() => this.setState({count: this.state.count + 1 }) }>
        {this.state.count}
      </button>
    );
  }
}
```

* CSS in JS
  * これは昨日のAdventCalendarにも書いた内容で、styleの指定をJavaScript内でやることでCSSが抱える問題を解決しようというアプローチです。

* Web Workers
  * VirtualDOMの計算をWeb WorkersでやることでUIへの影響を軽減できるなら取り入れたいということです。

* Layout & Animation
  * どのように定義出来るようにするのかが難しいけど重要なのでサポートしたいということです。

* M(V)C
  * 自分たちは必要としていないけど多くの開発者がReact.jsと使った時のMVCのMとCについて議論したり開発しているのをみてその辺りも重要な点として考えているようです。React.jsがモノリシックになることはないと思いますが。

* Other
  * その他にもさらなるテストのサポートや、ドキュメント、Immutable Dataなど考えていることは沢山あるようです。


## React.jsの未来？

react-futureのrepositoryを見てみると、ES6,7のfutureをどんどん取り入れていった未来のの姿が見えて面白いです。

ただ、ここにあるものは実装されていないし、合意も取られていないものなのであくまでイメージですのでこうなるとは限りません。


### Class

```js
import { Component } from "react";

export class Button extends Component {
  props : {
    width: number
  }
  static defaultProps = {
    width: 100
  }
  state = {
    counter: Math.round(this.props.width / 10)
  }
  handleClick = (event) => {
    event.preventDefault();
    this.setState({ counter: this.state.counter + 1 });
  }
  render(props, state) {
    return (
      <div>
        This button has been clicked: {state.counter} times
        <button onClick={this.handleClick} style={{ width: props.width }} />
      </div>
    );
  }

```

ES6のModuleやClass、ArrowFunctionなどが使われていてReact.js独自の部分が減っています。
また、`props`の型の指定も変わっていて、これはfacebook/flowとの連携になるのかなと思ったりしています。(CommentにはTypeScript compatible syntaxと書いていましたが)

また、renderにpropsとstateを渡すような形になっています。


### mixin

```js
import { mixin } from "react-utils";


const A = {
  componentDidMount() {
    super();
    console.log('A');
  }
};

class B extends mixin(A) {
  componentDidMount() {
    console.log('B');
    super();
  }
}

new B().componentDidMount(); // B, A

import { Component } from "react";

class Component extends mixin(Component, C) {
  render() {
    return <div />;
  }
}
```

mixinはutilとして用意されて、superで親のものも呼べるようなイメージになっています。
stateのmergeをどうするかといった問題はあるようですが。

### Stateless Functions

```js
export function Button(props : { width: number, onClick: function }) {
  return (
    <div>
      Fancy button
      <button onClick={props.onClick} style={{ width: props.width }} />
    </div>
  );
}
```

Propだけを持つStatelessなComponentについてはPropが渡されるだけの関数として定義出来るようになっています。

### Elements

生のJSやJSXの他にも様々な方法でReact Elementを作成出来るようにする方向性のようです。

* Objectリテラル

```js
{
  type: Button,
  props: {
    foo: bar,
    children: [
      { type: 'span', props: { children: a } },
      { type: 'span', props: { children: b } }
    ]
  },
  // optional
  key: 'mybutton',
  ref: myButtonRef
}
```

* Native Components

React.DOM以下のAPIはなくなりただの文字列として指定出来るようになっています。またWeb Componentsのカスタムタグに対しても互換性を持つようになっています。

* Template Strings

ES6のTemplate Stringsによる指定が使えるようになっています。

```js
X`
 <my-button foo=${bar} key="mybutton" ref=${myButtonRef}>
   <span>${a}</span>
   <span>${b}</span>
 </my-button>
`
```

などなど、色々紹介されているので興味を持った人は是非チェックしてみてください！

https://github.com/reactjs/react-future

------

次の大きなタイミングは1.0だと思いますが、まだ具体的なターゲットも決まってないのでどうなるかわかりませんが楽しみですね。

明日はいよいよ最終日です！