React我的整理

  • React基礎
//ReactDOM.render(reactWhat,domWhere)在瀏覽器中渲染應用的一種途徑
//React.DOM表示預約義好的HTML元素集合
//React.DOM.h1(attributes,children)表示一個預約義的React 組件
//h1()第一個參數接收一個對象,用於指定該組件的任何屬性(好比id屬性,三個特殊屬性class:className,for:htmlFor,style:對象形式賦值)。
//h1()第二個參數定義了該組件的子元素(Hello world!)
//document.getElementById("app") 方法訪問DOM 節點,告訴React 須要把應用渲染在頁面的哪一個部分
ReactDOM.render(React.DOM.h1({
    id: 'my-heading'
}, 'Hello world!'), document.getElementById('app'));

// JSX版本
ReactDOM.render(
    <h1 id="my-heading" > <span><em>Hell < /em>o</span > world! < /h1>, document.getElementById('app') ); 複製代碼
  • 自定義新組件
//自定義新組件
var Component = React.createClass({
    //該對象須要包含一個名爲render() 的方法來顯示組件
    render: function () {
        //該方法必須返回一個React 組件,不能只返回文本內容。
        return React.DOM.span(null, 'I\'m so custom');
    }
});
//使用自定義組件
ReactDOM.render(
    //React.createElement() 是建立組件「實例」的方法之一
    React.createElement(Component),
    //若是你想建立多個實例,還有另外一種途徑,就是使用工廠方法:React.createFactory(Component);
    document.getElementById('app')
);
複製代碼
  • props和propTypes
//自定義的組件能夠接收屬性,全部屬性均可以經過this.props對象獲取
var Component = React.createClass({
    //propTypes是可選的,聲明組件須要接收的屬性列表及其對應類型
    propTypes: {
        //清晰地指明瞭name 屬性是一個必須提供的字符串值
        name: React.PropTypes.string.isRequired,
        middleName: React.PropTypes.string,
    },
    //getDefaultProps() 方法返回一個對象,併爲每一個可選屬性(不帶.isRequired的屬性)提供了默認值。
    getDefaultProps: function () {
        return {
            middleName: 'chris'
        };
    },
    render: function () {
        //請把this.props 視做只讀屬性。從父組件傳遞配置到子組件時,屬性很是重要
        return React.DOM.span(null, 'My name is ' + this.props.name);
    }
});
ReactDOM.render(
    React.createElement(Component, {
        name: 'Bob'
    }),
    document.getElementById('app')
);
複製代碼
  • 帶狀態的文本框組件
var TextAreaCounter = React.createClass({
    propTypes: {
        text: React.PropTypes.string,
    },
    getDefaultProps: function () {
        return {
            text: '',
        };
    },
    // 無狀態版本
    render: function () {
        return React.DOM.div(null,
            //文本框使用了defaultValue 屬性,而不是你在常規HTML 中習慣使用的文本子元素
            React.DOM.textarea({
                defaultValue: this.props.text,
            }),
            React.DOM.h3(null, this.props.text.length)
        );
    },

    // 有狀態版本(狀態state負責組件內部數據的維護)
    _textChange: function (ev) {//數據發生改變時(即用戶在文本框中輸入內容時),組件能夠經過一個事件監聽器更新state
        this.setState({//改變state 必須使用this.setState() 方法。該方法接收一個對象參數,並把對象與this.state 中已存在的數據進行合併
            text: ev.target.value,
        });
    },
    getInitialState: function () {//在初始化時,定義state中須要包含的屬性,以保證能夠經過this.state.text訪問屬性
        return {
            text: this.props.text,
        };
    },
    render: function () {
        return React.DOM.div(null,
            //文本框使用了defaultValue 屬性,而不是你在常規HTML 中習慣使用的文本子元素
            React.DOM.textarea({
                value: this.state.text,
                //React 使用了合成事件來消除瀏覽器之間的不一致狀況,React 在事件處理中使用駝峯法命名。
                //當用戶輸入時觸發。而不是像原生DOM 事件那樣,在用戶結束輸入並把焦點從輸入框移走時才觸發。
                onChange: this._textChange,
            }),
            React.DOM.h3(null, this.state.text.length)
        );
    }
});
// 使用自定義組件
ReactDOM.render(
    React.createElement(TextAreaCounter, {
        text: "Bob",
    }),
    document.getElementById("app")
);
複製代碼
  • 從外部訪問組件(謹慎使用)
var myTextAreaCounter = ReactDOM.render(
    React.createElement(TextAreaCounter, {
        defaultValue: "Bob",
    }),
    document.getElementById("app")
);
//設置了新的state 值
myTextAreaCounter.setState({ text: "Hello outside world!" });
//獲取了React 建立的父元素DOM 節點的引用
var reactAppNode = ReactDOM.findDOMNode(myTextAreaCounter);
//獲取DOM 結構中首個<div id="app"> 節點。這也是你讓React 進行渲染的位置:
reactAppNode.parentNode === document.getElementById('app'); // true
//訪問組件的屬性和狀態
myTextAreaCounter.props; // Object { defaultValue: "Bob"}
myTextAreaCounter.state; // Object { text: "Hello outside world!"}
複製代碼
  • 中途改變屬性
