React 0.14 發佈,拆分爲 react 和 react-dom

React 0.14 正式發佈,此版本包括一些重要的改進,主要是簡化代碼編寫,提供更好的支持環境,比如 React Native。

Reactjs 0.14 獲取:

React 「一分爲二」

原本的 react package 被拆分爲 react 及 react-dom 兩個 package。其中 reactpackage 中包含 React.createElement、 .createClass、 .Component.PropTypes, .Children 這些 API,而 react-dom package 中包含ReactDOM.render、 .unmountComponentAtNode、 .findDOMNode

原本在服務端渲染用的兩個 API .renderToString 和 .renderToStaticMarkup 被放在了react-dom/server 中。

改變之後的結構,一個基本的 React 組件變成了這樣:

var React = require('react');  
var ReactDOM = require('react-dom');var MyComponent = React.createClass({  
  render: function() {
    return <div>Hello World</div>;
  }
});

ReactDOM.render(<MyComponent />, node);

此外,原本 React.addons 下面的工具全部變成了獨立的 package:

  • react-addons-clone-with-props

  • react-addons-create-fragment

  • react-addons-css-transition-group

  • react-addons-linked-state-mixin

  • react-addons-perf

  • react-addons-pure-render-mixin

  • react-addons-shallow-compare

  • react-addons-test-utils

  • react-addons-transition-group

  • react-addons-update

  • ReactDOM.unstable_batchedUpdates (在 react-dom 中)

當然,原本的 API 在 v0.14 版中仍然可以使用,只不過會有 warning,最終會在 v0.15 版的時候完全移除。

refs 變成了真正的 DOM 節點

當我們需要獲取 React 組件上某個 DOM 節點時,React 提供了 refs 方法方便我們快速引用。爲了方便我們使用,React 還「貼心」地對 refs 做了一層封裝,使用 this.refs.xxx.getDOMNode() 或React.findDOMNode(this.refs.xxx) 可以獲取到真正的 DOM 節點。

結果發現大家真正需要的就是 DOM 節點本身,封裝了半天完全是浪費感情。

於是在 v0.14 版中 refs 指向的就是 DOM 節點,同時也會保留 .getDOMNode() 方法(帶 warning),最終在 v0.15 版中去除該方法。

var Zoo = React.createClass({  
  render: function() {
    return <div>Giraffe name: <input ref="giraffe" /></div>;
  },
  showName: function() {
    // 之前:
    // var input = this.refs.giraffe.getDOMNode();
    //
    // v0.14 版:
    var input = this.refs.giraffe;
    alert(input.value);
  }
});

需要注意的是,如果你給自定義的 React 組件(除了 DOM 自帶的標籤,如 divp 等)添加 refs,表現和行爲與之前一致。

無狀態的函數式組件

其實在實際業務系統中使用 React 時,我們會寫很多隻有 render 方法的 React 組件。爲了減少冗餘的代碼量,React v0.14 中引入了 無狀態的函數式組件(Stateless functional components)的概念。先看看長啥樣:

// 一個 ES6 箭頭函數定義的無狀態函數式組件var Aquarium = (props) => {  
  var fish = getFish(props.species);  return <Tank>{fish}</Tank>;
};// 或者更加簡化的版本var Aquarium = ({species}) => (  
  <Tank>
    {getFish(species)}
  </Tank>
);// 最終使用方式: <Aquarium species="rainbowfish" />

可以看到,沒有 React.createClass,也沒有顯式的 render,寫起來更加輕鬆了。

當然,新語法也有需要注意的地方:

  1. 沒有任何生命週期方法,如 componentDidMount 等

  2. 不能添加 refs

  3. 可以通過給函數添加屬性定義 propTypes 和 defaultProps

react-tools 及 JSXTransformer.js 已棄用

擁抱 Babel 吧同學們!

編譯器優化

在 Babel 5.8.23 及更新的版本中,新增了兩項專門針對 React 的優化配置,僅推薦在生產環境中開啓,因爲優化後會導致代碼的報錯更加撲朔迷離(本來報錯就已經很難定位了……)。

  • optimisation.react.inlineElements 將 JSX 元素轉換爲對象而非使用React.createElement

  • optimisation.react.constantElements 針對擁有完全靜態子樹的組件,將其創建過程提升到頂層(Top level),從而減少對 React.createElement 方法的調用

其它變化

  • React.initializeTouchEvents 已棄用

  • 由於 refs 的相關變化(見上文),TestUtils.findAllInRenderedTree 及相關的方法不再接受 DOM 組件作爲參數,只能傳入自定義的 React 組件

  • props 一旦創建永遠不可修改,因此 .setProps 及 .replaceProps 已廢棄

  • children 不可以傳對象類型,推薦傳入數組,或使用 React.createFragment 方法(其實就是轉換爲了數組)

  • React.addons.classSet 已經移除,使用 classnames package 替代

將要發生的改變

在 v0.15 版中,下列內容將會發生改變:

  • this.getDOMNode() 方法將會廢棄,推薦使用 React.findDOMNode()

  • setProps 及 replaceProps 將會廢棄

  • React.addons.cloneWithProps 已廢棄,推薦使用 React.cloneElements,新方法不會自動 merge className 及 style

  • React.addons.CSSTransitionGroup 將不再監聽 transition 事件,因此使用者需要顯式指定動畫的 timeout,如:transitionEnterTimeout={500}

  • ES6 組件類必須 extends React.Component(如果使用 React.createClass 語法則不受影響)

  • 在多次 render 中重用並改變 style 對象已經被棄用(這一點不是太明白,中心思想貌似是不要 mutate object?)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章