成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入淺出redux學(xué)習(xí)(-)

xietao3 / 1517人閱讀

摘要:只要輸入的值不變,每次輸出都是一樣的值。指定位置元素運(yùn)算操作如可用以下方式代替主要是生成中最核心的對(duì)象。描述發(fā)生了什么,是響應(yīng)并對(duì)進(jìn)行更新。生成的對(duì)象包含個(gè)方法,分別為,和。按照約定,具有字段來(lái)表示它的類型。

前言:  
一開(kāi)始接觸redux的時(shí)候最令我記住的一句話是:You Might Not Need Redux(那我還寫這篇文章干嘛?手動(dòng)滑稽)
回歸正題,本文主要是圍繞redux的作者Dan的視頻,由淺入深了解redux
redux基礎(chǔ)用法 1. Action

如果需要改變state(狀態(tài)),我們需要使用到Action。Action是一個(gè)普通的JavaScript對(duì)象描述state變化。action的屬性可以自定義,但是必須有一個(gè)叫type的屬性,值是string類型(方便序列化)。每一個(gè)action都是對(duì)state的一個(gè)(minimal change)最小修改,在應(yīng)用里什么東西發(fā)生了變化。

  //創(chuàng)建一個(gè)加法器,減法器
  const INCREMENT = "INCREMENT";
  
  {
    type: INCREMENT
  }

  const DECREMENT = "DECREMENT";
  
  {
    type: DECREMENT
  }
  
  //-----------------------------

  //比如添加新todo任務(wù)
  // action type字符常量
  const ADD_TODO = "ADD_TODO";

  // ADD_TODO action
  {
    type: ADD_TODO,
    text: "Learn Redux"
  }
2. 純函數(shù)和非純函數(shù)

什么是純函數(shù)?

純函數(shù)就是沒(méi)有副作用的函數(shù),不包含數(shù)據(jù)庫(kù)查詢、網(wǎng)絡(luò)請(qǐng)求等操作。只要輸入的值不變,每次輸出都是一樣的值。
//pure function
function square(x) {
  return x * x;
}

// Impure function
function square(x) {
  updateXInDatabase(x);
  return x * x;
}

為什么需要說(shuō)純函數(shù)?
因?yàn)樵趓edux中,有些函數(shù)必須是純函數(shù),比如reducer,所以在編碼的時(shí)候有必要注意。

3. reducer

注意!reducer必須是純函數(shù),不能更改state,每次都必須返回一個(gè)新的state。
reducer,其實(shí)就是描述舊狀態(tài)(previous state)如何轉(zhuǎn)換為當(dāng)前狀態(tài)(current state)的函數(shù)。

這里使用的是計(jì)數(shù)器例子,我們通過(guò)actiontype

const counter = (state = 0, action) => {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

reducer是需要固定的形式的,需要傳入2個(gè)參數(shù),一個(gè)是state,另一個(gè)是action。
我們這里先不要管為什么要這么寫,記住這是redux的規(guī)定即可。我們可以通過(guò)es6的默認(rèn)參數(shù)方式賦予state初始默認(rèn)值。

4. 編寫reducer注意點(diǎn)

因?yàn)閞educer是純函數(shù),因此需要注意幾點(diǎn):

不能改變參數(shù)

不能使用非純函數(shù)

接下來(lái)我們一起看一下怎么處理reducer中對(duì)數(shù)據(jù)的處理。
reducer的state處理通常是兩種數(shù)據(jù)類型:

Object

Array

Object
// 注意,不能直接改變state中的屬性值
state.name = "ken" // ?這種對(duì)name屬性賦值操作是不允許的

// ---------------------------
// 正確??做法
// 1,使用Object的assign方法,需要對(duì)瀏覽器做polyfill
return Object.assign({}, state, { name: "ken" });

// 或者使用es7的解構(gòu)方法
return {
  ...state,
  name: "ken",
};
Array

array的操作中,常用操作為:

增(push)

刪(splice)

指定位置元素運(yùn)算操作,如 array[index]++ array[index] = array[index] * 2等操作

注意上述3個(gè)操作都是會(huì)改變?cè)瓟?shù)組,因此需要使用“純”操作代替這些“非純”操作。

push/pop/shift/unshift

如果需要使用push,我們可以使用concat方法代替。
concat方法返回一個(gè)新數(shù)組,且不改變?cè)瓟?shù)組。

array.push(x); // ?
array.concat(x); // ?
// 或者使用解構(gòu)方式
[...array, x];

splice

同理,splice操作也是會(huì)改變?cè)瓟?shù)組,我們可以用slice去代替。

array.splice(index, 1); // ?
[...array.slice(0, index),
 ...array.slice(index + 1)]; // ?

指定位置元素運(yùn)算操作

// 如 
array[index]++ // ?
// 可用以下方式代替 ?
[...array.slice(0, index),
array[index] + 1,
...array.slice(index + 1)];
5. createStore

createStore主要是生成redux中最核心的Store對(duì)象。action描述“發(fā)生了什么”,reducer是響應(yīng)action并對(duì)state進(jìn)行更新。而store可以看成把actionreducer聯(lián)系起來(lái)的一個(gè)對(duì)象。

