react基礎小結

React是一個Facebook和Instagram用來創(chuàng)建用戶界面的JavaScript庫讥电,用于構建“可預期的”和“聲明式的”Web用戶界面花鹅。 該框架的推出主要為了開發(fā)隨著時間數(shù)據(jù)不斷變化的大規(guī)模應用程序钮科。 具體文檔可以參考官網(wǎng)

React具有以下特點:
  • 1.聲明式設計 ?React采用聲明范式,可以輕松描述應用刁笙。
  • 2.高效 ?React通過對DOM的模擬改橘,最大限度地減少與DOM的交互滋尉。
  • 3.靈活 ?React可以與已知的庫或框架很好地配合。
  • 4.JSX ? JSX 是 JavaScript 語法的擴展飞主。React 開發(fā)不一定使用 JSX 狮惜,但我們建議使用它。
  • 5.組件 ? 通過 React 構建組件碌识,使得代碼更加容易得到復用碾篡,能夠很好的應用在大項目的開發(fā)中。
  • 6.單向響應的數(shù)據(jù)流 ? React 實現(xiàn)了單向響應的數(shù)據(jù)流筏餐,從而減少了重復代碼开泽,這也是它為什么比傳統(tǒng)數(shù)據(jù)綁定更簡單。

目錄

1魁瞪、構建與初始化
2穆律、React元素
3、React組件
4导俘、React組件生命周期
5峦耘、受控與非受控組件

1、構建與初始化

  • 方式一:如果你只是想簡單嘗試下 React趟畏,可以使用stackblitz贡歧。在這里滩租,我必須推薦一下這個在線編輯器赋秀,你不需要安裝任何東西,目前支持angular律想、react猎莲、ionic,遲點應該也會支持vue技即。支持github帳號登錄著洼,可以fork和share,一個專門為Web構建的更聰明而叼、更快的包管理器身笤。
  • 方式二:可以使用官網(wǎng)推薦用create-react-app的方式,是開始構建新的React單頁面應用的最佳途徑葵陵。它可以幫你配置開發(fā)環(huán)境液荸,以便你可以使用最新的 JavaScript 特性,還能提供很棒的開發(fā)體驗脱篙,并為生產(chǎn)環(huán)境優(yōu)化你的應用娇钱。
// 在終端下全局安裝官網(wǎng)推薦的create-react-app
npm install -g create-react-app
create-react-app my-app
cd my-app
npm start
  • 方式三: 可以使用像webpack或Browserify這樣的構建工具伤柄,以便于編寫模塊代碼并將其壓縮,優(yōu)化加載時間文搂,這里推薦使用webpack方式适刀。

2、React元素

react 是React庫的入口點煤蹭。如果你通過script標簽加載React笔喉,這些高階API可用于 React 全局。如果你使用ES6硝皂,你可以使用 import React from 'react' 然遏。如果你使用ES5,你可以使用 var React = require('react')

  • 創(chuàng)建React元素有3種方式吧彪,注意:官網(wǎng)認為createFactor方法過時了待侵,推薦你使用JSX或直接使用 React.createElement() 來替代它。JSX可以看做JavaScript的語法拓展(eXtension)姨裸,看起來有點像XML秧倾,讓我們可以在JavaScript中編寫類似HTML的代碼。 使用React傀缩,可以進行JSX語法到JavaScript的轉換那先。判斷一個元素是HTML元素還是React組件的原則是第一個字母是否大寫,如果為大寫赡艰,則認為是React組件售淡,否則認為是HTML元素。如果我們自定義的組件首字母寫成小寫慷垮,那會得不到我們想要的結果揖闸。在JSX中可以通過onClick這樣的方式來給一個元素添加事件處理函數(shù),在HTML我們還可以用onclick(onclick和onClick是不同的)來添加事件

  • 第一種是React.createElement(type,[props],[...children])

var listItemElement1 = React.createElement('li', {className: 'item-1', key: 'item-1'}, 'Item-1')
var listItemElement2 = React.createElement('li', {className: 'item-2', key: 'item-2'}, 'Item-2')
var listItemElement3 = React.createElement('li', {className: 'item-3', key: 'item-3'}, 'Item-3')
var reactFragment = [listItemElement1, listItemElement2, listItemElement3];
var listOfItems = React.createElement('ul', {className: 'list-of-items'}, reactFragment);
  • 第二種是通過創(chuàng)建工廠函數(shù)React.createFactory(type)料身,React.DOM.li(...) 是 React.createELement('li', ...) 的一個包裝寫法汤纸,但被官網(wǎng)認為是過時的,有可能最終會被遺棄芹血。
