再探React

早在一年前掂墓,我就很蠢發(fā)表過一篇關(guān)于React的文章,這篇文章主要根據(jù)React官方的介紹初步介紹一下React夸研,并稍微帶過一下Webpack永部,當(dāng)時只是作為一位iOS開發(fā)工程師隨便看看React這個東西,現(xiàn)在博主已經(jīng)勵志從一名懂一點Javascript的iOS程序員轉(zhuǎn)變成一位曾經(jīng)做過iOS的前端開發(fā)人員,在自己做過一些React項目之后信不,想再次介紹一下React這個東西

那么讓我們來回顧一下React的基本用法嘲叔,在某個版本之后React這個庫被分為react和react-dom,react負責(zé)對組件的操作抽活,react-dom負責(zé)將組件渲染到頁面上硫戈,組件的寫法基本為:

var MyComponent = React.createClass({
  render: function() {
    return React.createElement("div", null);
  }
})

使用JSX語法之后

var MyComponent = React.createClass({
  render: function() {
    return (
      <div>
        <!-- add some dom code -->
      </div>
    )
  }
})

使用ES6的語法來寫:

class MyComponent extends React.Component {
  render() {
    return (
      <div>
        <!-- add some dom code -->
      </div>
    )
  }
}

在Babel橫行的當(dāng)今,我是推薦至少要使用JSX的語法來編寫React的下硕,這樣會使得代碼的可讀性更強丁逝,至于ES6就靠個人洗好了,本文還是推薦使用ES6的語法的梭姓,也將使用ES6語法完成大部分代碼的示例

隨便說說生命周期

關(guān)于組件的裝載霜幼,按照順序執(zhí)行下面的方法

constructorcomponentWillMount誉尖,render罪既,componentDidMount

關(guān)于組件的更新,按照順序執(zhí)行下面的方法

componentWillReceiveProps铡恕,shouldComponentUpdate琢感,componentWillUpdaterender探熔,componentDidUpdate

關(guān)于組件卸載的

componentWillUnmount

英語好的看名字就知道是干嘛的了驹针,真的,應(yīng)該不用解釋了

這里稍微提及一下就是在使用ES6的時候诀艰,定義class如下代碼:

  class A extends React.Component {
    custom() {

    }
    render() {
      console.log(this.custom)
      return (
        <div>
          <A customProp="custom"/>
        </div>
      )
    }
  }

此處輸出this.custom的時候會顯示undefined柬甥,因為class的非constructor方法都是prototype,可以在this._proto_中訪問到其垄,如果想要比較友好的使用this.custom暗甥,可以使用auto-bind

React組件核心的兩個屬性分別叫做props和state,這兩個屬性其實就是存儲了一系列數(shù)據(jù)捉捅,props的數(shù)據(jù)主要從組件外部傳入,比如

  class A extends React.Component {
    render() {
      const {customProp} = this.props
      console.log(customProp)
      return (
        <div></div>
      )
    }
  }
  class B extends React.Component {
    render() {
      return (
        <div>
          <A customProp="custom"/>
        </div>
      )
    }
  }

以上就會輸出customProp的值為custom

而state的值則是由組件內(nèi)部控制的虽风,state應(yīng)當(dāng)在constructor的實現(xiàn)中初始化棒口,并在React中調(diào)用setState()組件會做diff并刷新相應(yīng)界面,所以我們能夠確定props對于組件內(nèi)部是靜態(tài)的辜膝,它從外部傳入无牵,由外部控制組件。而state是動態(tài)的厂抖,組件自己控制自己茎毁。

了解了以上的知識,基本的React項目已經(jīng)可以編寫了,當(dāng)然七蜘,只要配置好Webpack谭溉,關(guān)于項目的搭建,之前已經(jīng)有過一篇文章對其進行過翻譯

那么接下來講講一些進階吧

Redux

首先呢橡卤,Redux不是只用于React的扮念。當(dāng)然了React和它很搭,React是一個狀態(tài)維護組件的界面框架碧库,而Redux恰好是一個非常好的能夠維護狀態(tài)的框架柜与。接下來對Redux做一些介紹,Redux只適用于超大型項目嵌灰,輕易別用這個東西弄匕,很累贅。

那么我們從基礎(chǔ)的來看Redux

Action

Action相當(dāng)于指令沽瞭,一般會包含兩種屬性一種是指令類型迁匠,用以區(qū)分指令,另一種是數(shù)據(jù)秕脓,數(shù)據(jù)可以有很多柒瓣,用來處理,當(dāng)然也可以沒有數(shù)據(jù)單純發(fā)一個指令吠架,這都是可選的芙贫,比如以下都是Action:

const OPEN_MOUTH = "OPEN_MOUTH"
const CLOSE_MOUTH = "CLOSE_MOUTH"
const openAction = {
  type: OPEN_MOUTH,
  size: 10,
  time: 5
}
const closeAction = {
  type: CLOSE_MOUTH
}

上面一共有兩個Action,OPEN_MOUTH傍药、CLOSE_MOUTH分別是兩個類型磺平,openAction中的size和time是數(shù)據(jù),closeAction中沒有數(shù)據(jù)

Reducer

Reducer是指令的處理器拐辽,用于分類處理指令拣挪,先上一段代碼:

function myReducer(state, action) {
  if (action.type == OPEN_MOUTH) {
    var newState
    //create a new State for open mouth
    return newState
  } else if (action.type == CLOSE_MOUTH) {
    var newState
    //create a new State for close mouth
    return newState
  }
}

