react

react

Why React?

React is a JavaScript library for creating user interfaces by Facebook and Instagram. Many people choose to think of React as the V in MVC.We built React to solve one problem: building large applications with data that changes over time.

  • Simple

  • Declarative

  • Build Composable Components

  • In fact, with React the only thing you do is build components.

react的概念

組件

React 應(yīng)用都是構(gòu)建在組件之上骡苞,各個(gè)組件維護(hù)自己的狀態(tài)和 UI为肮,當(dāng)狀態(tài)變更扣唱,自動(dòng)重新渲染整個(gè)組件

import React, { Component } from 'react';
import { render } from 'react-dom';

class HelloMessage extends Component {
  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

propsstate

props 就是組件的屬性,由外部通過 JSX 屬性傳入設(shè)置

state 是組件的當(dāng)前狀態(tài),可以把組件簡單看成一個(gè)“狀態(tài)機(jī)”车摄,根據(jù)狀態(tài) state 呈現(xiàn)不同的 UI 展示祟牲。一旦狀態(tài)(數(shù)據(jù))更改,組件就會(huì)自動(dòng)調(diào)用 render 重新渲染 UI榛搔,這個(gè)更改的動(dòng)作會(huì)通過this.setState 方法來觸發(fā)诺凡。原則:讓組件盡可能地少狀態(tài)。

組件就是通過這兩個(gè)屬性的值在 render 方法里面生成這個(gè)組件對應(yīng)的 HTML 結(jié)構(gòu)

相關(guān)函數(shù)

1践惑、裝載組件觸發(fā)

componentWillMount

只會(huì)在裝載之前調(diào)用一次腹泌,在 render 之前調(diào)用,你可以在這個(gè)方法里面調(diào)用 setState 改變狀態(tài)尔觉,并且不會(huì)導(dǎo)致額外調(diào)用一次 render

componentDidMount

只會(huì)在裝載完成之后調(diào)用一次凉袱,在 render 之后調(diào)用,從這里開始可以通過ReactDOM.findDOMNode(this)獲取到組件的 DOM 節(jié)點(diǎn)

2侦铜、更新組件觸發(fā)

componentWillReceiveProps

shouldComponentUpdate

componentWillUpdate

componentDidUpdate

3专甩、卸載組件觸發(fā)

componentWillUnmount

組合組件

使用組件的目的就是通過構(gòu)建模塊化的組件,相互組合組件最后組裝成一個(gè)復(fù)雜的應(yīng)用钉稍。在 React 組件中要包含其他組件作為子組件涤躲,只需要把組件當(dāng)作一個(gè) DOM 元素引入就可以,通過 props 傳遞值贡未。

JSX

將 HTML 直接嵌入了 JS 代碼里面

<a >Hello!</a>

React.createElement('a', {href: 'http://facebook.github.io/react/'}, 'Hello!')

通過 React.createElement 來構(gòu)造組件的 DOM 樹种樱。第一個(gè)參數(shù)是標(biāo)簽名,第二個(gè)參數(shù)是屬性對象羞秤,第三個(gè)參數(shù)是子元素缸托。

利用 JSX 編寫 DOM 結(jié)構(gòu),可以用原生的 HTML 標(biāo)簽瘾蛋,也可以直接像普通標(biāo)簽一樣引用 React 組件俐镐。這兩者約定通過大小寫來區(qū)分,小寫的字符串是 HTML 標(biāo)簽哺哼,大寫開頭的變量是 React 組件佩抹。HTML 里的 class 在 JSX 里要寫成 className叼风,因?yàn)?class 在 JS 里是保留關(guān)鍵字。同理某些屬性比如 for 要寫成 htmlFor棍苹。

Virtual DOM

當(dāng)組件狀態(tài) state 有更改的時(shí)候无宿,React 會(huì)自動(dòng)調(diào)用組件的 render 方法重新渲染整個(gè)組件的 UI。組件 DOM 結(jié)構(gòu)就是映射到這個(gè) Virtual DOM 上枢里,React 在這個(gè) Virtual DOM 上實(shí)現(xiàn)了一個(gè) diff 算法孽鸡,當(dāng)要重新渲染組件的時(shí)候份乒,會(huì)通過 diff 尋找到要變更的 DOM 節(jié)點(diǎn)嘱函,再把這個(gè)修改更新到瀏覽器實(shí)際的 DOM 節(jié)點(diǎn)上板惑,所以實(shí)際上不是真的渲染整個(gè) DOM 樹摘刑。這個(gè) Virtual DOM 是一個(gè)純粹的 JS 數(shù)據(jù)結(jié)構(gòu),所以性能會(huì)比原生 DOM 快很多廓奕。

