reactjs的一些筆記

 

1.使用虛擬DOM做爲其不一樣的實現。同時能夠由服務器node.js渲染,從而不須要太重的瀏覽器DOM支持。javascript

 
2.虛擬DOM:在瀏覽器端用javascript實現了一套DOM API。用react開發時全部的DOM構造都是經過虛擬DOM進行,每當數據變化時,react都會從新構建整個DOM樹,而後將當前整個DOM樹和上一次的進行對比,獲得區別後,僅僅將須要變化的部分進行實際瀏覽器的DOM樹更新。從而使程序員只須要關心數據總體,兩次數據之間的UI如何變化,就交給框架去作。
 
3.  React 獨有的 JSX 語法,跟 JavaScript 不兼容 凡是使用 JSX 的地方,都要加上 type="text/jsx" 。 其次,React 提供兩個庫: react.js 和 JSXTransformer.js ,它們必須首先加載。其中,JSXTransformer.js 的做用是將 JSX 語法轉爲 JavaScript 語法。這一步很消耗時間,實際上線的時候,應該將它放到服務器完成。
 
4.一個最基本的react組件
    var Greet = React.createClass({
            render:function(){
                return <h1>Hello {this.props.name}</h1>;
            }
        });
        React.render(
            <Greet name="Jack" />,
            document.getElementById('container')
        );
有幾點須要注意:

 1)獲取屬性的值用的是this.props.屬性名css

 2)建立的組件名稱首字母必須大寫。html

 3)爲元素添加css的class時,要用className。java

 4)組件的style屬性的設置方式也值得注意,要寫成style={{width: this.state.witdh}}。這是由於 React 組件樣式是一個對象,因此第一重大括號表示這是 JavaScript 語法,第二重大括號表示樣式對象。node

 

 

5.組件狀態react

    react將組件看作一個狀態機,一旦組件的狀態發生改變,react就會觸發從新渲染UI(自動調用this.render)。經過this.state.XX來定義和設置用戶自定義的狀態。而getInitialState函數則是在組件初始化時執行,返回null或一個對象。例:jquery

     var InputState = React.createClass({git

            getInitialState:function(){程序員

                return {enable:false};github

            },

            handleClick:function(event){

                this.setState({enable:!this.state.enable});

            },

            render:function(){

                return (

                    <p>

                        <input type="text" disabled={this.state.enable} />

                        <button onClick={this.handleClick}>Change State</button>

                    </p>

                );

            }

        });

 這裏值得注意的幾點以下:

 1)getInitialState函數必須有返回值,能夠是NULL或者一個對象。

 2)訪問state的方法是this.state.屬性名。

 3)變量用{}包裹,不須要再加雙引號。

 

6.react組件的生命週期有3個    

  • Mounting:已插入真實 DOM

  • Updating:正在被從新渲染

  • Unmounting:已移出真實 DOM

     

     每一個狀態都有兩種處理函數,will在進入狀態前執行,did在進入以後執行,共五種處理函數: 

  • componentWillMount()

  • componentDidMount()

  • componentWillUpdate(object nextProps, object nextState)

  • componentDidUpdate(object prevProps, object prevState)

  • componentWillUnmount()

 

   此外,react還提供2種特殊狀態的處理函數:
  • componentWillReceiveProps(object nextProps):已加載組件收到新的參數時調用

  • shouldComponentUpdate(object nextProps, object nextState):組件判斷是否從新渲染時調用

     

 

 

7.this.props 對象的屬性與組件的屬性一一對應,可是有一個例外,就是 this.props.children 屬性。它表示組件的全部子節點

這裏須要注意, this.props.children 的值有三種可能:若是當前組件沒有子節點,它就是 undefined ;若是有一個子節點,數據類型是 object ;若是有多個子節點,數據類型就是 array 。因此,處理 this.props.children 的時候要當心。

React 提供一個工具方法 React.Children 來處理 this.props.children 。咱們能夠用 React.Children.map 來遍歷子節點,而不用擔憂 this.props.children 的數據類型是 undefined 仍是 object。更多的 React.Children 的方法,請參考

