国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

Redux 入門(mén)

shusen / 713人閱讀

摘要:系列文章入門(mén)本文進(jìn)階番外篇狀態(tài)管理,第一次聽(tīng)到這個(gè)詞要追溯到去年年底。只讀的唯一改變的方法就是觸發(fā),是一個(gè)用于描述已發(fā)生事件的普通對(duì)象。沒(méi)有特殊情況沒(méi)有副作用,沒(méi)有請(qǐng)求沒(méi)有變量修改,只進(jìn)行單純執(zhí)行計(jì)算。

系列文章:

Redux 入門(mén)(本文)

Redux 進(jìn)階

番外篇: Vuex — The core of Vue application

狀態(tài)管理,第一次聽(tīng)到這個(gè)詞要追溯到去年年底。那時(shí),F(xiàn)lux 紅透半邊天,而 Reflux 也是風(fēng)華正茂。然而,前一陣一直在忙其他的事,一直沒(méi)時(shí)間學(xué)學(xué)這兩個(gè)庫(kù),到現(xiàn)在 Redux 似乎又有一統(tǒng)天下的趨勢(shì)。

那就來(lái)看看,Redux 是憑借什么做到異軍突起的。

What"s Redux

Redux 是一個(gè) JavaScript 應(yīng)用狀態(tài)管理的庫(kù),它幫助你編寫(xiě)行為一致,并易于測(cè)試的代碼,而且它非常迷你,只有 2KB。

Redux 有一點(diǎn)和別的前端庫(kù)或框架不同,它不單單是一套類(lèi)庫(kù),它更是一套方法論,告訴你如何去構(gòu)建一個(gè)狀態(tài)可預(yù)測(cè)的應(yīng)用。

Why using Redux

隨著單頁(yè)應(yīng)用變得越來(lái)越復(fù)雜,前端代碼需要管理各種各樣的狀態(tài),它可以是服務(wù)器的響應(yīng),也可能是前端界面的狀態(tài)。當(dāng)這個(gè)狀態(tài)變得任意可變,那么你就可能在某個(gè)時(shí)間點(diǎn)失去對(duì)整個(gè)應(yīng)用狀態(tài)的控制。

Redux 就是為了解決這個(gè)問(wèn)題而誕生的。

簡(jiǎn)短地說(shuō),Redux 為整個(gè)應(yīng)用創(chuàng)建并管理一棵狀態(tài)樹(shù),并通過(guò)限制更新發(fā)生的時(shí)間和方式,而使得整個(gè)應(yīng)用狀態(tài)的變化變得可以被預(yù)測(cè)。

除此之外,Redux 有著一整套豐富的生態(tài)圈,包括教程、中間件、開(kāi)發(fā)者工具及文檔,這些都可以在官方文檔中找到。

How to use Redux 三大原則

在使用 Redux 之前,你必須要謹(jǐn)記它的三大原則:?jiǎn)我粩?shù)據(jù)源、state 是只讀的和使用純函數(shù)執(zhí)行修改。

單一數(shù)據(jù)源

整個(gè)應(yīng)用的 state 都被儲(chǔ)存在一棵樹(shù)中,并且這棵狀態(tài)樹(shù)只存在于唯一一個(gè) store 中。

這使得來(lái)自服務(wù)端的 state 可以輕易地注入到客戶(hù)端中;并且,由于是單一的 state 樹(shù),代碼調(diào)試、以及“撤銷(xiāo)/重做”這類(lèi)功能的實(shí)現(xiàn)也變得輕而易舉。

只讀的 state

唯一改變 state 的方法就是觸發(fā) actionaction 是一個(gè)用于描述已發(fā)生事件的普通對(duì)象。

這就表示無(wú)論是用戶(hù)操作或是請(qǐng)求數(shù)據(jù)都不能直接修改 state,相反它們只能通過(guò)觸發(fā) action 來(lái)變更當(dāng)前應(yīng)用狀態(tài)。其次,action 就是普通對(duì)象,因此它們可以被日志打印、序列化、儲(chǔ)存,以及用于調(diào)試或測(cè)試的后期回放。

使用純函數(shù)執(zhí)行修改

為每個(gè) action純函數(shù)編寫(xiě) reducer 來(lái)描述如何修改 state 樹(shù)

或許你是第一次聽(tīng)到純函數(shù)這個(gè)概念,但它是函數(shù)話編程的基礎(chǔ)。

純函數(shù)在維基百科上的解釋簡(jiǎn)單來(lái)說(shuō)是滿足以下兩項(xiàng):