Data Flow

單向數(shù)據(jù)綁定搀擂,Data Flow 只是一種應(yīng)用架構(gòu)的方式珊膜,比如數(shù)據(jù)如何存放灵奖,如何更改數(shù)據(jù)嚼沿,如何通知數(shù)據(jù)更改等等

兩種實(shí)踐:官方的 Flux 和 優(yōu)雅的 Redux

Redux 的基礎(chǔ)概念

1、整個(gè)應(yīng)用只有唯一一個(gè)可信數(shù)據(jù)源瓷患,也就是只有一個(gè) Store

2骡尽、State 只能通過觸發(fā) Action 來更改

3、State 的更改必須寫成純函數(shù)尉尾,也就是每次更改總是返回一個(gè)新的 State爆阶,在 Redux 里這種函數(shù)稱為 Reducer

Action 很簡單燥透,就是一個(gè)單純的包含 { type, payload } 的對象沙咏,type 是一個(gè)常量用來標(biāo)示動(dòng)作類型,payload 是這個(gè)動(dòng)作攜帶的數(shù)據(jù)班套。

action = {
  type: 'ADD_TODO',
  text: 'Build my first Redux app'
}

Action Creators 是一個(gè)pure function肢藐,它最后會(huì)返回一個(gè) action 對象

function addTodo(text) {
  return {
    type: 'ADD_TODO',
    text
  }
}

Reducer 用來處理 Action 觸發(fā)的對狀態(tài)樹的更改,接受 oldState 和 action 兩個(gè)參數(shù)吱韭,返回一個(gè)新的 newState

state:(oldState, action) => newState

const initialState = {
  a: 'a',
  b: 'b'
};

function someApp(state = initialState, action) {
  switch (action.type) {
    case 'CHANGE_A':
      return { ...state, a: 'Modified a' };
    case 'CHANGE_B':
      return { ...state, b: action.payload };
    default:
      return state
  }
}

Redux 里面只有一個(gè) Store吆豹,對應(yīng)一個(gè) State 狀態(tài),所以整個(gè) State 對象就是由一個(gè) reducer 函數(shù)管理理盆,但是如果所有的狀態(tài)更改邏輯都放在這一個(gè) reducer 里面痘煤,顯然會(huì)變得越來越巨大,越來越難以維護(hù)猿规。得益于純函數(shù)的實(shí)現(xiàn)衷快,我們只需要稍微變通一下,讓狀態(tài)樹上的每個(gè)字段都有一個(gè) reducer 函數(shù)來管理就可以拆分成很小的 reducer 了

Redux 提供了一個(gè)工具函數(shù) combineReducers 來簡化這種 reducer 合并

import { combineReducers } from 'redux';

const someApp = combineReducers({
  a: reducerA,
  b: reducerB
});

將 root reducer 函數(shù)傳遞給 createStore 方法即可

import { createStore } from 'redux';
import someApp from './reducers';
let store = createStore(someApp);

其實(shí)就構(gòu)成了一個(gè)“單向數(shù)據(jù)流”

store.dispatch(action) -> reducer(state, action) -> store.getState() 

Provider作為一個(gè)容器組件姨俩,用來接受 Store蘸拔,并且讓 Store 對子組件可用

import { render } from 'react-dom';
import { Provider } from 'react-redux';
import App from './app';

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

Connect 這個(gè)方法調(diào)用會(huì)返回另一個(gè)函數(shù)师郑,這個(gè)返回的函數(shù)來接受一個(gè)組件類作為參數(shù),最后才返回一個(gè)和 Redux store 關(guān)聯(lián)起來的新組件

connect([mapStateToProps], mapDispatchToProps], [mergeProps], [options])