import { createStore } from redux;

const store = createStore(counter)

console.log(store.getState());
// output 0

store.dispatch({ type: "INCREMENT"} );
console.log(store.getState());
// output 1

// ------------------------------
const render = () => {
  document.body.innerText = store.getState();
};
store.subscribe(render);

document.addEventListener("click", () => {
  store.dispatch({ type: "INCREMENT" });
});

createStore生成的store對(duì)象包含3個(gè)方法,分別為getStatedispatchsubscribe。其中subscribe函數(shù)的返回值是一個(gè)函數(shù),用于取消訂閱。

getState()返回應(yīng)用當(dāng)前的state樹(shù)。

dispatch(action)分發(fā)action。這個(gè)是觸發(fā)state改變的唯一方法。
action是描述應(yīng)用變化的普通對(duì)象。按照約定,action 具有 type 字段來(lái)表示它的類型。type 也可被定義為常量或者是從其它模塊引入。

subscribe(listener)添加一個(gè)變化監(jiān)聽(tīng)器。listener是一個(gè)函數(shù),每當(dāng)執(zhí)行dispatch方法時(shí)候就會(huì)執(zhí)行l(wèi)istener。 在例子中,每次dispatch一個(gè)action,就會(huì)觸發(fā)render函數(shù)執(zhí)行。如果需要解除綁定監(jiān)聽(tīng),執(zhí)行subscribe返回的函數(shù)即可。

6. 實(shí)現(xiàn)一個(gè)簡(jiǎn)單版的createStore

我們知道createStore返回的是一個(gè)store對(duì)象,其中包括getState,dispatchsubscribe方法。
當(dāng)然接下來(lái)的實(shí)現(xiàn)是最簡(jiǎn)單的實(shí)現(xiàn),去掉了很多參數(shù)校驗(yàn)、store enhancer(即中間件)和類RxJS等reactive庫(kù)支持。有興趣更深了解的同學(xué)可以看看redux的createStore源碼(ps:我打算下一篇文章寫關(guān)于redux源碼??)

const CreateStore = (reducers, initState = {}) {
  let currentState = initState;
  let listeners = [];

  // getState就是簡(jiǎn)單的把當(dāng)前的state返回給調(diào)用者
  const getState = () => currrentState;

  // subscribe:
  // 如果對(duì)觀察者模式(發(fā)布-訂閱模式)比較熟悉的同學(xué)就會(huì)發(fā)現(xiàn),這其實(shí)就是做訂閱
  // 
  const subscribe = listener => {
    listeners.push(listener);
    return function unsubscribe() {
      listeners = listeners.filter(currentListener => currentListener !== listener)
    };
  };

  // 同理,這個(gè)是觀察者模式中的發(fā)布
  // 接收到action后,通過(guò)reducer更新state,并且把listeners執(zhí)行一遍
  const dispatch = action => {
    reducers(currentState, action);
    listens.forEach(listener => listener());
  }

  // 初始化
  // 讓reducers返回他們的初始state
  dispatch({});

  return {
    getState,
    subscribe,
    dispatch,
  };
};

我們很簡(jiǎn)單就實(shí)現(xiàn)了createStore,當(dāng)然實(shí)際上還是會(huì)稍微復(fù)雜一點(diǎn)。

7. combineReducers

從上述我們實(shí)現(xiàn)的createStore源碼可以看出,傳入的reducer只有一個(gè)
真實(shí)的應(yīng)用中reducer是多個(gè)的,因此我們需要把reducer組合起來(lái)。combineReducers就是幫我們完成這個(gè)任務(wù)。

import { combineReducers } from "redux";

const todosReducer = (state = {}, action) => {
  switch (action.type) {
    ...
  }
};

const visibilityFilterReducer = (state = {}, action) => {
  switch (action.type) {
    ...
  }
};

const reducer = combineReducers({
  todos: todosReducer,
  visibilityFilter: visibilityFilterReducer,
});

const store = createStore(reducer, {});

代碼主要完成了把todosReducer和visibilityFilterReducer合并為一個(gè)reducer;todos和visibilityFilter分別是兩個(gè)變量接收兩個(gè)reducer處理的結(jié)果。

其實(shí)我們可以這么理解

const todosAndVisibilityFilterReducer = (state = {
  todos: {},
  visibilityFilter: {}
}, action) => {
  switch (action.type) {
    ...
    // 合并todosReducer和visibilityFilterReducer的case即可
  }
}

const store = createStore(todosAndVisibilityFilterReducer, {});

當(dāng)然真實(shí)項(xiàng)目不能這么搞,既然redux提供了combineReducers,我們就應(yīng)該使用。

8. 實(shí)現(xiàn)一個(gè)簡(jiǎn)單版的combineReducers

和createStore一樣,我們寫一個(gè)簡(jiǎn)單版本的combineReducers。