https://facebook.github.io/react/docs/top-level-api.html#react.children

 

8.組件的屬性能夠接受任意值,字符串、對象、函數等等均可以。有時,咱們須要一種機制,驗證別人使用組件時,提供的參數是否符合要求。

組件類的PropTypes屬性,就是用來驗證組件實例的屬性是否符合要求

 

var MyTitle = React.createClass({
  propTypes:{
    title: React.PropTypes.string.isRequired,},

  render:function(){return<h1>{this.props.title}</h1>;}});

這樣,就規定了MyTitle的title屬性是必須的,且類型爲字符串。若是不符合要求,控制檯就會報錯。

 

更多的PropTypes設置,能夠查看官方文檔

此外,getDefaultProps 方法能夠用來設置組件屬性的默認值。

 

getDefaultProps :function(){return{
      title :'Hello World'};},
 

 

9.組件並非真實的DOM節點,而是存在於內存之中的一種數據結構,叫作虛擬 DOM 。

可是,有時須要從組件獲取真實 DOM 的節點,這時就要用到 ref 屬性

 

var MyComponent = React.createClass({
  handleClick:function(){
    this.refs.myTextInput.focus();},
  render:function(){return(<div><input type="text" ref="myTextInput"/><input type="button" value="Focus the text input" onClick={this.handleClick}/></div>);}});

 

文本輸入框有一個 ref 屬性,而後 this.refs.[refName] 就會返回這個真實的 DOM 節點。須要注意的是,因爲 this.refs.[refName] 屬性獲取的是真實 DOM ,因此必須等到虛擬 DOM 插入文檔之後,才能使用這個屬性。

 

10.組件的構造規則跟函數或者對象的構造規則有殊途同歸之妙,最大的共同點就是單一功能原則,即一個組件應該儘可能只作一件事情,若是它的功能逐漸擴大就須要被拆分爲更小的子組件。

 
11.判斷數據是不是state的方法:
    (1)是不是從父級經過props傳入的?若是是,可能不是state。
    (2)是否會隨着時間改變?若是不是,可能不是state。
    (3)能根據組件中其它state數據或者props計算出來嗎?若是是,就不是state。
 
12.如何判斷哪些組件應該擁有哪些state?

 

 

13.經常使用的通知React 數據變化的方法是調用 setState(data, callback) 。這個方法會合並(merge) data 到 this.state,並從新渲染組件。渲染完成後,調用可選的callback 回調。大部分狀況下不須要提供 callback ,由於 React 會負責把界面更新到最新狀態。嘗試把儘量多的組件無狀態化。 這樣作能隔離 state,把它放到最合理的地方,也能減小冗餘並,同時易於解釋程序運做過程。經常使用的模式是建立多個只負責渲染數據的無狀態(stateless)組件,在它們的上層建立一個有狀態(stateful)組件並把它的狀態經過 props 傳給子級。這個有狀態的組件封裝了全部用戶的交互邏輯,而這些無狀態組件則負責聲明式地渲染數據。

 
14.
 

 
 

15.若是子級要在多個渲染階段保持本身的特徵和狀態,在這種狀況下,你能夠經過給子級設置唯一標識的 key 來區分。當 React 校訂帶有 key 的子級時,它會確保它們被從新排序(而不是破壞)或者刪除(而不是重用)。 務必把 key 添加到子級數組裏組件自己上,而不是每一個子級內部最外層 HTML 上。

 
16.有時候爲了控制性能,須要在數據變化後不更新界面,這種狀況下,能夠重寫shouldComponetUpdate()方法使其返回false來讓react跳過對子樹的處理。    
        注: 若是在數據變化時讓 shouldComponentUpdate() 返回 false,React 就不能保證用戶界面同步 。當使用它的

 

時候必定確保你清楚到底作了什麼,而且只在遇到明顯性能問題的時候才使用它。不要低估 JavaScript 的速

度,DOM 操做一般纔是慢的緣由。

 

 

