redux 學(xué)習(xí)筆記

redux的作用

redux流程.png

Redux 主要分為三個(gè)部分 Action磁椒、Reducer违寞、及 Store

action

  • action用來傳遞操作 State 的信息,以 Javascript Plain Object 的形式存在哮缺,形如
{
  type: 'ADD_FILM',
  name: 'Mission: Impossible'
}

type 屬性是必要的淌友,用來表達(dá)處理 state 數(shù)據(jù)的方式游两,其他屬性任意太闺,建議簡(jiǎn)單

但為了方便組織跺讯,可以創(chuàng)建函數(shù)來生產(chǎn) action枢贿,即Action Creator

function addFilm(name) {
  return { type: 'ADD_FILM', name: name };
}

Reducer

  • 處理action傳達(dá)需要操作的信息
  • 通過傳入舊的 state 和指示操作的 action 來更新 state

Reducer 根據(jù)傳入的** action.type** 來匹配 case 進(jìn)行不同的 state 更新


function films(state = initialState, action) {
  switch (action.type) {
 
  case 'ADD_FILM':
    // 更新 state 中的 films 字段
    return [{
      id: state.films.reduce((maxId, film) => Math.max(film.id, maxId), -1) + 1,
      name: action.name
    }, ...state];
 
  case 'DELETE_FILM':
    return state.films.filter(film =>
        film.id !== action.id
    );
 
  case 'SHOW_ALL_FILM':
    return Object.assign({}, state, {
        visibilityFilter: action.filter
      });
 //不要修改 state。 使用 Object.assign() 新建了一個(gè)副本
  default:
    return state;
    //在 default 情況下返回舊的 state刀脏。遇到未知的 action 時(shí)局荚,一定要返回舊的 state。
  }

當(dāng) action.type變多時(shí)愈污,可以按照功能拆分耀态,在通過組合函數(shù)合并

function rootReducer(state = {}, action) {
  return {
    films: filmReducer(state.films, action),
    filter: filterReducer(state.filter, action)
  };
}
 // rootReducer 將不同部分的 state 傳給對(duì)應(yīng)的 reducer 處理,最終合并所有 reducer 的返回值暂雹,組成整個(gè)state首装。
 
 //使用Redux 提供的 combineReducers() 方法
import { combineReducers } from 'redux'

var rootReducer = combineReducers({
    films: filmReducer,
    filter: filterReducer
  });
  
 //combineReducers() 將調(diào)用一系列 reducer,并根據(jù)對(duì)應(yīng)的 key 來篩選出 state 中的一部分?jǐn)?shù)據(jù)給相應(yīng)的 reducer杭跪,這樣也意味著每一個(gè)小的 reducer 將只能處理 state 的一部分?jǐn)?shù)據(jù)

Store

  • 銜接action和reducer

Store 是單一的,維護(hù)著一個(gè)全局的 State簿盅,并且根據(jù) Action 來進(jìn)行事件分發(fā)處理 State,Store 是一個(gè)把 Action 和 Reducer 結(jié)合起來的對(duì)象挥下。

生成store

import {createStore } from 'redux'

var store = createStore(rootReducer);

store 對(duì)象可以簡(jiǎn)單的理解為如下形式

function createStore(reducer, initialState) {
    //閉包私有變量 
    var currentReducer = reducer;
    var currentState = initialState;
    var listeners = [];
    function getState() {
      return currentState;
    }    
    function subscribe(listener) {
      listeners.push(listener);
      return function unsubscribe() {
        var index = listeners.indexOf(listener);
        listeners.splice(index, 1);
      };
    }
    function dispatch(action) {
        currentState = currentReducer(currentState, action);
        listeners.slice().forEach(listener => listener());
        return action;
    }
    //返回一個(gè)包含可訪問閉包變量的公有方法
    return {
      dispatch,
      subscribe,
      getState
    };
}

store.getState() 用來獲取 state 數(shù)據(jù)。
store.subscribe(listener) 用于注冊(cè)監(jiān)聽函數(shù)桨醋。每當(dāng) state 數(shù)據(jù)更新時(shí)棚瘟,將會(huì)觸發(fā)監(jiān)聽函數(shù)。
store.dispatch(action) 是用于將一個(gè) action 對(duì)象發(fā)送給 reducer 進(jìn)行處理

store.dispatch({
  type: 'ADD_FILM',
  name: 'Mission: Impossible'
}); 

connect

  • Connect 組件主要為 React 組件提供 store 中的部分 state 數(shù)據(jù) 及 dispatch 方法

通過import { connect } from 'react-redux'將state的值和action綁定到組件的props上

import { connect } from 'react-redux'
import Counter from '../components/Counter' //一個(gè)組件
import * as CounterActions from '../actions/counter'

//將state.counter綁定到props的counter
// state 將由 store 提供
function mapStateToProps(state) {
  return {
    counter: state.counter
  }
}

//將action的所有方法綁定到props上
function mapDispatchToProps(dispatch) {
  return bindActionCreators(CounterActions, dispatch)
}

//通過react-redux提供的connect方法將我們需要的state中的數(shù)據(jù)和actions中的方法綁定到props上
export default connect(mapStateToProps, CounterActions)(Counter)


saga

import {
  takeEvery
} from 'redux-saga'
import {
  call,
  put,
  fork,
  take,
  cancel
} from 'redux-saga/effects'
import {
  GET_LOGINED_REQUEST,
  LOGIN_REQUEST
} from './login.js'
import {
  loginAPI,
  loginedAPI
} from '../../../api'

export function* watchRequestLogined() {
  yield takeEvery(GET_LOGINED_REQUEST, queryFlow)
}

export function* queryFlow(action) {
  const task = yield fork(logined)
  yield take(LOGIN_CANCEL)
  yield cancel(task)
}

export function* logined(){
  try {
    const response = yield call(loginedAPI)
    yield put({
      type: LOGIN_SUCCESS,
      response
    })
  } catch (error) {
    yield put({
      type: LOGIN_CANCEL,
      error
    })
  }
}

export function* watchRequestLogin() {
  yield takeEvery(LOGIN_REQUEST, loginFlow)
}

export function* authorize({account, password}){
  try {
    const response = yield call(loginAPI, {
      account,
      password
    })
    yield put({
      type: LOGIN_SUCCESS,
      response
    })
  } catch (error) {
    yield put({
      type: LOGIN_ERROR,
      error
    })
  }
}

export function* loginFlow(action) {
  const { account, password } = action.payload
  const task = yield fork(authorize, { account, password })
  yield take(LOGIN_CANCEL)
  yield cancel(task)
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喜最,一起剝皮案震驚了整個(gè)濱河市偎蘸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瞬内,老刑警劉巖迷雪,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異虫蝶,居然都是意外死亡章咧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門能真,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赁严,“玉大人,你說我怎么就攤上這事粉铐√墼迹” “怎么了?”我有些...
    開封第一講書人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵蝙泼,是天一觀的道長(zhǎng)程剥。 經(jīng)常有香客問我,道長(zhǎng)汤踏,這世上最難降的妖魔是什么织鲸? 我笑而不...
    開封第一講書人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮溪胶,結(jié)果婚禮上搂擦,老公的妹妹穿的比我還像新娘。我一直安慰自己载荔,他們只是感情好盾饮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著懒熙,像睡著了一般丘损。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上工扎,一...
    開封第一講書人閱讀 51,231評(píng)論 1 299
  • 那天徘钥,我揣著相機(jī)與錄音,去河邊找鬼肢娘。 笑死呈础,一個(gè)胖子當(dāng)著我的面吹牛舆驶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播而钞,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼沙廉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了臼节?” 一聲冷哼從身側(cè)響起撬陵,我...
    開封第一講書人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎网缝,沒想到半個(gè)月后巨税,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粉臊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年草添,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扼仲。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡远寸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出犀盟,到底是詐尸還是另有隱情而晒,我是刑警寧澤蝇狼,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布阅畴,位于F島的核電站,受9級(jí)特大地震影響迅耘,放射性物質(zhì)發(fā)生泄漏贱枣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一颤专、第九天 我趴在偏房一處隱蔽的房頂上張望纽哥。 院中可真熱鬧,春花似錦栖秕、人聲如沸春塌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽只壳。三九已至,卻和暖如春暑塑,著一層夾襖步出監(jiān)牢的瞬間吼句,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工事格, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惕艳,地道東北人搞隐。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像远搪,于是被迫代替她去往敵國(guó)和親劣纲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

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

  • 做React需要會(huì)什么? react的功能其實(shí)很單一棠耕,主要負(fù)責(zé)渲染的功能余佛,現(xiàn)有的框架,比如angular是一個(gè)大而...
    蒼都閱讀 14,759評(píng)論 1 139
  • 學(xué)習(xí)必備要點(diǎn): 首先弄明白窍荧,Redux在使用React開發(fā)應(yīng)用時(shí)辉巡,起到什么作用——狀態(tài)集中管理 弄清楚Redux是...
    賀賀v5閱讀 8,896評(píng)論 10 58
  • http://gaearon.github.io/redux/index.html ,文檔在 http://rac...
    jacobbubu閱讀 79,956評(píng)論 35 198
  • 一蕊退、什么情況需要redux郊楣? 1、用戶的使用方式復(fù)雜 2瓤荔、不同身份的用戶有不同的使用方式(比如普通用戶和管...
    初晨的筆記閱讀 2,028評(píng)論 0 11
  • 前言 本文 有配套視頻净蚤,可以酌情觀看。 文中內(nèi)容因各人理解不同输硝,可能會(huì)有所偏差今瀑,歡迎朋友們聯(lián)系我討論。 文中所有內(nèi)...
    珍此良辰閱讀 11,904評(píng)論 23 111