React基礎(chǔ)進階

結(jié)合最近對react項目優(yōu)化的同時,對一些第一次看來感覺很容易疲扎,但是使用上容易搞混淆的東西再學習和整理一番昵时。由于是老項目,主要采用的是React.createElement的方式來使用椒丧。

關(guān)于React.createElement

  string/ReactClass type,  
  [object props],  
  [children ...]  
)  
第一個參數(shù):必填壹甥,元素類型
第二個參數(shù):可填,元素屬性
第三個參數(shù):可填壶熏,元素子節(jié)點

var child1 = React.createElement('li', null, 'First Text Content');  
var child2 = React.createElement('li', null, 'Second Text Content');  
var child3 = React.createElement('li', null, 'Third Text Content');  
var root = React.createElement('ul', { className: 'my-list' }, child1, child2, child3);
等價
var root = React.createElement('ul', { className: 'my-list' }, [child1, child2, child3]); 
ReactDOM.render(  
        root,  
        document.getElementById('content')  
);  

React其實有三種定義react組件的方式:

函數(shù)式定義的無狀態(tài)組件
es5原生方式React.createClass定義的組件
es6形式的extends React.Component定義的組件

上面的屬于es5原生方式React.createClass定義的組件句柠。

函數(shù)式定義的無狀態(tài)組件

創(chuàng)建無狀態(tài)函數(shù)式組件形式是從React 0.14版本開始出現(xiàn)的。

無狀態(tài)函數(shù)式組件形式上表現(xiàn)為一個只帶有一個render方法的組件類久橙,通過函數(shù)形式或者ES6 arrow function的形式在創(chuàng)建俄占,并且該組件是無state狀態(tài)的。具體的創(chuàng)建形式如下:

function HelloComponent(props, /* context */) { return <div>Hello {props.name}</div> } ReactDOM.render(<HelloComponent name="Sebastian" />, mountNode)

它是為了創(chuàng)建純展示組件淆衷,這種組件只負責根據(jù)傳入的props來展示缸榄,不涉及到要state狀態(tài)的操作。具體的無狀態(tài)函數(shù)式組件.

1,組件不會被實例化祝拯,整體渲染性能得到提升
2,組件不能訪問this對象
3,組件無法訪問生命周期的方法
4,無狀態(tài)組件只能訪問輸入的props甚带,同樣的props會得到同樣的渲染結(jié)果,不會有副作用

es6形式的extends React.Component定義的組件

React.Component是以ES6的形式來創(chuàng)建react的組件的佳头,是React目前極為推薦的創(chuàng)建有狀態(tài)組件的方式鹰贵,最終會取代React.createClass形式;
`
class InputControlES6 extends React.Component {
constructor(props) {
super(props);

    // 設(shè)置 initial state
    this.state = {
        text: props.initialValue || 'placeholder'
    };

    // ES6 類中函數(shù)必須手動綁定
    this.handleChange = this.handleChange.bind(this);
}

handleChange(event) {
    this.setState({
        text: event.target.value
    });
}

render() {
    return (
        <div>
            Type something:
            <input onChange={this.handleChange}
           value={this.state.text} />
        </div>
    );
}

}
`

React.createClass與React.Component區(qū)別

函數(shù)this自綁定

React.createClass創(chuàng)建的組件康嘉,其每一個成員函數(shù)的this都有React自動綁定碉输,任何時候使用,直接使用this.method即可亭珍,函數(shù)中的this會被正確設(shè)置敷钾。

const Contacts = React.createClass({  
  handleClick() {
    console.log(this); // React Component instance
  },
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
});

React.Component創(chuàng)建的組件枝哄,其成員函數(shù)不會自動綁定this,需要開發(fā)者手動綁定阻荒,否則this不能獲取當前組件實例對象挠锥。

class Contacts extends React.Component {  
  constructor(props) {
    super(props);
  }
  handleClick() {
    console.log(this); // null
  }
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }

當然,React.Component有三種手動綁定方法:可以在構(gòu)造函數(shù)中完成綁定侨赡,也可以在調(diào)用時使用method.bind(this)來完成綁定蓖租,還可以使用arrow function來綁定。拿上例的handleClick函數(shù)來說羊壹,其綁定可以有:

    constructor(props) {
       super(props);
       this.handleClick = this.handleClick.bind(this); //構(gòu)造函數(shù)中綁定
  }
    <div onClick={this.handleClick.bind(this)}></div> //使用bind來綁定
    <div onClick={()=>this.handleClick()}></div> //使用arrow function來綁定

組件屬性類型propTypes及其默認props屬性defaultProps配置不同

React.createClass在創(chuàng)建組件時蓖宦,有關(guān)組件props的屬性類型及組件默認的屬性會作為組件實例的屬性來配置,其中defaultProps是使用getDefaultProps的方法來獲取默認組件屬性的

const TodoItem = React.createClass({
    propTypes: { // as an object
        name: React.PropTypes.string
    },
    getDefaultProps(){   // return a object
        return {
            name: ''    
        }
    }
    render(){
        return <div></div>
    }
})

React.Component在創(chuàng)建組件時配置這兩個對應信息時舶掖,他們是作為組件類的屬性球昨,不是組件實例的屬性,也就是所謂的類的靜態(tài)屬性來配置的眨攘。對應上面配置如下:

class TodoItem extends React.Component {
    static propTypes = {//類的靜態(tài)屬性
        name: React.PropTypes.string
    };

    static defaultProps = {//類的靜態(tài)屬性
        name: ''
    };

    ...
}