17. 傳遞Props的技巧,若是想把傳入組件的所有props複製到對應的HTML元素上,<a {...this.props}>便可。有時候不須要傳遞全部屬性,可以使用 var { checked, ...other } = this.props; 再調用other即表明除了checked之外全部的props,而checked就是this,props.checked,能夠直接使用,多個屬性能夠用逗號隔開。若是不使用 JSX,可使用一些庫來實現相同效果。Underscore 提供 _.omit 來過濾屬性, _.extend 複製屬性到新的對象。P60

 

var FancyCheckbox = React.createClass(

 

    render: function() {

 

        var checked = this.props.checked;

 

        var other = _.omit(this.props, 'checked');

 

        var fancyClass = checked ? 'FancyChecked' : 'FancyUnchecked';

 

        return (

 

            React.DOM.div(_.extend({}, other, { className: fancyClass }))

 

        );

 

    }

 

});

 

 


 

 

 

18.propTypes的用法,見P52,限制props的類型。也能夠限制children的個數。
 
19.有時一些複雜的組件須要公用一些功能,相似跨切面關注點,react裏使用mixins來解決這類問題。P55
     例如: 一個組件須要按期更新。用 setInterval() 作很容易,但當不須要它的時候取消定時器來節省內存是很是重要的。
                       
 
 
20.設置了 value 的 是一個受限組件。 對於受限的 ,渲染出來的 HTML 元素始終保持 value屬性的值。要想改變就須要使用onChange事件。若是既想給組件賦一個初始值,又想反應用戶對組件值的改變,能夠設置defaultValue,同理,類型爲radio 、 checkbox 的 支持 defaultChecked 屬性,支持 defaultValue 屬性  
 
21.React中<select>元素設置選中使用value屬性,而不是option的select屬性。
 
22.爲了和瀏覽器交互,有時候須要對DOM節點的引用,使用refs和getDOMNode()便可,注意只有在組件已經放進了DOM中時,此方法纔有用。
 
23.組件的生命週期
     React組件的生命週期主要包括  掛載更新移除 三個部分。
        掛載期函數: 
            (1)getInitialState(): object 在組件被掛載以前調用。狀態化的組件應該實現這個方法,返回初始的state數據。
 
            (2)componentWillMount() 在掛載發生以前當即被調用。
            (3)componentDidMount() 在掛載結束以後立刻被調用。須要DOM節點的初始化操做應該放在這裏。
 
        更新期函數:
            (1)componentWillReceiveProps(object nextProps) 當一個掛載的組件接收到新的props的時候被調用。該方法應該用於比較this.props 和 nextProps ,而後使用 this.setState() 來改變state。
            (2)shouldComponentUpdate(object nextProps, object nextState): boolean 當組件作出是否要更新DOM決定的時候被調用。實現該函數,優化 this.props 和 nextProps ,以及 this.state 和 nextState 的比較,若是不須要React更新DOM,則返回false。
            (3)componentWillUpdate(object nextProps, object nextState) 在更新發生以前被調用。你能夠在這裏調用 this.setState()。
            (4)componentDidUpdate(object prevProps, object prevState) 在更新發生以後調用。
 
        移除期函數:
            (1)componentWillUnmount() 在組件移除和銷燬以前被調用。清理工做應該放在這裏。
 
 
 
 
        
 
24.shouldComponentUpdate()更新原理:
    
 
 
 
    詳情見P74
 
 
25. Immutable-js
 
immutable-js提供了經過結構性共享一成不變持久化集合。讓咱們看看這些性能:

 

        • 不可變的:一旦建立,集合不能在另外一個時間點改變。

        • 持久性:新的集合能夠由從早先的集合和突變結合建立。在建立新的集合後,原來集合仍然有效。

        • 結構共享:使用新的集合建立爲與對原始集合大體相同的結構,減小了拷貝的最低限度,以實現空間效率和可接受的性能。若是新的集合等於原始的集合,則一般會返回原來的集合。

 

   

     不變性使得跟蹤更改方便;而變化將老是產生在新的對象,因此咱們只須要檢查的已經改變參考對象。

    即原始的對象是不變的,每當對原始數據進行改變,會建立一個新的對象。

    例:           

            var SomeRecord = Immutable.Record({ foo: null });
            var x = new SomeRecord({ foo: 'bar' });
            var y = x.set('foo', 'baz');
            x === y; // false

 