第一個(gè)可選參數(shù)是一個(gè)函數(shù)调窍,只有指定了這個(gè)參數(shù)宝冕,這個(gè)關(guān)聯(lián)(connected)組件才會(huì)監(jiān)聽 Redux Store 的更新,每次更新都會(huì)調(diào)用mapStateToProps 這個(gè)函數(shù)邓萨,返回一個(gè)字面量對象將會(huì)合并到組件的 props 屬性地梨。

第二個(gè)可選參數(shù)是一個(gè)函數(shù),用來指定如何傳遞dispatch 給組件缔恳,在這個(gè)函數(shù)里面直接 dispatch action creator湿刽,返回一個(gè)字面量對象將會(huì)合并到組件的 props 屬性,這樣關(guān)聯(lián)組件可以直接通過 props 調(diào)用到 action

import React, { Component } from 'react';
import someActionCreator from './actions/someAction';
import * as actionCreators from './actions/otherAction';

function mapStateToProps(state) {
  return {
    propName: state.propName
  };
}

function mapDispatchProps(dispatch) {
  return {
    someAction: (arg) => dispatch(someActionCreator(arg)),
    otherActions: bindActionCreators(actionCreators, dispatch)
  };
}

class App extends Component {
  render() {
    // `mapStateToProps` 和 `mapDispatchProps` 返回的字段都是 `props`
    const { propName, someAction, otherActions } = this.props;
    return (
      <div onClick={someAction.bind(this, 'arg')}>
        {propName}
      </div>
    );
  }
}

export default connect(mapStateToProps, mapDispatchProps)(App);

react的核心

轉(zhuǎn)換Transformation

UIs 只是把數(shù)據(jù)通過映射關(guān)系轉(zhuǎn)換成另一種形式的數(shù)據(jù)

The same input gives the same output

抽象Abstraction

You can't fit a complex UI in a single function though. It is important that UIs can be abstracted into reusable pieces that don't leak their implementation details. Such as calling one function from another.

不可以用單個(gè)函數(shù)就實(shí)現(xiàn)復(fù)雜的UI褐耳,把 UI 抽象成多個(gè)隱藏內(nèi)部細(xì)節(jié)诈闺,又可復(fù)用的函數(shù)。通過在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù)來實(shí)現(xiàn)铃芦。

組合Composition

build abstractions from the containers that compose other abstractions

combine two or more different abstractions into a new one

將兩個(gè)或者多個(gè)不同的抽象組合到新的抽象

react項(xiàng)目構(gòu)建

react技術(shù)棧

  • react

  • webpack

  • react-router

  • redux

  • redux-thunk (this API requires redux@>=3.1.0)

  • es6

react-redux-boilerplate

參考

react入門教程

官網(wǎng)get-started

think-in-react

react設(shè)計(jì)基礎(chǔ)

redux 中文文檔

redux-tutorial

react-router

redux-thunk中間件

react-redux-universal-hot-example

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末雅镊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子刃滓,更是在濱河造成了極大的恐慌仁烹,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咧虎,死亡現(xiàn)場離奇詭異卓缰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)砰诵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門征唬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人茁彭,你說我怎么就攤上這事总寒。” “怎么了理肺?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵摄闸,是天一觀的道長。 經(jīng)常有香客問我妹萨,道長年枕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任乎完,我火速辦了婚禮熏兄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己霍弹,他們只是感情好毫别,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著典格,像睡著了一般岛宦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耍缴,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天砾肺,我揣著相機(jī)與錄音,去河邊找鬼防嗡。 笑死变汪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蚁趁。 我是一名探鬼主播裙盾,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼他嫡!你這毒婦竟也來了番官?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤钢属,失蹤者是張志新(化名)和其女友劉穎徘熔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淆党,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡酷师,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了染乌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片山孔。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖慕匠,靈堂內(nèi)的尸體忽然破棺而出饱须,到底是詐尸還是另有隱情,我是刑警寧澤台谊,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站譬挚,受9級特大地震影響锅铅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜减宣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一盐须、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漆腌,春花似錦贼邓、人聲如沸阶冈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽女坑。三九已至,卻和暖如春统舀,著一層夾襖步出監(jiān)牢的瞬間匆骗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工誉简, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碉就,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓闷串,卻偏偏與公主長得像瓮钥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子烹吵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

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