這就是一個Reducer,可以看到俱诸,這個Reducer接受兩個參數(shù)菠劝,一個是原來的state,一個是action睁搭,也就是我們的指令赶诊,通過指令的類型和指令的數(shù)據(jù)來產(chǎn)生新的state就是Reducer的任務(wù)。
這里需要注意园骆,Redux開發(fā)過程中舔痪,在Reducer處理的時候都是期望state純凈的,也就是說锌唾,產(chǎn)生的新的state不會修改老的state锄码,所以請巧用Object.assign()concat()等函數(shù)經(jīng)行操作

Store

可以通過createStore來創(chuàng)建新的store對象,store對象主要的功能是發(fā)送Action滋捶,和監(jiān)控整個發(fā)送處理過程

let store = createStore(myReducer, {})
store.dispatch(openAction)

createStore第一個參數(shù)為Reducer痛悯,第二個參數(shù)是初始的state值
dispatch方法發(fā)送Action

以上就是最簡單的Redux的用法,想了想其實就是很簡單的東西炬太,如果要我們自己來實現(xiàn)的話我們也可以來演示一遍灸蟆,主要就是實現(xiàn)一個store

var createStore = (reducer, init) => {
  var store = {}
  var state = init
  var listeners = []
  store.dispatch = (action) => {
    state = reducer(state, action)
    listeners.forEach((listener) => {
      listener()
    })
  }
  store.getState = () => {
    return state
  }
  store.subscribe = (listener) => {
    let count = listeners.push(listener)
    return () => {
      listeners.slice(count - 1, 1)
    }
  }
  return store
}

以上就是createStore的大致實現(xiàn),很簡單對不對亲族,所以如果只是想用這個Redux的功能炒考,完全可以用這么點代碼代替,不用使用一整個Redux的庫霎迫,殺雞焉用牛刀

那么我們來繼續(xù)介紹一些斋枢,Redux還有哪些Api

combineReducers

隨著項目越來越復(fù)雜,一個Reducer處理的數(shù)據(jù)就會越來越多知给,比如針對如下的數(shù)據(jù):

{
  user: {
    name: 'goodname',
    sex: 1
  },
  setting: {
    showing: false,
    count: 100
  }
}

當(dāng)我們修改user的時候其實setting根本沒有被修改瓤帚,隨著同級的屬性的增多,把所有的屬性的操作都放入一個reducer涩赢,代碼難免會有一些雜亂戈次,那么我們就會把Reducer拆分,讓單個Reducer來處理單個同級屬性筒扒,combineReducers就幫我們很好的處理了這件事情怯邪。比如針對上面的數(shù)據(jù),我們之前會這么做

var reducer = (state, action) => {
  if (action.type == CHANGE_NAME) {

  } else if (action.type == CHANGE_SEX) {

  } else if (action.type == SHOWING) {

  } else if (action.type == HIDE) {

  }
}

同級屬性再增多花墩,都會把所有的操作都放在這個函數(shù)中悬秉,是不好的,有了combineReducers冰蘑,我們可以這么做:

var user = (state, action) => {
  if (action.type == CHANGE_NAME) {

  } else if (action.type == CHANGE_SEX) {

  }
}

var setting = (state, action) => {
  if (action.type == SHOWING) {

  } else if (action.type == HIDE) {

  }
}

module.exports = combineReducers({user, setting})

這么做就會自動分發(fā)屬性名對應(yīng)的Reducer來處理了(當(dāng)然對應(yīng)關(guān)系可以自己設(shè)置)

////未完待續(xù) -> redux-react

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末和泌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子祠肥,更是在濱河造成了極大的恐慌武氓,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仇箱,死亡現(xiàn)場離奇詭異县恕,居然都是意外死亡,警方通過查閱死者的電腦和手機工碾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來百姓,“玉大人渊额,你說我怎么就攤上這事。” “怎么了旬迹?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵火惊,是天一觀的道長。 經(jīng)常有香客問我奔垦,道長屹耐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任椿猎,我火速辦了婚禮惶岭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘犯眠。我一直安慰自己按灶,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布筐咧。 她就那樣靜靜地躺著鸯旁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪量蕊。 梳的紋絲不亂的頭發(fā)上铺罢,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音残炮,去河邊找鬼韭赘。 笑死,一個胖子當(dāng)著我的面吹牛吉殃,可吹牛的內(nèi)容都是我干的辞居。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蛋勺,長吁一口氣:“原來是場噩夢啊……” “哼瓦灶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抱完,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤贼陶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后巧娱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碉怔,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年禁添,在試婚紗的時候發(fā)現(xiàn)自己被綠了撮胧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡老翘,死狀恐怖芹啥,靈堂內(nèi)的尸體忽然破棺而出锻离,到底是詐尸還是另有隱情,我是刑警寧澤墓怀,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布汽纠,位于F島的核電站,受9級特大地震影響傀履,放射性物質(zhì)發(fā)生泄漏虱朵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一钓账、第九天 我趴在偏房一處隱蔽的房頂上張望碴犬。 院中可真熱鬧,春花似錦官扣、人聲如沸翅敌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蚯涮。三九已至,卻和暖如春卖陵,著一層夾襖步出監(jiān)牢的瞬間遭顶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工泪蔫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留棒旗,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓撩荣,卻偏偏與公主長得像铣揉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子餐曹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

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