//這個方法會接收新屬性對象,讓你能夠根據新屬性設置state
componentWillReceiveProps: function(newProps) {
    this.setState({
        text: newProps.defaultValue,
    });
};
複製代碼

生命週期方法

初始化

  1. getDefaultProps()

設置默認的props,也能夠用dufaultProps設置組件的默認屬性. 對於組件類來講只調用一次,該組件類的全部後續應用,getDefaultPops 將不會再被調用html

  1. getInitialState()

在使用es6的class語法時是沒有這個鉤子函數的,能夠直接在constructor中定義this.statereact

對於組件的每一個實例來講,這個方法的調用有且只有一次,用來初始化每一個實例的 state,在這個方法裏,能夠訪問組件的 this.propses6

getInitialStategetDefaultPops 的調用是有區別的,getDefaultPops 是對於組件類來講只調用一次,後續該類的應用都不會被調用, 而 getInitialState 是對於每一個組件實例來說都會調用,而且只調一次。算法

  1. componentWillMount()

組件初始化以後,首次渲染以前調用,之後組件更新不調用,整個生命週期只調用一次,是在render 方法調用以前修改 state 的最後一次機會。canvas

  1. render()

react最重要的步驟,建立虛擬dom,進行diff算法,更新dom樹都在此進行。此時就不能更改state了。 該方法會建立一個虛擬DOM,用來表示組件的輸出。對於一個組件來說,render方法是惟一一個必需的方法。瀏覽器

render方法須要知足下面幾點:性能優化

(1)只能經過 this.propsthis.state 訪問數據(不能修改)數據結構

(2)能夠返回 null,false 或者任何React組件app

(3)只能出現一個頂級組件,不能返回一組元素dom

(4)不能改變組件的狀態

(5)不能修改DOM的輸出

render方法返回的結果並非真正的DOM元素,而是一個虛擬的表現,相似於一個DOM tree的結構的對象。react之因此效率高,就是這個緣由。

  1. componentDidMount()

組件渲染以後調用,只調用一次。 該方法被調用時,已經渲染出真實的 DOM,能夠再該方法中經過 this.getDOMNode() 訪問到真實的 DOM(推薦使用 ReactDOM.findDOMNode())。

因爲組件並非真實的 DOM 節點,而是存在於內存之中的一種數據結構,叫作虛擬 DOM (virtual DOM)。只有當它插入文檔之後,纔會變成真實的 DOM 。有時須要從組件獲取真實 DOM 的節點,這時就要用到 ref 屬性:

var Area = React.createClass({
    render: function () {
        this.getDOMNode(); //render調用時,組件未掛載,這裏將報錯

        return <canvas ref='mainCanvas' > }, componentDidMount: function () { var canvas = this.refs.mainCanvas.getDOMNode(); //這是有效的,能夠訪問到 Canvas 節點 } }); 複製代碼

須要注意的是,因爲 this.refs.[refName]屬性獲取的是真實 DOM ,因此必須等到虛擬 DOM 插入文檔之後,才能使用這個屬性,不然會報錯。

更新

此時組件已經渲染好而且用戶能夠與它進行交互,好比鼠標點擊,手指點按,或者其它的一些事件,致使應用狀態的改變,你將會看到下面的方法依次被調用

  1. componentWillReceiveProps(nextProps)

組件的 props 屬性能夠經過父組件來更改,這時,componentWillReceiveProps 未來被調用。能夠在這個方法裏更新 state,以觸發 render 方法從新渲染組件。

componentWillReceiveProps: function(nextProps) {
    if (nextProps.checked !== undefined) {
        this.setState({
            checked: nextProps.checked
        })
    }
}
複製代碼
  1. shouldComponentUpdate(nextProps, nextState)

react性能優化很是重要的一環。 組件接受新的state或者props時調用,咱們能夠在此對比先後兩個propsstate是否相同。 若是相同,則返回false阻止更新,由於相同的屬性狀態必定會生成相同的dom樹,這樣就不須要創造新的dom樹和舊的dom樹進行diff算法對比,節省大量性能

若是你肯定組件的 props 或者state 的改變不須要從新渲染,能夠經過在這個方法裏經過返回 false 來阻止組件的從新渲染,返回 false 則不會執行 render 以及後面的 componentWillUpdatecomponentDidUpdate 方法。

該方法是非必須的,而且大多數狀況下不會使用。

  1. componentWillUpdate(nextProps, nextState)

這個方法和 componentWillMount 相似,在組件接收到了新的 props 或者 state 即將進行從新渲染前,componentWillUpdate(object nextProps, object nextState) 會被調用。 注意此時能夠修改state,但最好不要在此方面裏再去更新 props 或者 state

  1. render()

組件渲染

  1. componentDidUpdate()

這個方法和 componentDidMount 相似,在組件從新被渲染以後,componentDidUpdate(object prevProps, object prevState) 會被調用。能夠在這裏訪問並修改 DOM

卸載

  1. componentWillUnmount()

組件將要卸載時調用,一些事件監聽和定時器須要在此時清除。

// 組件卸載
React.unmountComponentAtNode(this.props.containerNode[0]);
複製代碼
相關文章
相關標籤/搜索