函數(shù)在有相同的輸入值時(shí),產(chǎn)生相同的輸出

函數(shù)中不包含任何會(huì)產(chǎn)生副作用的語(yǔ)句

在這里,reducer 要做到只要傳入?yún)?shù)相同,返回計(jì)算得到的下一個(gè) state 就一定相同。沒(méi)有特殊情況、沒(méi)有副作用,沒(méi)有 API 請(qǐng)求、沒(méi)有變量修改,只進(jìn)行單純執(zhí)行計(jì)算。

知道了三大原則之后,那就可以開(kāi)始了解如何創(chuàng)建一個(gè)基于 Redux 的應(yīng)用。

Action

就如之前提到的,action 是一個(gè)描述事件的簡(jiǎn)單對(duì)象,它是改變 storestate 的唯一方法,它通過(guò) store.dispatch() 方法來(lái)將 action 傳到 store 中。

下面就是一個(gè) action 的例子,它表示添加一個(gè)新的 todo 項(xiàng)。

const ADD_TODO = "ADD_TODO"
// action
{
  type: ADD_TODO,
  text: "Build my first Redux app"
}

可以看到 action 就是一個(gè)簡(jiǎn)單的 JavaScript 對(duì)象。

用一個(gè)字符串類(lèi)型的 type 字段來(lái)表示將要執(zhí)行的動(dòng)作,type 最好用常量來(lái)定義,當(dāng)應(yīng)用擴(kuò)大時(shí),可以使用多帶帶的模塊來(lái)存放 action

除了 type 字段外,action 對(duì)象的結(jié)構(gòu)完全由你自己決定(也可以借鑒 flux-standard-action 來(lái)構(gòu)建你的 action)。

在現(xiàn)實(shí)場(chǎng)景中,action 所傳遞的值很少會(huì)是一個(gè)固定的值,都是動(dòng)態(tài)產(chǎn)生的。所以,要為每個(gè) action 創(chuàng)建它的工廠方法,工廠方法返回一個(gè) action 對(duì)象。

上面的那個(gè)例子就會(huì)變?yōu)椋?/p>

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

Action 的創(chuàng)建工廠可以是異步非純函數(shù)。牽扯到異步的問(wèn)題內(nèi)容就比較多,放到下一篇再分享了。

Reducer

Action 只是一個(gè)描述事件的簡(jiǎn)單對(duì)象,并沒(méi)有告訴應(yīng)用該如何更新 state,而這正是 reducer 的工作。

在 Redux 應(yīng)用中,所有的 state 都被保存在一個(gè)單一對(duì)象中。所以,建議在寫(xiě)代碼前先確定這個(gè)對(duì)象的結(jié)構(gòu)。如何才能以最簡(jiǎn)的形式把應(yīng)用的 state 用對(duì)象描述出來(lái)?

在設(shè)計(jì)過(guò)程中,你會(huì)發(fā)現(xiàn)你有時(shí)需要在 state 中存儲(chǔ)一些如 UI 的 state,盡量將應(yīng)用數(shù)據(jù)和 UI state 分開(kāi)存放。

{
  todos: [
    {
      text: "Consider using Redux",
      completed: true,
    },
    {
      text: "Keep all state in a single tree",
      completed: false
    }
  ]
}

注意:在處理復(fù)雜應(yīng)用時(shí),建議盡可能地把 state 范式化,把所有數(shù)據(jù)放到一個(gè)對(duì)象里,每個(gè)數(shù)據(jù)以 ID 為主鍵,不同實(shí)體或列表間通過(guò) ID 相互引用數(shù)據(jù),這種方法在 normalizr 文檔里有詳細(xì)闡述。

現(xiàn)在我們已經(jīng)確定了 state 對(duì)象的結(jié)構(gòu),就可以開(kāi)始開(kāi)發(fā) reducerreducer 是一個(gè)純函數(shù),它接收舊的 stateaction,返回新的 state,就像這樣

(previousState, action) => newState

還記不記得三大原則

沒(méi)錯(cuò),最后一點(diǎn)使用純函數(shù)進(jìn)行修改,所以,永遠(yuǎn)不要reducer 里做這些操作:

修改傳入的參數(shù)(即之前的 stateaction 對(duì)象)

執(zhí)行有副作用的操作,如 API 請(qǐng)求或路由跳轉(zhuǎn)

調(diào)用非純函數(shù),如 Date.now()Math.random()

將這些銘記于心后,就能創(chuàng)建對(duì)應(yīng)之前 actionreducer 了。