26.  React API

    (1)React.createClass  再也不贅述。

    (2)React.createElement:

                    

 

 

            ReactElement createElement(
                string/ReactClass type,
                [object props],
                [children ...]
            )

            建立並返回一個新的指定類型的 ReactElement。type 參數能夠是一個 html 標籤名字字符串(例如,「div」,「span」,等等),或者是 ReactClass (經過 React.createClass 建立的)。

 

 

 

 

 

 

 
 
    (3)React.createFactory:

 

           

            factoryFunction createFactory(
                string/ReactClass type
            )

            返回一個生成指定類型 ReactElements 的函數。好比 React.createElement,type 參數能夠是一個 html 標籤名字字符串(例如,「div」,「span」,等等),或者是 ReactClass 。

 
 
    (4) boolean unmountComponentAtNode(DOMElement container)

 

            從 DOM 中移除已經掛載的 React 組件,清除相應的事件處理器和 state。若是在 container 內沒有組件掛 載,這個函數將什麼都不作。若是組件成功移除,則返回 true ;若是沒有組件被移除,則返回 false 。

 
 
    (5)string renderToString(ReactElement element)

 

            把組件渲染成原始的 HTML 字符串。該方法應該僅在服務器端使用。React 將會返回一個 HTML 字符串。你能夠在服務器端用此方法生成 HTML,而後將這些標記發送給客戶端,這樣能夠得到更快的頁面加載速度,而且有利於搜索引擎抓取頁面,方便作 SEO。

 

    (6) string renderToStaticMarkup(ReactElement element)

 

            和 renderToString 相似,除了不建立額外的 DOM 屬性,例如 data-react-id ,由於這些屬性僅在 React 內部使用。若是你想用 React 作一個簡單的靜態頁面生成器,這是頗有用的,由於丟掉額外的屬性可以節省不少字節。

 

    (7)React.isValidElement

 

            boolean isValidElement(* object)判斷對象是不是一個 ReactElement。

 

    (8)initializeTouchEvents(boolean shouldUseTouch)

 

            配置 React 的事件系統,使 React 能處理移動設備的觸摸( touch )事件。

    

    (9)React.ChildrenReact.Children

 

            React.Children 爲處理 this.props.children 這個封閉的數據結構提供了有用的工具。

            詳情見P82,有.map 、.forEach、.count、.only等用法。

 

    27.ReactComponent    

            React 組件實例在渲染的時候建立。這些實例在接下來的渲染中被重複使用,能夠在組件方法中經過 this 訪問。惟一一種在 React 以外獲取 React 組件實例句柄的方式就是保存 React.render 的返回值。在其它組件內,可使用 refs 獲得相同的結果。

            

    (1)setState(object nextState[, function callback]))

 

 

 

            合併 nextState 和當前 state。這是在事件處理函數中和請求回調函數中觸發 UI 更新的主要方法。另外,也支持可選的回調函數,該函數在 setState 執行完畢而且組件從新渲染完成以後調用。

 

 

            注:setState() 不會馬上改變 this.state ,而是建立一個即將處理的 state 轉變。在調用該方法以後獲取 this.state 的值可能會獲得現有的值,而不是最新設置的值。   
        

    (2)replaceState(object nextState[, function callback])相似於 setState(),可是刪除以前全部已存在的 state 鍵,這些鍵都不在 nextState 中。

 

    

    (3)forceUpdate([function callback])

            若是 render() 方法從 this.props 或者 this.state 以外的地方讀取數據,你須要經過調用 forceUpdate() 告訴 React 何時須要再次運行 render()。若是直接改變了 this.state ,也須要調用 forceUpdate()。

            注:應該儘可能避免使用forceUpdate的狀況。

    

    (4)bool isMounted()

 

            若是組件渲染到了 DOM 中, isMounted() 返回 true。可使用該方法保證 setState() 和 forceUpdate() 在異步場景下的調用不會出錯。

 

    (5)

 