組件初始狀態(tài)state的配置不同

React.createClass創(chuàng)建的組件主慰,其狀態(tài)state是通過getInitialState方法來配置組件相關(guān)的狀態(tài);
React.Component創(chuàng)建的組件鲫售,其狀態(tài)state是在constructor中像初始化組件屬性一樣聲明的共螺。

const TodoItem = React.createClass({
    // return an object
    getInitialState(){ 
        return {
            isEditing: false
        }
    }
    render(){
        return <div></div>
    }
})
class TodoItem extends React.Component{
    constructor(props){
        super(props);
        this.state = { // define this.state in constructor
            isEditing: false
        } 
    }
    render(){
        return <div></div>
    }
}

Mixins的支持不同

Mixins(混入)是面向?qū)ο缶幊蘋OP的一種實現(xiàn),其作用是為了復用共有的代碼情竹,將共有的代碼通過抽取為一個對象藐不,然后通過Mixins進該對象來達到代碼復用。具體可以參考React Mixin的前世今生秦效。

React.createClass在創(chuàng)建組件時可以使用mixins屬性雏蛮,以數(shù)組的形式來混合類的集合。

var SomeMixin = {  
  doSomething() {

  }
};
const Contacts = React.createClass({  
  mixins: [SomeMixin],
  handleClick() {
    this.doSomething(); // use mixin
  },
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
});

但是遺憾的是React.Component這種形式并不支持Mixins阱州,至今React團隊還沒有給出一個該形式下的官方解決方案挑秉;但是React開發(fā)者社區(qū)提供一個全新的方式來取代Mixins,那就是Higher-Order Components

Higher-Order Components

通過函數(shù)向現(xiàn)有組件類添加邏輯,就是高階組件苔货。

讓我們先來看一個可能是史上最無聊的高階組件:

  return function(Comp) {
    return class NoID extends Component {
      render() {
        const {id, ...others} = this.props;
        return (
          <Comp {...others}/>
        )
      }
    }
  }
}

const WithoutID = noId()(Comp);

這個例子向我們展示了高階組件的工作方式:通過函數(shù)和閉包犀概,改變已有組件的行為——這里是忽略id屬性——而完全不需要修改任何代碼。

之所以稱之為高階夜惭,是因為在React中姻灶,這種嵌套關(guān)系會反映到組件樹上,層層嵌套就好像高階函數(shù)的function in function一樣.

補充一點

無狀態(tài)組件內(nèi)部其實是可以使用ref功能的诈茧,雖然不能通過this.refs訪問到产喉,但是可以通過將ref內(nèi)容保存到無狀態(tài)組件內(nèi)部的一個本地變量中獲取到。

例如下面這段代碼可以使用ref來獲取組件掛載到dom中后所指向的dom元素:

function TestComp(props){
let ref;
return (<div>
<div ref={(node) => ref = node}>
...
</div>
</div>)
}
參考:
https://segmentfault.com/a/1190000004598113
https://www.cnblogs.com/wonyun/p/5930333.html
http://www.cnblogs.com/sven36/p/6267105.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市曾沈,隨后出現(xiàn)的幾起案子尘颓,更是在濱河造成了極大的恐慌,老刑警劉巖晦譬,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異互广,居然都是意外死亡敛腌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門惫皱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來像樊,“玉大人,你說我怎么就攤上這事旅敷∩鳎” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵媳谁,是天一觀的道長涂滴。 經(jīng)常有香客問我,道長晴音,這世上最難降的妖魔是什么柔纵? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮锤躁,結(jié)果婚禮上搁料,老公的妹妹穿的比我還像新娘。我一直安慰自己系羞,他們只是感情好郭计,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著椒振,像睡著了一般昭伸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上杠人,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天勋乾,我揣著相機與錄音,去河邊找鬼嗡善。 笑死辑莫,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的罩引。 我是一名探鬼主播各吨,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了揭蜒?” 一聲冷哼從身側(cè)響起横浑,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎屉更,沒想到半個月后徙融,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡瑰谜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年欺冀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片萨脑。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡隐轩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出渤早,到底是詐尸還是另有隱情职车,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布鹊杖,位于F島的核電站悴灵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏骂蓖。R本人自食惡果不足惜称勋,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望涯竟。 院中可真熱鬧赡鲜,春花似錦、人聲如沸庐船。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽筐钟。三九已至揩瞪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間篓冲,已是汗流浹背李破。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留壹将,地道東北人嗤攻。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像诽俯,于是被迫代替她去往敵國和親妇菱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容

  • 原教程內(nèi)容詳見精益 React 學習指南,這只是我在學習過程中的一些閱讀筆記闯团,個人覺得該教程講解深入淺出辛臊,比目前大...
    leonaxiong閱讀 2,843評論 1 18
  • React創(chuàng)建組件的三種方式及其區(qū)別 React推出后,出于不同的原因先后出現(xiàn)三種定義react組件的方式房交,殊途同...
    程序猿吳彥祖閱讀 260評論 0 0
  • 轉(zhuǎn)載自https://www.cnblogs.com/wonyun/p/5930333.html React推出后...
    8d2855a6c5d0閱讀 364評論 0 2
  • React推出后彻舰,出于不同的原因先后出現(xiàn)三種定義react組件的方式。 具體的三種方式: (1)函數(shù)式定義的無狀態(tài)...
    一只dororo閱讀 865評論 0 1
  • react腳手架大集合 react4.0 官網(wǎng)redux入門教程react-native中文官網(wǎng)react官方文檔...
    pauljun閱讀 492評論 0 7