const initialState = {
  todos: []
}

function todoApp(state = initialState, action) {
  switch (action.type) {
    case ADD_TODO:
      return {
        ...state,
        todos: [
          ...state.todos,
          {
            text: action.text,
            completed: false
          }
        ]
      }
    default:
      return state
  }
}

注意:

不要修改傳入的 state,否則它就不是個(gè)純函數(shù)

在遇到未知 action type 的時(shí)候,默認(rèn)返回之前的 state

這樣一個(gè) reducer 就創(chuàng)建好了,是不是很簡(jiǎn)單?多個(gè) action 也是如此,我們?cè)賮?lái)添加一個(gè)

case TOGGLE_TODO:
  return {
    ...state,
    todos: state.todos.map((todo, index) => {
      if (index === action.index) {
        return {
          ...todo,
          completed: !todo.completed
        } // 時(shí)刻謹(jǐn)記不要修改 state,保證 reducer 是純函數(shù)
      }
      return todo
    })
  }

從例子中可以發(fā)現(xiàn),當(dāng)對(duì) state 的一部分進(jìn)行操作時(shí),不會(huì)影響 state 的其他部分,但仍需復(fù)制 state 樹(shù)的其他部分。當(dāng)項(xiàng)目的規(guī)模成長(zhǎng)時(shí),state 樹(shù)的層次也會(huì)隨之增長(zhǎng),對(duì)樹(shù)深層節(jié)點(diǎn)的操作將會(huì)帶來(lái)大量的復(fù)制。

此時(shí),我們就可以將這些相互獨(dú)立的 reducer 拆分開(kāi)來(lái),我們之前的例子就可以改成這樣(官網(wǎng)的例子更能體現(xiàn)這一點(diǎn),為了縮減篇幅我這里省略了另一個(gè) reducer)。

// todos reducer
function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case TOGGLE_TODO:
      return state.map((todo, index) => {
        if (index === action.index) {
          return {
            ...todo,
            completed: !todo.completed
          } // 時(shí)刻謹(jǐn)記不要修改 state,保證 reducer 是純函數(shù)
        }
        return todo
      })
    default:
      return state
  }
}

// main reducer
function todoApp(state = initialState, action) {
  switch (action.type) {
    case ADD_TODO:
    case TOGGLE_TODO:
      return {
        ...state,
        todos: todos(state.todos, action)
      }
   default:
      return state
  }
}

這就是所謂的 reducer 合成,它是開(kāi)發(fā) Redux 應(yīng)用的基礎(chǔ)。

注意:每個(gè) reducer 應(yīng)當(dāng)只負(fù)責(zé)管理全局 state 中它負(fù)責(zé)的一部分;并且,每個(gè) reducerstate 參數(shù)分別對(duì)應(yīng)它管理的那部分 state

由于,每個(gè) reducer 應(yīng)當(dāng)只負(fù)責(zé)管理全局 state 中它負(fù)責(zé)的一部分,那么上面的 main reducer 就能改為

// main reducer
function todoApp(state = initialState, action) {
  return {
    todos: todos(state.todos, action)
  }
}

最后,Redux 提供了 combineReducers() 工具類(lèi),它能幫我們減少很多重復(fù)的模板代碼。

combineReducers() 就像一個(gè)工廠,它根據(jù)傳入對(duì)象的 key 來(lái)篩選出 state 中 key 所對(duì)應(yīng)的值傳給對(duì)應(yīng)的 reducer,最終它返回一個(gè)符合規(guī)范的 reducer 函數(shù)。

最終,我們的 main reducer 就變?yōu)?/p>

// main reducer
const todoApp = combineReducers({
  todos // 等價(jià)于 todos: todos(state.todos, action)
})

隨著應(yīng)用的膨脹,你可以將拆分后的 reducer 放到不同的文件中, 以保持其獨(dú)立性。然后,你的代碼就可以變成這樣...

import { combineReducers } from "redux"
import * as reducers from "./reducers"

const todoApp = combineReducers(reducers)

export default todoApp

Store

Store 用來(lái)存放整個(gè)應(yīng)用的 state,并將 actionreducer 聯(lián)系起來(lái)。它主要有以下幾個(gè)職能:

存儲(chǔ)整個(gè)應(yīng)用的 state

提供 getState() 方法獲取 state

提供 dispatch(action) 方法更新 state

提供 subscribe(listener) 來(lái)注冊(cè)、取消監(jiān)聽(tīng)器