//可以理解combineReducers就是一個(gè)reducer,因此其返回值是一個(gè)可以傳入(state, action)的函數(shù)
const combineReducers = (reducers = {}) => {
  return (state = {}, action) => {
    // 和普通的reducer一樣,返回一個(gè)新的state作為返回值
    // 此處選擇Array.reducer方法更加簡(jiǎn)潔;forEach還要?jiǎng)?chuàng)建一個(gè)臨時(shí)變量保存新值。
    return Object.keys(reducers).reduce((nextState, key) => {
      // 這里的key可以套入todos/visibilityFilter
      // 執(zhí)行每個(gè)reducer方法,并取得其返回的state值,放入nextState中
      nextState[key] = reducers[key](state[key], action);
      return nextState;
    });
  }
};
參考

redux官網(wǎng)

Dan的Getting Started With Redux系列課程(非常贊,5星級(jí)推薦)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/98720.html

相關(guān)文章

  • redux 資料合集

    摘要:資料合集學(xué)習(xí)有段時(shí)間了,相關(guān)不錯(cuò)的資料整理下,希望能幫到有緣人五顆星推薦中文文檔通讀不下邊,翻譯的很好,想理解清楚,定下心來(lái),認(rèn)真讀,必有收獲官方推薦資料合集,沒(méi)有啥說(shuō)的中間件深入淺出就因?yàn)榭戳诉@篇文章才更加深入學(xué)習(xí),同時(shí)對(duì)有了別樣的看法 redux 資料合集 學(xué)習(xí)redux有段時(shí)間了,相關(guān)不錯(cuò)的資料整理下,希望能幫到有緣人 五顆星推薦 中文文檔 通讀不下3邊,翻譯的很好,想理解清楚...

    Alan 評(píng)論0 收藏0
  • 深入redux技術(shù)棧

    摘要:另外,內(nèi)置的函數(shù)在經(jīng)過(guò)一系列校驗(yàn)后,觸發(fā),之后被更改,之后依次調(diào)用監(jiān)聽(tīng),完成整個(gè)狀態(tài)樹(shù)的更新??偠灾?,遵守這套規(guī)范并不是強(qiáng)制性的,但是項(xiàng)目一旦稍微復(fù)雜一些,這樣做的好處就可以充分彰顯出來(lái)。 這一篇是接上一篇react進(jìn)階漫談的第二篇,這一篇主要分析redux的思想和應(yīng)用,同樣參考了網(wǎng)絡(luò)上的大量資料,但代碼同樣都是自己嘗試實(shí)踐所得,在這里分享出來(lái),僅供一起學(xué)習(xí)(上一篇地址:個(gè)人博客/s...

    imingyu 評(píng)論0 收藏0
  • 深入redux技術(shù)棧

    摘要:另外,內(nèi)置的函數(shù)在經(jīng)過(guò)一系列校驗(yàn)后,觸發(fā),之后被更改,之后依次調(diào)用監(jiān)聽(tīng),完成整個(gè)狀態(tài)樹(shù)的更新。總而言之,遵守這套規(guī)范并不是強(qiáng)制性的,但是項(xiàng)目一旦稍微復(fù)雜一些,這樣做的好處就可以充分彰顯出來(lái)。 這一篇是接上一篇react進(jìn)階漫談的第二篇,這一篇主要分析redux的思想和應(yīng)用,同樣參考了網(wǎng)絡(luò)上的大量資料,但代碼同樣都是自己嘗試實(shí)踐所得,在這里分享出來(lái),僅供一起學(xué)習(xí)(上一篇地址:個(gè)人博客/s...

    VPointer 評(píng)論0 收藏0
  • redux深入進(jìn)階

    摘要:上一篇文章講解了如何使用,本篇文章將進(jìn)一步深入,從的源碼入手,深入學(xué)習(xí)的中間件機(jī)制。的功能是讓支持異步,讓我們可以在中跟服務(wù)器進(jìn)行交互等操作,而他的實(shí)現(xiàn)。。。 上一篇文章講解了redux如何使用,本篇文章將進(jìn)一步深入,從redux的源碼入手,深入學(xué)習(xí)redux的中間件機(jī)制。在這里我們會(huì)以一個(gè)redux-thunk中間件為例,逐步分解redux的中間機(jī)制如何操作,如何執(zhí)行。 閑話不多說(shuō),...

    omgdog 評(píng)論0 收藏0
  • 教你如何打好根基快速入手react,vue,node

    摘要:謹(jǐn)記,請(qǐng)勿犯這樣的錯(cuò)誤。由于在之前的教程中,積累了堅(jiān)實(shí)的基礎(chǔ)。其實(shí),這是有緣由的其復(fù)雜度在早期的學(xué)習(xí)過(guò)程中,將會(huì)帶來(lái)災(zāi)難性的影響。該如何應(yīng)對(duì)對(duì)于來(lái)說(shuō),雖然有大量的學(xué)習(xí)計(jì)劃需要采取,且有大量的東西需要學(xué)習(xí)。 前言倘若你正在建造一間房子,那么為了能快點(diǎn)完成,你是否會(huì)跳過(guò)建造過(guò)程中的部分步驟?如在具體建設(shè)前先鋪設(shè)好部分石頭?或直接在一塊裸露的土地上先建立起墻面? 又假如你是在堆砌一個(gè)結(jié)婚蛋糕...

    ddongjian0000 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<