React實(shí)戰(zhàn)之Redux

Redux、React-Redux 簡介


Redux 是 JavaScript 狀態(tài)容器粤咪,提供可預(yù)測化的狀態(tài)管理隔嫡。
盡管 Redux 來自 React 社區(qū)式塌,但它并不依賴于 React劝术。無論有沒有 JavaScript 框架,比如 React呆奕、Angular养晋、Backbone 或 Cycle.js,都可以使用 Redux梁钾。

React-Redux 是Redux 方提供的 React 綁定绳泉。
提供了一個組件和一個API幫助Redux 和 React 進(jìn)行綁定,一個是 React 組件<Provider/> 姆泻,一個是 connect()零酪。
<Provider/> 接受一個 store 作為props,它是 個 Redux 應(yīng)用的頂層組件拇勃,而 connect() 提供了在 個 React 應(yīng)用的任意組件中獲取 store 中數(shù)據(jù)的功能四苇。

Redux基礎(chǔ)

一、Store

Store 就是保存數(shù)據(jù)的地方方咆,你可以把它看成一個容器月腋。整個應(yīng)用只能有一個 Store。

Redux 提供createStore這個函數(shù)瓣赂,用來生成 Store榆骚。

//react-app/index.js

import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './components/App'
import reducer from './reducers'

//用redux創(chuàng)建的store
//createStore函數(shù)接受另一個函數(shù)作為參數(shù),返回新生成的 Store 對象煌集。
const store = createStore(reducer)
// Provider就是把我們用redux創(chuàng)建的store傳遞到內(nèi)部的其他組件妓肢。
//讓內(nèi)部組件可以享有這個store并提供對state的更新。
render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

二苫纤、State

Store對象包含所有數(shù)據(jù)碉钠。如果想得到某個時點(diǎn)的數(shù)據(jù)纲缓,就要對 Store 生成快照。這種時點(diǎn)的數(shù)據(jù)集合放钦,就叫做 State色徘。

三、Action

Action 就是 View 發(fā)出的通知操禀,表示 State 應(yīng)該要發(fā)生變化了褂策。

Action 是一個對象。其中的type
屬性是必須的颓屑,表示 Action 的名稱斤寂。其他屬性可以自由設(shè)置,社區(qū)有一個規(guī)范可以參考揪惦。

//react-app/actions/index.js

export const setVisibilityFilter = (filter) => ({
  type: 'SET_VISIBILITY_FILTER',
  filter
})

四遍搞、Reducer

Store 收到 Action 以后,必須給出一個新的 State器腋,這樣 View 才會發(fā)生變化溪猿。這種 State 的計(jì)算過程就叫做 Reducer。

Reducer 是一個函數(shù)纫塌,它接受 Action 和當(dāng)前 State 作為參數(shù)诊县,返回一個新的 State。

Reducer 函數(shù)最重要的特征是措左,它是一個純函數(shù)依痊。也就是說,只要是同樣的輸入怎披,必定得到同樣的輸出胸嘁。

//react-app/reducers/index.js

import { combineReducers } from 'redux'
import visibilityFilter from './visibilityFilter'

const todoApp = combineReducers({
  visibilityFilter
})

export default todoApp
//react-app/reducers/visibilityFilter.js