var createListItemElement = React.createFactory('li');
var listItemElement1 = React.DOM.li({className: 'item-1', key: 'item-1'}, 'Item-1')
var listItemElement2 = React.DOM.li({className: 'item-2', key: 'item-2'}, 'Item-2')
var listItemElement3 = React.DOM.li({className: 'item-3', key: 'item-3'}, 'Item-3')
var reactFragment = [listItemElement1, listItemElement2, listItemElement3];
var listOfItems = React.createElement('ul', {className: 'list-of-items'}, reactFragment);
  • 第三種是使用JSX創(chuàng)建React元素贮泞,編寫React的時候,JSX并不是必須的幔烛。每一個JSX元素都只是 React.createElement(component, props, ...children) 的語法糖啃擦。因此,任何時候你用JSX語法寫的代碼也可以用普通的 JavaScript 語法寫出來饿悬。
var listOfItems = <ul className="list-of-items">
    <li className="item-1">Item 1</li>
    <li className="item-2">Item 2</li>
    <li className="item-3">Item 3</li>
</ul>;
//官網(wǎng)例子jsx寫法
class Hello extends React.Component {
  render() {
    return <div>Hello {this.props.toWhat}</div>;
  }
}
//編譯轉成不使用JSX的代碼
class Hello extends React.Component {
  render() {
    return React.createElement('div', null, `Hello ${this.props.toWhat}`);
  }
}
ReactDOM.render(
  React.createElement(Hello, {toWhat: 'World'}, null),
  document.getElementById('root')
);
  • 渲染React元素
//格式:ReactDOM.render(ReactElement, DOMElement, callback);
ReactDOM.render(
    listOfItems,
    document.getElementById('example')
)

3令蛉、React組件

  • 可以通過三種方式創(chuàng)建React組件,注意乡恕,組件類的第一個字母必須大寫言询,否則會報錯俯萎,比如HelloMessage不能寫成helloMessage。另外运杭,組件類只能包含一個頂層標簽夫啊,否則也會報錯。
  • 第一種無狀態(tài)函數(shù)式組件辆憔,無狀態(tài)函數(shù)式組件形式上表現(xiàn)為只帶有一個render方法的組件類撇眯,通過函數(shù)形式或者ES6 arrow function的形式創(chuàng)建,并且該組件是無state狀態(tài)的虱咧。只要有可能熊榛,盡量使用無狀態(tài)組件。能用React.Component創(chuàng)建的組件的就盡量不用React.createClass形式創(chuàng)建組件腕巡。
function HelloComponent(props) {
    return <div> Hello {props.name} </div>;
}
ReactDOM.render(
    <HelloComponent name="world" />, 
    document.getElementById('example')
) 
  • 第二種React.createClass玄坦,它是react剛開始推薦的創(chuàng)建組件的方式,是用ES5的寫法實現(xiàn)
var InputControlES5 = React.createClass({
    propTypes: {//定義傳入props中的屬性各種類型要求绘沉,可以接受任意值煎楣,字符串、對象车伞、函數(shù)等等择懂。
        initialValue: React.PropTypes.string.isRequired
    },
    defaultProps: { //用來設置組件屬性的默認值
        initialValue: 'Hello World'
    },
    getInitialState: function() {//用于定義初始狀態(tài),也就是一個對象另玖,這個對象可以通過 this.state 屬性讀取困曙。
        return {
            text: this.props.initialValue || 'placeholder'
        };
    },
    handleChange: function(event) {
        this.setState({ //事件的回調(diào)函數(shù),當用戶交互導致狀態(tài)變化谦去,this.setState 方法就修改狀態(tài)值慷丽,每次修改以后,自動調(diào)用this.render方法哪轿,再次渲染組件盈魁。
            text: event.target.value
        });
    },
    render: function() {
        return (
            <div>
                Type something:
                <input onChange={this.handleChange} value={this.state.text} />
            </div>
        );
    }
});

ReactDOM.render(
    <InputControlES5 />, 
    document.getElementById('example')
)
  • 第三種是React.Component,它是以ES6的形式來創(chuàng)建react的組件的窃诉,是React目前極為推薦的創(chuàng)建有狀態(tài)組件的方式,最終會取代React.createClass形式赤套;相對于 React.createClass可以更好實現(xiàn)代碼復用飘痛。將上面React.createClass的形式改為React.Component形式如下:
class InputControlES6 extends React.Component {
    constructor(props) {
        super(props);  //調(diào)用super,是為了正確獲取到this
        this.state = {
            text: props.initialValue || 'placeholder'
        };
        this.handleChange = this.handleChange.bind(this); // ES6 類中函數(shù)必須手動綁定
    }

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

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

InputControlES6.propTypes = {
    initialValue: React.PropTypes.string.isRequired
};
InputControlES6.defaultProps = {
    initialValue: 'Hello Wrold'
};

ReactDOM.render(
    <InputControlES6 />, 
    document.getElementById('example')
)
React.createClass與React.Component區(qū)別
  • React.createClass 創(chuàng)建的組件容握,其每一個成員函數(shù)的this都有React自動綁定宣脉,任何時候,直接使用this.method即可剔氏,函數(shù)中的this會被正確設置
  • React.Component創(chuàng)建的組件塑猖,其成員函數(shù)不會自動綁定this竹祷,需要開發(fā)者手動綁定,否則將它作為事件處理函數(shù)被調(diào)用時不能通過this獲取當前組件實例對象羊苟。
  • React.Component 有三種手動綁定方法:
    1塑陵、在構造函數(shù)中完成綁定
    2、調(diào)用時使用method.bind(this)來完成綁定
    3蜡励、使用arrow function 來綁定
  • 組件屬性類型 propTypes 及其默認 props 屬性 defaultProps 配置不同令花。
  • 組件初始狀態(tài)state配置不同。React.createClass創(chuàng)建的組件凉倚,其狀態(tài)state是通過getInitState方法方法來配置組件的相關狀態(tài)兼都。React.Component創(chuàng)建的組件,其狀態(tài)state是在construct中像初始化組件屬性一樣聲明稽寒。
  • Mixins的支持不同扮碧。React.createClass在創(chuàng)建組件時可以使用mixins屬性,以數(shù)組的形式來混合類的集合杏糙。React.Component不支持Mixins,React開發(fā)者社區(qū)提供了一個全新的方式來取代Mixins芬萍,那就是Higher-Order Components(高階組件)
//React.createClass
const Contacts = React.createClass({  
    handleClick() {
        console.log(this); // React組件實例
    },
    render() {
        return (
            <div onClick={this.handleClick}></div>
        );
    }
});
//React.Component
class Contacts extends React.Component {  
    constructor(props) {
        super(props);
    }
    handleClick() {
        console.log(this); // null
    }
    render() {
        return (
          <div onClick={this.handleClick}></div>
        );
    }
}
//React.Component綁定this方法
constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this); //構造函數(shù)中綁定
}
<div onClick={this.handleClick.bind(this)}></div> //使用bind來綁定
<div onClick={()=>this.handleClick()}></div> //使用arrow function來綁定

4、React組件生命周期

組件的生命周期分成三個狀態(tài):
  • 掛在(Mounting): 這個階段發(fā)生在組件被創(chuàng)建并被插入到DOM時
  • 更新(Updating): 這個階段發(fā)生在組件被重新渲染成虛擬DOM并決定實際DOM是否需要更新時
  • 卸載(Unmounting): 這個階段發(fā)生在組件從DOM中被刪除時
組件掛載階段
ES5(React.createClass)
  • getInitialState()
  • componentWillMount()
  • render()
  • componentDidMount()
ES6(React.Component)
  • constructor()
  • componentWillMount()
  • render()
  • componentDidMount()
組件更新階段
  • componentWillReceiveProps()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • render()
  • componentDidUpdate()
組件卸載階段
  • componentWillUnmount()
var Hello = React.createClass({
    getInitialState: function () {
        return {
            opacity: 1.0
        };
    },
    componentDidMount: function () {
        this.timer = setInterval(function () {
            var opacity = this.state.opacity;
            opacity -= .05;
            if (opacity < 0.1) {
                opacity = 1.0;
            }
            this.setState({
                opacity: opacity
            });
        }.bind(this), 100);
    },
    render: function () {
        return (
            <div style={{opacity: this.state.opacity}}>
                Hello {this.props.name}
            </div>
        );
    }
});
ReactDOM.render(
    <Hello name="world"/>,
    document.body
);

5搔啊、受控與非受控組件