28.render() 函數應該是純粹的,也就是說該函數不修改組件 state,每次調用都返回相同的結果,不讀寫 DOM 信息,也不和瀏覽器交互(例如經過使用 setTimeout )。若是須要和瀏覽器交互,在 componentDidMount()中或者其它生命週期方法中作這件事。保持 render() 純粹,可使服務器端渲染更加切實可行,也使組件更容易被理解。

 

 

 

 

 

 

 

 

 

29.object statics

 

        statics 對象容許你定義靜態的方法,這些靜態的方法能夠在組件類上調用。

 

30. React 也提供了一些 DOM 裏面不存在的屬性。

 

 

        • key :可選的惟一的標識器。當組件在 渲染 過程當中被各類打亂的時候,因爲差別檢測邏輯,可能會被銷燬後從新建立。給組件綁定一個 key,能夠持續確保組件還存在 DOM 中。 

 

        • ref:參考這裏 (頁 0)

        • dangerouslySetInnerHTML :提供插入純 HTML 字符串的功能,主要爲了能和生成 DOM 字符串的庫整合。

 

 

31.React的渲染策略

    (1)若先後兩個節點元素或者組件的類型不一樣,React會直接把他們當作不一樣的子樹,甚至不會嘗試計算出該渲染什麼,直接從DOM中移除以前的節點,而後插入新的節點。

    (2)比較兩個DOM節點的時候,查看二者的屬性,而後找出變化的屬性。

    (3)對於自定義組件,React決定2個自定義組件是相同的,利用新組件上的全部屬性,而後再以前的組件實例上調用componetWill(Did)ReceiveProps()。如今,以前的組件的render(0被調用,而後差別算法從新比較新的狀態和上一次的狀態。

    (4)爲了完成子級更新,React同時遍歷兩個子級列表,當發現差別的時候,就產生一次DOM修改。        

            在開始處插入元素比較麻煩。React 發現兩個節點都是 span,所以直接修改已有 span 的文本內容,而後在後面插入一個新的 span 節點。

                renderA:<div><span>first</span></div>

                renderB:<div><span>secon</span><span>first</span></div>
            => [replaceAttribute textContent 'second'], [insertNode <span>first</span>]

        爲了解決這個問題,引入了一個可選的屬性keys。若是指定了一個鍵值,React 就可以檢測出節點插入、移除和替換,而且藉助哈希表使節點移動複雜度爲O(n)。

        注:鍵值只須要在兄弟節點中惟一,而不是全局惟一。

        

32.行內樣式:    

    var divStyle = {
        color: 'white',
        backgroundImage: 'url(' + imgUrl + ')',
        WebkitTransition: 'all', // 注意這裏的首字母'W'是大寫
        msTransition: 'all' // 'ms'是惟一一個首字母須要小寫的瀏覽器前綴
    };

    React.render(Hello World!, mountNode);

 

33.一般,一個組件的子代(this.props.children)是一個組件的數組,即爲數組類型,可是當只有一個子代的時候,this.props.children是一個單獨的組件,而不是數組形式,這樣就減小了數組的佔用。

 

 

 

 

 

 

34.getInitialState裏的props是一個反模式。詳情見P118。

 

35.給DOM元素綁定React未提供的事件,好比想共用react和jquery的時候,在componentDidMount中 調用  

 

component.addEventListener('xxx', this.handleResize) 綁定事件,在componentWillUnmount中removeEventListener()取消綁定。詳情見P120

 
36.在 componentDidMount 時加載數據。當加載成功,將數據存儲在 state 中,觸發 render 來更新你的 UI。

 

當執行同步請求的響應時,在更新 state 前, 必定要先經過 this.isMounted() 來檢測組件的狀態是否仍是 mou

nted。

相關文章
相關標籤/搜索