const visibilityFilter = (state = 'SHOW_ALL', action) => {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

export default visibilityFilter

React-Redux基礎(chǔ)

一、組件

React-Redux 將所有組件分成兩大類:
1凉逛、展示型組件(presentational component)
2性宏、容器型組件(container component)

展示型組件負(fù)責(zé) UI 的呈現(xiàn),容器型件負(fù)責(zé)管理數(shù)據(jù)和邏輯状飞。

此外React-Redux 提供Provider組件衔沼,負(fù)責(zé)讓容器組件拿到state

1、Provider組件

//react-app/index.js

import React from 'react'
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import App from './components/App'
import reducer from './reducers'

//用redux創(chuàng)建的store
//createStore函數(shù)接受另一個函數(shù)作為參數(shù)昔瞧,返回新生成的 Store 對象指蚁。
const store = createStore(reducer)
// Provider就是把我們用redux創(chuàng)建的store傳遞到內(nèi)部的其他組件。
//讓內(nèi)部組件可以享有這個store并提供對state的更新自晰。
render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

2凝化、展示型組件特點(diǎn)

1、只負(fù)責(zé) UI 的呈現(xiàn)酬荞,不帶有任何業(yè)務(wù)邏輯
2搓劫、沒有狀態(tài)(即不使用this.state這個變量)
3瞧哟、所有數(shù)據(jù)都由參數(shù)(this.props)提供
4、不使用任何 Redux 的 API

//react-app/components/App.js

import React from 'react'
import Footer from './Footer'

const App = () => (
  <div>
    <Footer />
  </div>
)

export default App
//react-app/components/Footer.js

import React from 'react'
import FilterLink from '../containers/FilterLink'

const Footer = () => (
  <p>
    Show:
    {" "}
    <FilterLink filter="SHOW_ALL">
      All
    </FilterLink>
    {", "}
    <FilterLink filter="SHOW_ACTIVE">
      Active
    </FilterLink>
    {", "}
    <FilterLink filter="SHOW_COMPLETED">
      Completed
    </FilterLink>
  </p>
)

export default Footer
//react-app/components/Link.js

import React from 'react'
import PropTypes from 'prop-types'

const Link = ({ active, children, onClick }) => {
  if (active) {
    return <span>{children}</span>
  }

  return (
    // eslint-disable-next-line
    <a href="#"
       onClick={e => {
         e.preventDefault()
         onClick()
       }}
    >
      {children}
    </a>
  )
}

Link.propTypes = {
  active: PropTypes.bool.isRequired,
  children: PropTypes.node.isRequired,
  onClick: PropTypes.func.isRequired
}

export default Link

3枪向、容器型組件特點(diǎn)

1勤揩、負(fù)責(zé)管理數(shù)據(jù)和業(yè)務(wù)邏輯,不負(fù)責(zé) UI 的呈現(xiàn)
2秘蛔、帶有內(nèi)部狀態(tài)
3陨亡、使用 Redux 的 API

//react-app/containers/FilterLink.js

import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'

const mapStateToProps = function(state, ownProps) {
    console.log('state : ', state);
    console.log('ownProps : ', ownProps);
    return {
  active: ownProps.filter === state.visibilityFilter
}
}


const mapDispatchToProps = function(dispatch, ownProps){
    console.log('mapDispatchToProps')
     return {
      onClick: () => {
        dispatch(setVisibilityFilter(ownProps.filter))
      }
    }
}

const FilterLink = connect(
  mapStateToProps,
  mapDispatchToProps
)(Link)

export default FilterLink

4、展示型組件和容器型組件對比

展示型組件和容器型組件對比

二深员、connect()

React-Redux 提供connect方法负蠕,用于從 UI 組件生成容器組件。

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

connect()一共有四個參數(shù)倦畅,但我這里只說基本的兩個遮糖,mapStateToProps和mapDispatchToProps。

1叠赐、mapStateToProps

mapStateToProps是一個函數(shù)欲账,建立一個從(外部的)state對象到(UI 組件的)props對象的映射關(guān)系。

mapStateToProps執(zhí)行后應(yīng)該返回一個對象芭概,里面的每一個鍵值對就是一個映射赛不。

mapStateToProps會訂閱 Store,每當(dāng)state更新的時候谈山,就會自動執(zhí)行,重新計(jì)算 UI 組件的參數(shù)宏怔,從而觸發(fā) UI 組件的重新渲染奏路。

mapStateToProps的第一個參數(shù)總是state對象,還可以使用第二個參數(shù)臊诊,代表容器組件的props對象鸽粉。

使用ownProps作為參數(shù)后,如果容器組件的參數(shù)發(fā)生變化抓艳,也會引發(fā) UI 組件重新渲染触机。

const mapStateToProps = function(state, ownProps) {
    return {
        active: ownProps.filter === state.visibilityFilter
    }
}

2、mapDispatchToProps

store.dispatch方法的映射玷或。也就是說儡首,它定義了哪些用戶的操作應(yīng)該當(dāng)作 Action,傳給 Store偏友。它可以是一個函數(shù)蔬胯,也可以是一個對象。

2.1位他、mapDispatchToProps是一個函數(shù)

如果mapDispatchToProps是一個函數(shù)氛濒,會得到dispatch和ownProps(容器組件的props對象)兩個參數(shù)产场。

mapDispatchToProps作為函數(shù),應(yīng)該返回一個對象舞竿,該對象的每個鍵值對都是一個映射京景,定義了 UI 組件的參數(shù)怎樣發(fā)出 Action。

const mapDispatchToProps = function(dispatch, ownProps) {
    return {
        onClick: () => {
            dispatch(setVisibilityFilter(ownProps.filter))
        }
    }
}
2.2骗奖、mapDispatchToProps是一個對象

它的每個鍵名也是對應(yīng) UI 組件的同名參數(shù)确徙,鍵值應(yīng)該是一個函數(shù),會被當(dāng)作 Action creator 重归,返回的 Action 會由 Redux 自動發(fā)出米愿。舉例來說,上面的mapDispatchToProps寫成對象就是下面這樣鼻吮。

const mapDispatchToProps = {
  onClick: (filter) => {
    setVisibilityFilter(filter)
  };
}

Redux 的核心 作流程

Redux 的核心 作流程

最后

如果有疑問育苟,請下載示例代碼,也可以歡迎私信或者留言給我椎木。
如果覺得對你有幫助违柏,請點(diǎn)個??,謝謝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末香椎,一起剝皮案震驚了整個濱河市漱竖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌畜伐,老刑警劉巖馍惹,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異玛界,居然都是意外死亡万矾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門慎框,熙熙樓的掌柜王于貴愁眉苦臉地迎上來良狈,“玉大人,你說我怎么就攤上這事笨枯⌒蕉。” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵馅精,是天一觀的道長严嗜。 經(jīng)常有香客問我,道長洲敢,這世上最難降的妖魔是什么阻问? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮沦疾,結(jié)果婚禮上称近,老公的妹妹穿的比我還像新娘第队。我一直安慰自己,他們只是感情好刨秆,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布凳谦。 她就那樣靜靜地躺著,像睡著了一般衡未。 火紅的嫁衣襯著肌膚如雪尸执。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天缓醋,我揣著相機(jī)與錄音如失,去河邊找鬼。 笑死送粱,一個胖子當(dāng)著我的面吹牛褪贵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播抗俄,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼脆丁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了动雹?” 一聲冷哼從身側(cè)響起槽卫,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎胰蝠,沒想到半個月后歼培,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茸塞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年躲庄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翔横。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡读跷,死狀恐怖梗搅,靈堂內(nèi)的尸體忽然破棺而出禾唁,到底是詐尸還是另有隱情,我是刑警寧澤无切,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布荡短,位于F島的核電站,受9級特大地震影響哆键,放射性物質(zhì)發(fā)生泄漏掘托。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一籍嘹、第九天 我趴在偏房一處隱蔽的房頂上張望闪盔。 院中可真熱鬧弯院,春花似錦、人聲如沸泪掀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽异赫。三九已至椅挣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間塔拳,已是汗流浹背鼠证。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留靠抑,地道東北人量九。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像孕荠,于是被迫代替她去往敵國和親娩鹉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

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