React 通過props和state來區(qū)分組件的屬性和狀態(tài)柬祠。其中,props(屬性)用來表示組件外部傳入的屬性负芋,組件內(nèi)部不能改變漫蛔。而state(狀態(tài))通常表示組件內(nèi)部的狀態(tài),狀態(tài)是可以并且應該改變的旧蛾。React通過 props和state的值來渲染組件莽龟,組件渲染完畢之后,通過響應用戶操作或者異步網(wǎng)絡請求等操作更新組件的狀態(tài)來重新渲染組件锨天。

  • 受控組件將表單數(shù)據(jù)統(tǒng)一存放在 state 中毯盈,交由 React 管理,我們就可以根據(jù)用戶的輸入及時作出響應:1病袄、驗證輸入正確性(輸入格式搂赋、類型等),并作出反饋 2益缠、根據(jù)輸入設置其它組件的狀態(tài)脑奠,譬如輸入不規(guī)范時,提交按鈕處于不可用狀態(tài)
class ControlledForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            username: ''
        }
        this.handleSubmit = this.handleSubmit.bind(this);
        this.updateUsername = this.updateUsername.bind(this);
    }

    updateUsername(e) {
        this.setState({
            username: e.target.value,
        })
    }

    handleSubmit() {}

    render () {
        return (
            <form onSubmit={this.handleSubmit}>
                <input
                    type='text'
                    value={this.state.username}
                    onChange={this.updateUsername} />
                <button type='submit'>Submit</button>
            </form>
        )
    }
}
ReactDOM.render(<ControlledForm />, document.getElementById('react-root'))
  • 非受控組件和傳統(tǒng)的表單數(shù)據(jù)管理一樣幅慌,由DOM存放表單數(shù)據(jù)宋欺,可以使用React提供的refs來獲得DOM元素的引用。在需要的時候(譬如表單提交的時候)一次性獲取表單的值。
class UnControlledForm extends React.Component {
    constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleSubmit(e) {
        e.preventDefault();
        console.log("Value: ", this.input.value)
    }

    render () {
        return (
            <form onSubmit={this.handleSubmit}>
            <input
                type='text'
                ref={(input) => this.input = input} />
            <button type='submit'>Submit</button>
            </form>
        )
    }
}
ReactDOM.render(<UnControlledForm />, document.getElementById('react-root'));
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斑司,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吠式,更是在濱河造成了極大的恐慌陡厘,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件特占,死亡現(xiàn)場離奇詭異糙置,居然都是意外死亡,警方通過查閱死者的電腦和手機是目,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門谤饭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人懊纳,你說我怎么就攤上這事揉抵。” “怎么了嗤疯?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵冤今,是天一觀的道長。 經(jīng)常有香客問我茂缚,道長拟烫,這世上最難降的妖魔是什么嵌戈? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任靖诗,我火速辦了婚禮芦拿,結果婚禮上,老公的妹妹穿的比我還像新娘悔耘。我一直安慰自己讲岁,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布衬以。 她就那樣靜靜地躺著缓艳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泄鹏。 梳的紋絲不亂的頭發(fā)上郎任,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音备籽,去河邊找鬼。 笑死,一個胖子當著我的面吹牛车猬,可吹牛的內(nèi)容都是我干的霉猛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼珠闰,長吁一口氣:“原來是場噩夢啊……” “哼惜浅!你這毒婦竟也來了?” 一聲冷哼從身側響起伏嗜,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤坛悉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后承绸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裸影,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年军熏,在試婚紗的時候發(fā)現(xiàn)自己被綠了轩猩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡荡澎,死狀恐怖均践,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情摩幔,我是刑警寧澤彤委,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站或衡,受9級特大地震影響焦影,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜薇宠,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一偷办、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澄港,春花似錦椒涯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至狱意,卻和暖如春湖苞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背详囤。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工财骨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留镐作,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓隆箩,卻偏偏與公主長得像该贾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子捌臊,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

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

  • 原教程內(nèi)容詳見精益 React 學習指南杨蛋,這只是我在學習過程中的一些閱讀筆記,個人覺得該教程講解深入淺出理澎,比目前大...
    leonaxiong閱讀 2,833評論 1 18
  • GUIDS 第一章 為什么使用React逞力? React 一個提供了用戶接口的JavaScript庫。 誕生于Fac...
    jplyue閱讀 3,532評論 1 11
  • 3. JSX JSX是對JavaScript語言的一個擴展語法糠爬, 用于生產(chǎn)React“元素”寇荧,建議在描述UI的時候...
    pixels閱讀 2,823評論 0 24
  • 本筆記基于React官方文檔,當前React版本號為15.4.0秩铆。 1. 安裝 1.1 嘗試 開始之前可以先去co...
    Awey閱讀 7,700評論 14 128
  • 因為一個眼神砚亭,愛上一個人 因為一個人,愛上一座城 因為一座城殴玛,愛上整個世界 冥冥之中捅膘,仿佛早已注定 你我的相遇恰到...
    東風東風閱讀 146評論 4 8