React文檔閱讀

自己最近的項(xiàng)目是基于react的德挣,于是讀了一遍react的文檔平绩,做了一些記錄(除了REFERENCE部分還沒開始讀)

文章也可以直接訪問我的前端網(wǎng)站來查看

quick start

Tutorial

建立一個模塊

我們可以使用React.createClass()來創(chuàng)建一個React模塊圈匆。我們通過一個JS對象傳了一些方法給這個函數(shù),最重要的方法是render捏雌,返回了最終會變成HTML的部分跃赚。

render里面的div不是真正的DOM節(jié)點(diǎn),他們是React的div components的實(shí)例化性湿,不直接產(chǎn)生HTML纬傲,所以XSS保護(hù)是默認(rèn)的。

我們使用ReactDom.render()來實(shí)例化入口框架肤频,這個方法必須在最下面模塊定義好了才執(zhí)行叹括,這個方法來真正的產(chǎn)生DOM,其他的平臺的話有其他的生成方式着裹,比如React Native领猾。

HTML tags在生成的時候會調(diào)用React.createElement(tagName)來創(chuàng)建。

this.props

由父模塊傳遞給子模塊的數(shù)據(jù)骇扇,我們可以在子模塊中通過this.props來訪問得到摔竿。

dangerouslySetInnerHTML

如果我們想要直接插入html進(jìn)入文檔中(這一點(diǎn)需要自己來保證XSS的問題),我們可以使用dangerouslySetInnerHTML這個屬性來添加少孝。

遍歷輸出

var commentListNodes = this.props.comList.map(function(comment){
    return (
      <Comment author={comment.author} key={comment.id}>
          {comment.text}
        </Comment>
    );
});

我們可以通過map方法來得到數(shù)組继低,然后使用的時候直接{commentListNodes}就能輸出了。

state

目前稍走,依賴于props袁翁,所有的組件都是被刷新了一次,props是不變的婿脸,這個被父組件傳過來的且被父組件擁有粱胜。所以出現(xiàn)了state這個屬性,我們使用這個可變的私有的值來改變狀態(tài)狐树。我們可以使用setState()來rerender這個組件焙压。getInitialState這個方法會在初始化的時候執(zhí)行一次來初始化組件的初始狀態(tài)。

componentDidMount

這個方法會在組件第一次初始化之后被調(diào)用

控制組件的輸入

這里推薦的也是在this.state里面存這個value抑钟,在input的onChange時調(diào)用修改this.setState來改變涯曲。包括submit方法的話就是監(jiān)聽onSubmit。我們可以先調(diào)用e.preventDefault()來阻止默認(rèn)行為在塔。

從子組件傳數(shù)據(jù)給父組件

我們可以在調(diào)用子組件的時候幻件,將callback綁在props上,然后調(diào)用子組件的props上面的方法來調(diào)用父組件相應(yīng)的方法蛔溃。

我們在寫一些回調(diào)的時候要綁定好this

  $.ajax({
      url: this.props.url,
      dataType: 'json',
      type: 'POST',
      data: comment,
      success: function(data) {
        this.setState({data: data});
      }.bind(this)
  });
  //就像這樣綁定好this

Tip

這里還給了一個小建議绰沥,我們在添加了某一項(xiàng)之后篱蝇,可以直接加進(jìn)list,如果ajax失敗了再重置回去

Thinking in React

創(chuàng)建react的步驟

我們分解成react要尊崇單一職責(zé)原則揪利,盡量把交互與展示分開态兴,展示也根據(jù)種類分細(xì)點(diǎn)

然后我們先不考慮交互,不考慮傳輸?shù)臄?shù)據(jù)疟位,先創(chuàng)建一個靜態(tài)的項(xiàng)目出來

react是單項(xiàng)綁定的

然后我們要計算出最小的state我們需要什么瞻润,通過父組件傳的,不變的甜刻,能夠通過其他state計算得到的都不應(yīng)該是state

我們需要得出哪一塊需要數(shù)據(jù)绍撞,如果我們實(shí)在沒法區(qū)分的時候,我們可以專門在其上用一個組件來專門管理state

社區(qū)資源

這個就先不看了

Guides

why react

React就像是MVC的view層得院,react主要解決的是大項(xiàng)目數(shù)據(jù)不斷變化的場景傻铣。我們只需要修改數(shù)據(jù),react會幫我們進(jìn)行所有的UI更新祥绞。

他只更新被改變的部分非洲。