根據(jù)已有的 reducer 來(lái)創(chuàng)建 store 非常容易,只需將 reducer 作為參數(shù)傳遞給 createStore() 方法。

import { createStore } from "redux"
import todoApp from "./reducers"
let store = createStore(todoApp)

這樣,整個(gè)應(yīng)用的 store 就創(chuàng)建完成了。雖然還沒(méi)有界面,但我們已經(jīng)可以測(cè)試數(shù)據(jù)處理邏輯了。

import { addTodo, toggleTodo } from "./actions"

// 打印初始狀態(tài)
console.log(store.getState())

// 注冊(cè)監(jiān)聽(tīng)器,在每次 state 更新時(shí),打印日志
const unsubscribe = store.subscribe(() =>
  console.log(store.getState())
)

// 發(fā)起 actions
store.dispatch(addTodo("Learn about actions"))
store.dispatch(addTodo("Learn about reducers"))
store.dispatch(addTodo("Learn about store"))
store.dispatch(actions.toggleTodo(0))
store.dispatch(actions.toggleTodo(1))

// 停止監(jiān)聽(tīng)
unsubscribe();

運(yùn)行代碼,控制臺(tái)中就能看到下面的輸出。

Data flow

時(shí)刻謹(jǐn)記一點(diǎn):嚴(yán)格的單向數(shù)據(jù)流是 Redux 架構(gòu)的設(shè)計(jì)核心

也就是說(shuō),對(duì) state 樹(shù)的任何修改都該通過(guò) action 發(fā)起,然后經(jīng)過(guò)一系列 reducer 組合的處理,最后返回一個(gè)新的 state 對(duì)象。

Take a try with Angular

之前的舉例已經(jīng)將 redux 最基本的一套生命周期處理展示完畢了,但沒(méi)有個(gè)界面顯示總是不那么令人信服。Redux 官網(wǎng)的例子是將 Redux 同 React 一起使用,但如同一開(kāi)始說(shuō)的,Redux 更是一套方法論,它不單可以和 React 一同使用,也可以和 Angular 等其他框架一同使用。

雖然,同官網(wǎng)用的是不同的框架,但概念是相通的。

首先,頁(yè)面都是由組件構(gòu)成,組件又分為兩大類(lèi):容器組件(Smart/Container Components)展示組件(Dumb/Presentational Components)

容器組件 展示組件
目的 數(shù)據(jù)處理,state 更新 界面展示
受 redux 影響
數(shù)據(jù)來(lái)源 store.subscribe() 組件屬性傳遞
修改數(shù)據(jù) store.dispatch() 調(diào)用通過(guò)組件屬性傳遞的方法

簡(jiǎn)單來(lái)說(shuō),容器組件就是通過(guò) store.subscribe() 這個(gè)方法監(jiān)聽(tīng) storestate 的變化,而展示組件,就是平常使用的普通的組件,只有一點(diǎn)需要注意的是,所有數(shù)據(jù)修改都是通過(guò)父組件中傳遞下來(lái)的 store.dispatch() 方法來(lái)修改。

可以說(shuō),容器組件是整個(gè)界面顯示的核心。

// todos/index.js
import angular from "angular"
import template from "./todos.html"
import controller from "./todos"

const todoContainer = {
    controller,
    template
}

export default angular.module("todoContainer", [])
    .component("todoContainer", todoContainer)
    .name
    
// todos/todos.js
import store from "../../store"
import actions from "../../actions"

export default class TodosContainController {

    $onInit() {
        // 注冊(cè)監(jiān)聽(tīng)器,在每次 state 更新時(shí),更新頁(yè)面綁定內(nèi)容
        this.unsubscribe = store.subscribe(() => {
                console.log(store.getState())
                this.todos = store.getState().todos
        })
    }

    addTodoItem(text) {
        store.dispatch(actions.addTodo(text))
    }

    toggleTodoItem(index) {
        store.dispatch(actions.toggleTodo(index))
    }

    $onDistory() {
        // 銷(xiāo)毀監(jiān)聽(tīng)器
        this.unsubscribe()
    }
}    

// todos/todos.html

Redux 官網(wǎng)并不建議直接這樣使用 store.subscribe() 來(lái)監(jiān)聽(tīng)數(shù)據(jù)的變化,而是調(diào)用 React Redux 庫(kù)的 connect() 方法,因?yàn)?connect 方法做了許多性能上的優(yōu)化。相對(duì)于 Angular,也有 ng-redux 和 ng2-redux 提供了相同的方法。