Displaying Data

他的組件是很封閉的,所以更容易重用蜕径,更容易測試以及分離相關(guān)两踏。

Components更像是方法,接受props和state來生成HTML兜喻。(react模塊只能生成一個簡單的根節(jié)點(diǎn)梦染,如果想要返回大量的節(jié)點(diǎn)的話,得用一個根節(jié)點(diǎn)包裹起來)

React允許我們用js對象的形式來創(chuàng)建HTML朴皆,如`React.createElement('a',{href:''},'Hello!')帕识。為了簡便,我們還可以使用createFactory的形式來創(chuàng)建遂铡。但是使用比較少肮疗,還是JSX比較方便。

JSX時間上只是一種語法扒接,并不是使用React的必需品伪货,不用的話,就得像上面一樣使用create的形式慢慢創(chuàng)建珠增。

Jsx in Depth

我們在JSX里面使用HTML tag的時候,用小寫的形式砍艾。如果是HTML屬性的話蒂教,使用駝峰的寫法。并且因?yàn)閏lass和for都作為XML的本身的屬性名脆荷,所以我們分別用className和htmlFor來代替凝垛。

我們在版本0.11以上可以使用namespaced components懊悯,就是在某個組件之下進(jìn)行申明。

當(dāng)我們在屬性里想要使用js的表達(dá)式的時候梦皮,用一個大括號包裹起來炭分,替代雙引號。

boolean attribute剑肯,如disable捧毛,readonly,checked让网,required直接省略屬性值和{true}一樣呀忧,如果不寫和值為{false}效果一樣。

js表達(dá)式也可以用來申明生成哪個子節(jié)點(diǎn)溃睹,比如{ifShow ? <Nav/> : <Login/>}而账。

注釋的話使用這種形式是可以的{/* */}。

Jsx 延展屬性

我們可以使用延展屬性因篇,來講一個對象所有的屬性復(fù)制到另一個對象上泞辐。我們可以多次使用,或者和普通的屬性一起用竞滓,不過得注意順序咐吼,后面的會覆蓋前面的。這里是React直接支持虽界。

var props = {foo:"check"}
var component = <Component {...props} foo='name'/>
console.log(component.props.foo);
//name

延展屬性在ES6的效果主要是將數(shù)組類型的一個個推出來汽烦,就像是apply方法一樣,支持情況當(dāng)然不好啦莉御,但是Bebal可以轉(zhuǎn)撇吞。

JSX 一些陷阱

如果想插入·這種符號的話,我們可以直接插入礁叔,但是如果想插入動態(tài)的話牍颈,我們就會以這樣的形式包裝起來{'·'},然后就沒法顯示了

我們可以直接以UTF-8的形式寫個點(diǎn)琅关,或者我們可以寫unicode的編碼\u00b7煮岁,或者我們用個span包起來,例如{['First ', <span>·</span>, ' Second']}涣易,或者我們可以直接dangerouslySetInnerHTML={{__html: 'First · Second'}}這樣來強(qiáng)行插入原始的HTML画机。

原生的HTML的自定義屬性必須以data開頭,自定義的節(jié)點(diǎn)的屬性可以是任意的新症,aria-hidden這種aria-開頭的屬性是可以正常render的步氏。

交互以及動態(tài)UI

他自動把方法綁定在模塊上,是使用的事件代理徒爹,完全綁在了根元素上荚醒。

模塊就是狀態(tài)機(jī)芋类。

通過setState來將data merge進(jìn)入this.state中,這里的merge只有一層界阁,如果想深層次的merge侯繁,使用那個immutability helpers

所以我們應(yīng)該有許多stateless的模塊來負(fù)責(zé)渲染,然后在其上有一個stateful的模塊來將state通過props傳給這個模塊泡躯。

計算過的數(shù)據(jù)贮竟,react模塊以及與props里面重復(fù)的數(shù)據(jù)都不應(yīng)該在State里面出現(xiàn)。

Multiple Components

動機(jī)主要是將關(guān)注點(diǎn)分離精续。

組件自己沒法修改props坝锰,這樣可以保證組件是始終如一的。Owner負(fù)責(zé)修改以及傳遞狀態(tài)重付。

注意Owner和Parent是不一樣的顷级,<Parent><Child/></Parent>這個是parent,而owner是React.createClass确垫。我們可以在Parent里面使用this.props.children來操作弓颈。

我們最好不要用hide來隱藏,我們應(yīng)該直接讓他們消失删掀,對于list生成的我們需要給每一個一個唯一的key來保證他們正常且不別破壞翔冀。

數(shù)據(jù)流是單向綁定的。

JS執(zhí)行的速度是非撑幔快的纤子,所以基本上沒有性能瓶頸。主要的瓶頸是DOM的渲染款票,而這點(diǎn)React幫我們通過批處理以及臟檢測來優(yōu)化過了控硼。

當(dāng)我們真的感覺到性能問題的時候,我們可以重寫shouldComponentUpdate來讓他返回false就可以了艾少,但是其實(shí)不是很需要卡乾。

Reusable Components

設(shè)計接口的時候,將那些簡單設(shè)計的元素分解為可重復(fù)使用的缚够,良好設(shè)計的接口幔妨。下次就可以復(fù)用了。

為了保證我們的組件被正確的使用谍椅,我們可以通過設(shè)置propTypes來限制用戶傳入的數(shù)據(jù)误堡,但是這個東西只有在development模式才會有效。

default prop values

我們可以在用戶沒有傳的時候設(shè)置一個默認(rèn)值雏吭,調(diào)用getDefaultProps就可以設(shè)置默認(rèn)值了锁施,如果用戶設(shè)置過的話,就會被忽略

Transferring Props: A Shortcut

有的時候我們想要從父元素傳遞props給子元素思恐,我們可以直接使用spread syntax來簡寫沾谜,比如直接{...this.props}這樣。

Mixins

當(dāng)不同的組件擁有相同的功能的時候胀莹,我們可以使用mixins基跑,這個就是將組件的功能進(jìn)行抽離的一個方法,還蠻有意思的描焰。使用的時候加個mixins: [SetIntervalMixin]就可以了媳否。

一個很重要的有點(diǎn)在于,如果有多個Mixin在同一個生命周期的方法執(zhí)行荆秦,那么他們都會被執(zhí)行篱竭,并且會嚴(yán)格按照申明的順序執(zhí)行。

ES6 Classes

我們也可以使用es6的class語法來聲明組件步绸,唯一不同的是沒有g(shù)etInitialState這個方法掺逼,我們只能在constructor里面手動初始化state。

而且方法如果想要在render里面以this來調(diào)用的話瓤介,必須在constructor里面bind一下this吕喘。

還有propTypes和defaultProps得在外面申明,而不是寫在里面刑桑。下面的例子

export class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
    this.tick = this.tick.bind(this);
  }
  tick() {
    this.setState({count: this.state.count + 1});
  }
  render() {
    return (
      <div onClick={this.tick}>
        Clicks: {this.state.count}
      </div>
    );
  }
}
Counter.propTypes = { initialCount: React.PropTypes.number };
Counter.defaultProps = { initialCount: 0 };

關(guān)于this的綁定氯质,我們可以在調(diào)用的時候綁定,也可以使用箭頭祠斧,不過最好像上面一樣在constructor里面綁定闻察,這樣只綁定了一次。

<div onClick={this.tick.bind(this)}>//bad
<div onClick={()=> this.tick()}>//bad

ES6的語法的話沒有Mixins的支持琢锋。

Stateless Functions

如果組件只是一個簡單的js function的話辕漂,我們可以使用這種語法

function HelloMessage(props) {
  return <div>Hello {props.name}</div>;
}
//或者直接使用下面的箭頭語法
const HelloMessage = (props) => <div>Hello {props.name}</div>;

這種比較適合沒有l(wèi)ifestyle方法的,不存有內(nèi)部狀態(tài)吩蔑,我們?nèi)匀豢梢栽O(shè)置propTypes和defaultProps钮热。就像ES6的設(shè)置一樣。我們的項(xiàng)目應(yīng)該較多的是stateless的模塊烛芬。

Transferring Props

我們想要傳遞給子模塊的時候加上某個屬性的話隧期,可以直接使用spread語法。<Component {...this.props} more="values" />

如果沒有用jsx的話赘娄,我們可以使用ES6的語法Object.assign和underscore的extends仆潮。

如果我們在某一層組件的時候截斷某個屬性,然后將其他屬性傳下去的話遣臼,可以使用other的語法性置。

function FancyCheckbox(props) {
  var { checked, ...other } = props;
  var fancyClass = checked ? 'FancyChecked' : 'FancyUnchecked';
  // `other` contains { onClick: console.log } but not the checked property
  return (
    <div {...other} className={fancyClass} />
  );
}
ReactDOM.render(
  <FancyCheckbox checked={true} onClick={console.log.bind(console)}>
    Hello world!
  </FancyCheckbox>,
  document.getElementById('example')
);

這樣子的話,other就會只包含除了checked以外的屬性了揍堰,主要是因?yàn)?code>checked這個屬性在html的結(jié)構(gòu)有特殊的意義鹏浅,而在自定義的組件沒有這個效果嗅义。

我們也可以使用rest properties,var { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };隐砸,不過在webpack里面得加上transform-object-rest-spread這個plugin之碗。

不用jsx的話,我們可以使用underscore的omit來刪屬性和extends來擴(kuò)展季希。

Forms

與HTML對應(yīng)的褪那,value是被input和textarea支持的。

checked是被input的checkbox和radio支持的式塌。

selected是被options支持的博敬。

注意HTML中,textarea的值是被設(shè)置在兩個標(biāo)簽之間峰尝,REACT是在value屬性上偏窝。

onChange事件會在input和textarea的值發(fā)生改變的時候觸發(fā),還有input的checked改變武学,以及option的selected改變的時候囚枪。

如果我們在render方法里面寫死了input的value,那么我們輸入會被忽視的劳淆,只有value改為state的可變的值才行链沼。

我們可以使用defaultValue給input,textarea沛鸵,select(這個支持multiple)括勺,然后radio和checkbox的值是defaultChecked,注意這個值只能夠在初始化的時候曲掰。

Working with the browser

react快的原因是因?yàn)樗恢苯优cDOM交流疾捍,render方法返回的對DOM的描述,react會計算最快的更新頁面的方法栏妖。

事件系統(tǒng)完美處理乱豆。

當(dāng)我們想要調(diào)用html本身的命令的時候或者接觸真實(shí)的DOM樹,我們可以使用refs來控制吊趾。

Component Lifecycle

模塊有3個主要的階段:

  • Mounting:組件準(zhǔn)備插入DOM中
  • Updating:組件更新
  • Unmounting:組件從DOM中刪除

Mounting提供了getInitialState()和componentWillMount()和componentDidMount()宛裕。

Updating提供了componentWillReceiveProps(這個方法的價值在于組件接收到新的props的時候,我們可以比較新老的props论泛,然后setState揩尸。這個方法在初次mount的時候并不會被觸發(fā),因?yàn)檫@個時候沒有老的props)屁奏,shouldComponentUpdate岩榆,componentWillUpdate(組件即將執(zhí)行更新之前,我們無法執(zhí)行setState方法),componentDidUpdate(更新發(fā)生之后會立即觸發(fā))勇边。

Unmounting提供了componentWillUnmount()在組件被移除之前觸發(fā)犹撒。

Mounted好了的復(fù)合組件也提供了component.forceUpdate()來強(qiáng)行重新刷一次。

react支持IE9以及以上粒褒,但是我們可以引入es5-shim和es5-sham來讓老版的支持油航,這其實(shí)取決于我們自己。

Refs to Components

構(gòu)建組件完了怀浆,你可能想要在render的component實(shí)例上調(diào)用方法。大多數(shù)情況下應(yīng)該是用不到的怕享,因?yàn)檎5臄?shù)據(jù)流應(yīng)該是父組件傳props給子組件的执赡。

jsx并不返回一個component的實(shí)例,他只是返回一個ReactElement(這只是一個告訴React這個組件應(yīng)該是什么樣子的輕量的)函筋。

我們想要調(diào)用某個組價實(shí)例的方法沙合,只能在最上層的component使用(就是ReactDom.render生成的東西)。在組件的內(nèi)部跌帐,我們應(yīng)該自己處理他們之間的狀態(tài)首懈,或者使用另一種方法來得到ref(字符串屬性或者回調(diào)方法屬性)。

The ref Callback Attribute

ref屬性我們可以直接寫成一個回調(diào)方法谨敛。這個方法會在組件結(jié)束mount之后立即被觸發(fā)究履,參數(shù)是引用的組件。我們可以直接使用這個組件或著把他存了等到以后使用脸狸。

這個方法會在componentDidMount之前觸發(fā)最仑。

render: function() {
    return (
      <TextInput
        ref={function(input) {
          if (input != null) {
            input.focus();
          }
        }} />
    );
  },
render: function() {
  return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
  this._input.focus();
},

當(dāng)我們將refs添加給div的時候,我們得到的是DOM元素炊甲,如果給自定義的組件綁定泥彤,我們得到的是react的實(shí)例。如果是我們自定義的組件卿啡,我們可以調(diào)用任何在他的class里面定義的方法吟吝。

當(dāng)組件unmounted或者ref改變的時候,老的ref都會以null來被調(diào)用颈娜,所以說當(dāng)ref update的時候剑逃,在被組件實(shí)例為參數(shù)之前,會立即調(diào)用一次null為參數(shù)的官辽。(這點(diǎn)需要注意的)

The ref String Attribute

我們也可以簡單的加一個string的ref屬性炕贵,然后我們在其他的事件處理里面就可以this.refs.xx來調(diào)用了。

Tooling Integration

作者希望react成為環(huán)境無關(guān)的野崇,推薦了一些工具來讓我們更好地使用各種種類的語言称开。

Language Tooling

我們寫成JSX的文件的話,我們要用babel先轉(zhuǎn)化為純粹的react的語法。Flow和TypeScrip也都支持JSX了鳖轰。

Package Management

我們可以在commonjs系統(tǒng)browserify或者webpack里面直接npm的形式來引入react和react-dom清酥。

Server-side Environments

react并不是真的依賴于DOM,所以可以后端來執(zhí)行蕴侣,將HTML吐在頁面上焰轻,如果是nodejs的話,是可以ReactDOMServer.rendertoString的昆雀。

如果是java的話辱志,可以依賴于Nashorn這個JS的執(zhí)行器來轉(zhuǎn)化JSX。

Add-ons

這是一些react提供的功能插件狞膘,這些相對于核心來說變化的會比較多一些揩懒。以下的是一些實(shí)驗(yàn)性質(zhì)的:

  • TransitionGroup and CSSTransitionGroup:解決那些不容易實(shí)現(xiàn)的動畫,例如在組件移除的時候的動畫挽封。
  • LinkedStateMixin:這個是將form的屬性與state綁在一起的插件已球,如果form比較大的話,這個還是很關(guān)鍵的辅愿。
  • ...還有很多下面會慢慢介紹的

Animation

react提供了ReactTransitionGroup這種比較級別比較低的api來讓我們使用智亮,還提供了ReactCSSTransitionGroup來讓我們更好的使用css實(shí)現(xiàn)的動畫。包括進(jìn)入和離開頁面的動畫点待。

當(dāng)我們在list添加的時候阔蛉,我們可以使用ReactCSSTransitionGroup的enter和leave來實(shí)現(xiàn)。他會根據(jù)key的區(qū)別來判斷是不是新添加的癞埠,然后就會像我們通常觸發(fā)動畫一樣來toggle css的class馍忽。

組件初始化渲染的話,我們可以使用transitionAppear這個來添加動畫燕差。注意初始化渲染的時候遭笋,所有的children是appear,然后后來添加進(jìn)的就是enter了徒探。

使用ReactCSSTransitionGroup我們得不到動畫結(jié)束的通知瓦呼,也無法為了動畫加上更復(fù)雜的邏輯,想定制化测暗,就得使用ReactTransitionGroup了央串。

如果想禁掉某些動畫,我們可以設(shè)置為false碗啄。

ReactTransitionGroup

這個玩意功能強(qiáng)大的多质和,他提供了在動畫生命周期里能夠執(zhí)行的方法。使用到的時候再思考吧稚字。

Two-Way Binding Helpers

ReactLink是個方便的在react里面實(shí)現(xiàn)雙向綁定的工具饲宿。但是這個在新版本被廢棄了厦酬,還是推薦通過onchange來設(shè)置值。

雙向綁定實(shí)際上強(qiáng)制性的要求了DOM完全等于react的state瘫想,這點(diǎn)雖然其實(shí)有很廣的范圍仗阅,React提供了ReactLink來幫我們簡單的封裝了setState和onChange方法。他并沒有實(shí)際上改變react的單項(xiàng)數(shù)據(jù)流国夜。最好別用~

Test Utilities

React提供了非常棒的測試語法减噪。配合Jest這層依賴于Jsdom的,我們可以寫腳本測試整個的渲染以及事件邏輯车吹。

我們可以直接寫腳本模擬點(diǎn)擊筹裕,模擬輸入,模擬鍵盤事件窄驹。

類似于ReactTestUtils.Simulate.click(node);

我們可以renderIntoDocument然后進(jìn)行各種類型判斷以及事件觸發(fā)檢驗(yàn)朝卒。

不依賴于Jest蓄诽,不依賴于DOM,我們也可以render組件隆夯,使用如下的Shallow rendering骚秦。

Shallow rendering

使用這個組件我們可以脫離DOM來渲染組件,但是這只是一層渲染澳迫,子組件不會被渲染。我們只能夠檢查output的信息。功能其實(shí)還是很少的扯罐。refs也不支持,function也不支持烦衣。

Cloning ReactElements

cloneWithProps這個組件被廢棄了歹河,現(xiàn)在只建議使用React.cloneElement。就是在想要復(fù)制一個element花吟。并且在他的原props上進(jìn)行一些修改秸歧。

Keyed Fragments

有時我們需要將兩塊元素?fù)Q位置,按照我們一般的寫法衅澈,我們會單純的給他們換位置键菱,于是這些元素就會經(jīng)歷unmount和remount兩個步驟。這是因?yàn)槲覀儧]有給他們每個模塊一個單獨(dú)的key今布。我們?nèi)绻褂胏reateFragment就可以讓元素不執(zhí)行unmount了经备。

Immutability Helpers

(這個add-on的好處在于我們可以改變外面的殼子為一個新對象,然后對象里面的屬性會自動重用老的部默。等于就是一個淺復(fù)制侵蒙,然后我們就可以在子組件里面使用shandowCompare來比較。)

我們有時想要改變對象的里面的某個屬性傅蹂,然后其他的不想改變纷闺。例如下圖算凿。

var old = {a:1,b:{c:1,d:{e:12}},r:{f:1}};
var newData = Update(old,{b:{c:{$set:2}}});
console.log(old === newData);//false
console.log(old.b === newData.b);//false
console.log(old.b.d === newData.b.d);//true
console.log(old.r === newData.r);//true

PureRenderMixin

就是如果你的組件是pure的,就是說給不變的props和state急但,render同樣的結(jié)果澎媒。可以直接mixins這個插件波桩。其實(shí)就是shouldComponentUpdate里面返回了一個shandowCompare而已戒努。

Performance Tools

(這個是個非常好的提供性能的工具,可以讓我們查看一定的操作之后镐躲,我們頁面組件重新渲染的次數(shù)储玫,可以讓我們進(jìn)行組件的優(yōu)化,使用可以參照本項(xiàng)目DEMO里的那個debug-panel萤皂,這個是勐喆開發(fā)的一個查看工具撒穷,內(nèi)部調(diào)用了start,stop裆熙,printWasted端礼,getLastMeasurement等方法)

perf.png

這里有個Perf.printWasted,這個是react內(nèi)部做的深層次比對入录,發(fā)現(xiàn)沒有變化蛤奥,于是DOM沒有觸及,這一塊的浪費(fèi)我們可以在shouldComponentUpdate里面通過return false來進(jìn)行阻止僚稿。

Shandow Compare

這個是個最淺層的比較凡桥,會對對象的每個屬性進(jìn)行嚴(yán)格等于的比較,然后都相等就返回false蚀同,有改變的話就返回true缅刽。代表著需要更新。

Advanced Performance

人們使用react的原因在于他們希望網(wǎng)站是快速的蠢络,并且是響應(yīng)的衰猛。每次state的改變導(dǎo)致重新render整個子樹讓人們想知道這樣是否影響了性能,React使用了一些聰明的技術(shù)來減少需要更新UI時的DOM操作刹孔。

首先線上環(huán)境要使用壓縮過的production build

Avoiding reconciling the DOM

React使用的是虛擬DOM腕侄。這種平行的關(guān)系阻止了React直接創(chuàng)建和接觸真實(shí)的DOM。每次React的props和state改變的話芦疏。React都會生成一個新的虛擬DOM來和老的比較冕杠,如果不相等的話,React才會盡可能小的改變虛擬DOM酸茴。

在這之上分预,React提供了一個組件的生命周期的方法,shouldComponentUpdate薪捍,這個方法來阻止虛擬DOM比較以及可能的最終的DOM的更改笼痹。讓開發(fā)者來縮短整個過程配喳。這個值默認(rèn)返回true,默認(rèn)執(zhí)行比較以及更新凳干。

我們很多時候的比較其實(shí)只是引用地址的比較(shandow compare)晴裹,這個基本上都是true的,因?yàn)槲覀兪窃谕粋€對象上修改的救赐。

我們可以使用Immutable這個東西來創(chuàng)建不同的對象涧团,或者使用Object.assign來做這件事情。

Context

React讓我們很容易的跟蹤數(shù)據(jù)流的走向经磅,因?yàn)樗际茄刂M件樹的結(jié)構(gòu)一層層props傳遞下去的泌绣。但是有時我們不想要一層層的傳遞下去,我們可以使用Context這個東西预厌。(這個是個實(shí)驗(yàn)性質(zhì)的屬性阿迈,將來可能會修改)

我們在父組件中(context的提供者)申明好childContextTypes和getChildContext。然后我們在子組件里面申明好contextTypes就可以拿到相關(guān)的數(shù)據(jù)了轧叽。如果不申明苗沧,那this.context就會是一個空對象。

還是建議不要使用這個東西炭晒,用了的話待逞,生命周期函數(shù)基本都會變化,會新加一個參數(shù)nextContext腰埂。會讓組件無法被重用飒焦。

REFERENCE

這一塊的太多了蜈膨,先不看好了....

FLUX

這個也先不管....

TIPS

這里主要就是一些細(xì)節(jié)的點(diǎn)了

Inline Styles

在React里面屿笼,我們想要使用行內(nèi)式樣的話,必須以對象的形式申明翁巍,而且必須是駝峰式驴一,行內(nèi)樣式本來就不推薦,這里也就了解一下感覺就夠了灶壶。

If-Else in JSX

JSX里面我們沒法使用if else肝断,因?yàn)镴SX只是一個來處理函數(shù)調(diào)用以及對象構(gòu)建語法糖,最多只能處理3目運(yùn)算符驰凛。如果想要使用if else也可以胸懈,只要在JSX外面使用就好了∏∠欤或者寫成一個自執(zhí)行的匿名函數(shù)調(diào)用趣钱。

Self-Closing Tag

就是說react component都可以自封閉,包括div什么的胚宦,因?yàn)樗麄儽旧硪簿褪莚eact的component首有。

Maximum Number of JSX Root Nodes

目前燕垃,render里面只允許返回一個root nodes。如果我們想要返回多個的話井联,我們只能用一個將他們包裝起立卜壕。

Shorthand for Specifying Pixel Values in style props

就是說在行內(nèi)的style屬性中,當(dāng)我們寫一些長度屬性的時候烙常,React會幫我們自動加上px這個單位轴捎,這里也介紹了一些不會加的,不過行內(nèi)的用處不大军掂,這里了解下就好了轮蜕。

Type of the Children props

我們在componentDidMount中可以通過this.props.children來訪問到組件內(nèi)部包裹的組件。如果包裹的數(shù)量大于1的話蝗锥,這個值就是一個數(shù)組跃洛,如果是1的話,這個值就是一個單個的值终议,并沒有用數(shù)組包起來汇竭,所以提供了React.Children utilities來訪問。

Value of null for Controlled Input

我們正常給input設(shè)置了value之后我們是無法修改他的值的穴张,但是我們把input的value設(shè)置為null或者undefined之后细燎,input就變的可以編輯狀態(tài)了(但是我這種賦值并沒有價值,這只是一種錯誤的狀態(tài))

componentWillReceiveProps Not Triggered After Mounting

這個方法并不會在初次mount的時候執(zhí)行皂甘,因?yàn)樗淖饔迷谟诒容^老的props和新的props玻驻,如果老的沒有的話,就不會觸發(fā)偿枕。

Props in getInitialState Is an Anti-Pattern

我們在getInitialState里面使用props來設(shè)置state需要注意一下璧瞬,因?yàn)間etInitialState這個方法只會在初始化的時候被執(zhí)行一次。

DOM Event Listeners in a Component

就是說我們最好在componentDidMount這個方法執(zhí)行之后進(jìn)行DOM上事件的綁定渐夸,因?yàn)檫@個時候渲染已經(jīng)完成了嗤锉。

Load Initial Data via AJAX

讓我們在componentDidMount里面拉取ajax數(shù)據(jù),然后在UnMount方法里面abort掉這個request墓塌。

False in JSX

false在jsx里面的渲染結(jié)果會有些不同瘟忱,比如false作為id或者value等等的值就會被解析為字符串“false”,如果在div中間使用{false}苫幢,就會得到一個空白的div访诱。

Communicate Between Components

想要父組件與子組件交流,很簡單的傳輸props就可以了韩肝,想要子組件與父組件交流触菜,只需要func.bind(this,i,props)這樣綁定一下就好了。

如果是沒有父子關(guān)系的組件之間的交流伞梯,我們可以設(shè)置自己的時間系統(tǒng)玫氢,在componentDidMount里面訂閱帚屉,然后在willUnmount里面取消訂閱。

或者按照flux來解決漾峡。

Expose Component Functions

將方法暴露給父組件來調(diào)用攻旦,其實(shí)就是父組件創(chuàng)建的時候給個ref值,然后在父組件里面使用this.refs.item1.func()就可以調(diào)用子組件的方法了生逸。

this.props.children undefined

children這個屬性并不指的是自己的render方法里面的子牢屋,而是調(diào)用這個組件里面?zhèn)魅氲淖印W⒁庹{(diào)用我們自己包裝的組件時槽袄,在里面包的div并不會渲染烙无,除非我們自己在組件里面的渲染中調(diào)用{this.props.children}來手動渲染。

Use React with Other Libraries

我們完全可以不整個的使用react遍尺,我們可以在shouldComponentUpdate里面手動return false截酷。我們可以在DidMount里面進(jìn)行一些事件的綁定。在DidUpdate進(jìn)行一些處理乾戏。但是這是件tricky的事迂苛。

Dangerously Set innerHTML

一般React會幫我們編碼一下吐到頁面上,基本不會有XSS攻擊鼓择,但是有時我們想要自己生成html吐到頁面上三幻,react提供了dangerouslySetInnerHTML這個function,傳入的數(shù)據(jù)是{__html:'haha'}呐能,注意這個就是有風(fēng)險的念搬,而且我們基本完全可以避免,除非一些非常特別的case摆出。

接下來會細(xì)讀一下react的reference和flux朗徊。

文章可以直接訪問我的前端網(wǎng)站來查看

平時的日常整理也會記錄上去。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末懊蒸,一起剝皮案震驚了整個濱河市荣倾,隨后出現(xiàn)的幾起案子悯搔,更是在濱河造成了極大的恐慌骑丸,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妒貌,死亡現(xiàn)場離奇詭異通危,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)灌曙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門菊碟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人在刺,你說我怎么就攤上這事逆害⊥纺鳎” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵魄幕,是天一觀的道長相艇。 經(jīng)常有香客問我,道長纯陨,這世上最難降的妖魔是什么坛芽? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮翼抠,結(jié)果婚禮上咙轩,老公的妹妹穿的比我還像新娘。我一直安慰自己阴颖,他們只是感情好活喊,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著量愧,像睡著了一般胧弛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侠畔,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天结缚,我揣著相機(jī)與錄音,去河邊找鬼软棺。 笑死红竭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的喘落。 我是一名探鬼主播茵宪,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瘦棋!你這毒婦竟也來了稀火?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤赌朋,失蹤者是張志新(化名)和其女友劉穎凰狞,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沛慢,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赡若,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了团甲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逾冬。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出身腻,到底是詐尸還是另有隱情产还,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布嘀趟,位于F島的核電站雕沉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏去件。R本人自食惡果不足惜坡椒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望尤溜。 院中可真熱鬧倔叼,春花似錦、人聲如沸宫莱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽授霸。三九已至巡验,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碘耳,已是汗流浹背显设。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辛辨,地道東北人捕捂。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像斗搞,于是被迫代替她去往敵國和親指攒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

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

  • 深入JSX date:20170412筆記原文其實(shí)JSX是React.createElement(componen...
    gaoer1938閱讀 8,048評論 2 35
  • GUIDS 第一章 為什么使用React僻焚? React 一個提供了用戶接口的JavaScript庫允悦。 誕生于Fac...
    jplyue閱讀 3,519評論 1 11
  • 本筆記基于React官方文檔,當(dāng)前React版本號為15.4.0虑啤。 1. 安裝 1.1 嘗試 開始之前可以先去co...
    Awey閱讀 7,649評論 14 128
  • 原教程內(nèi)容詳見精益 React 學(xué)習(xí)指南隙弛,這只是我在學(xué)習(xí)過程中的一些閱讀筆記,個人覺得該教程講解深入淺出咐旧,比目前大...
    leonaxiong閱讀 2,810評論 1 18
  • 以下內(nèi)容是我在學(xué)習(xí)和研究React時驶鹉,對React的特性绩蜻、重點(diǎn)和注意事項(xiàng)的提取铣墨、精練和總結(jié),可以做為React特性...
    科研者閱讀 8,219評論 2 21