鑒于展示組件與 redux 并沒(méi)有太大的相關(guān),就不在這里贅述了,有興趣可以去 github 上查看。

至此,一個(gè)簡(jiǎn)單的基于 Angular 并運(yùn)用 Redux 的 todo MVC 應(yīng)用就完成了。

最后

如果你熟悉 Flux,那么這篇圖文并茂的文章獲取會(huì)對(duì)你有很大的幫助。

如果你是和我一樣直接接觸 Redux,那官方文檔是你的首選。

當(dāng)然,你一定得看看 Redux 作者 Dan Abramov 自己錄制的視頻,它會(huì)對(duì)你理解 Redux 有極大的幫助。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/79978.html

相關(guān)文章

  • react-redux插件入門(mén)

    摘要:描述這個(gè)插件可以讓我們的代碼更加的簡(jiǎn)潔和美觀。安裝使用提供了兩個(gè)重要的接口使用了這個(gè)插件,的和就可以忘記來(lái),它們就用不著了。現(xiàn)在有美女個(gè)。 可先查看我的redux簡(jiǎn)單入門(mén) react-redux簡(jiǎn)介 react-redux是使用redux開(kāi)發(fā)react時(shí)使用的一個(gè)插件,另外插一句,redux不是react的產(chǎn)品,vue和angular中也可以使用redux;下面簡(jiǎn)單講解,如何使用rea...

    Baaaan 評(píng)論0 收藏0
  • Redux入門(mén)0x106: `react`、`vue`、`原生 js`集成`redux`

    摘要:概述之前寫(xiě)的所有關(guān)于的文章都是純粹的,是和框架無(wú)關(guān)環(huán)境無(wú)關(guān)的,所以我沒(méi)有將和一起講,為的是吧和分開(kāi),作為獨(dú)立的個(gè)體來(lái)分析,提現(xiàn)的是一種思想,而不是一個(gè)思維定式。而現(xiàn)在我們可以嘗試在中來(lái)使用了。 0x000 概述 之前寫(xiě)的所有關(guān)于redux的文章都是純粹的redux,是和框架無(wú)關(guān)、環(huán)境無(wú)關(guān)的redux,所以我沒(méi)有將redux和react一起講,為的是吧redux和react分開(kāi),作為獨(dú)立...

    BetaRabbit 評(píng)論0 收藏0
  • Reactjs、redux的從入門(mén)到放棄、刪庫(kù)跑路示例

    摘要:我的入門(mén)到放棄之路最近看到很多相關(guān)的問(wèn)題跟討論,越來(lái)越多的小伙伴喜歡這個(gè)框架了,同時(shí)也在看到了有些入門(mén)的小伙伴遇到了各種各樣的問(wèn)題,本人也是框架使用都一枚,公司是騰訊阿里平安三巨頭合資的一家公司,分別上海深圳杭州北京廣州等多個(gè)分部,前端人員 showImg(https://segmentfault.com/img/bVbhonB?w=1278&h=722); 我的react入門(mén)到放棄之...

    Miracle 評(píng)論0 收藏0
  • redux入門(mén)事例

    摘要:中定義來(lái)各個(gè)要做的事情。代碼定義把封裝成一個(gè)方法,這樣用的時(shí)候不用每次定義,避免出錯(cuò)入口文件封裝成方法,方便下面的的訂閱調(diào)用每當(dāng)時(shí),訂閱的函數(shù)就會(huì)執(zhí)行現(xiàn)在有機(jī)關(guān)槍把。通過(guò)的來(lái)觸發(fā),中訂閱的事件就會(huì)執(zhí)行。觸發(fā),獲取的值。 環(huán)境準(zhǔn)備 為了方便,這里使用create-react-app搭建react環(huán)境 create-react-app mydemo 彈出配置 如果需要自定義react的配置...

    cheng10 評(píng)論0 收藏0
  • React-Redux 入門(mén)教程

    摘要:具體了解此方法可以請(qǐng)戳這里最后把對(duì)象暴露給在主入口進(jìn)行調(diào)用我們通過(guò)提供的頂層組件傳入然后把要展示的寫(xiě)入頂層組件就行了,提供了整個(gè)全局的供所有的子組件進(jìn)行調(diào)用具體代碼實(shí)現(xiàn)請(qǐng) 項(xiàng)目目錄 showImg(https://segmentfault.com/img/bVTGs8?w=214&h=571); 整個(gè)項(xiàng)目目錄分為圖中所示: Redux分為{Action,Reducer,Store} 入...

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

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

0條評(píng)論

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