成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

redux原來(lái)如此簡(jiǎn)單

wuyumin / 1746人閱讀

摘要:是狀態(tài)容器,提供可預(yù)測(cè)化的狀態(tài)管理。一般我們會(huì)使用一個(gè)常量來(lái)表示對(duì)應(yīng)的值。作為純函數(shù),內(nèi)部不建議使用任何有副作用的操作,比如操作外部的變量,任何導(dǎo)致相同輸入但輸出卻不一致的操作。結(jié)合,其他類庫(kù),開(kāi)發(fā)步驟莫不如此。

Redux 是 JavaScript 狀態(tài)容器, 提供可預(yù)測(cè)化的狀態(tài)管理。

那什么是可以預(yù)測(cè)化,我的理解就是根據(jù)一個(gè)固定的輸入,必然會(huì)得到一個(gè)固定的結(jié)果。

redux是專門(mén)為react開(kāi)發(fā)的,但并不是只能用于react,可以用于任何界面庫(kù)。

動(dòng)機(jī)

隨著單頁(yè)面應(yīng)用的普及,web app內(nèi)部需要管理的狀態(tài)越來(lái)越多,這些狀態(tài)可能來(lái)自服務(wù)器端,用戶輸入的數(shù)據(jù),用戶交互數(shù)據(jù),當(dāng)前UI狀態(tài),本地的緩存數(shù)據(jù)等等。如何能夠有條理的管理這些數(shù)據(jù),成為前端開(kāi)發(fā)中一個(gè)難題。

核心概念 三大原則 單一數(shù)據(jù)源

使用redux的程序,所有的state都存儲(chǔ)在一個(gè)單一的數(shù)據(jù)源store內(nèi)部,類似一個(gè)巨大的對(duì)象樹(shù)。

state是只讀的

state是只讀的,能改變state的唯一方式是通過(guò)觸發(fā)action來(lái)修改

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

為了描述 action 如何改變 state tree , 你需要編寫(xiě) reducers。

reducers是一些純函數(shù),接口當(dāng)前state和action。只需要根據(jù)action,返回對(duì)應(yīng)的state。而且必須要有返回。

一個(gè)函數(shù)的返回結(jié)果只依賴于它的參數(shù),并且在執(zhí)行過(guò)程里面沒(méi)有副作用,我們就把這個(gè)函數(shù)叫做純函數(shù)

基礎(chǔ) action

顧名思義,action就是動(dòng)作,也就是通過(guò)動(dòng)作來(lái)修改state的值。也是修改store的唯一途徑。

action本質(zhì)上就是一個(gè)普通js對(duì)象,我們約定這個(gè)對(duì)象必須有一個(gè)字段type,來(lái)表示我們的動(dòng)作名稱。一般我們會(huì)使用一個(gè)常量來(lái)表示type對(duì)應(yīng)的值。

此外,我們還會(huì)把希望state變成什么樣子的對(duì)應(yīng)的值通過(guò)action傳進(jìn)來(lái),那么這里action可能會(huì)類似這樣子的

{
    type: "TOGGLE_TODO",
    index: 5
}
Reducer

Action 只是描述了有事情發(fā)生了這件事實(shí),但并沒(méi)有說(shuō)明要做哪些改變,這正是reducer需要做的事情。

Reducer作為純函數(shù),內(nèi)部不建議使用任何有副作用的操作,比如操作外部的變量,任何導(dǎo)致相同輸入但輸出卻不一致的操作。

如果我們的reducer比較多,比較復(fù)雜,我們不能把所有的邏輯都放到一個(gè)reducer里面去處理,這個(gè)時(shí)候我們就需要拆分reducer。

幸好,redux提供了一個(gè)api就是combineReducers Api。

store

store是redux應(yīng)用的唯一數(shù)據(jù)源,我們調(diào)用createStore Api創(chuàng)建store。

脫離react的redux案例 store,reducer基礎(chǔ)使用

第一步搭建開(kāi)發(fā)環(huán)境,這里不介紹了,參考上一篇文章 手把手教會(huì)使用react開(kāi)發(fā)日歷組件,搭建環(huán)境部分

搭建好環(huán)境切換到目錄下面

npm install redux --save

把index.tsx修改為之下代碼。

import { createStore, combineReducers, applyMiddleware } from "redux"

var simpleReducer = function(state = {}, action) {
  return {
    user: {
      name: "redux"
    }
  }
}

var store = createStore(simpleReducer)

console.log(store.getState())

我們看到控制臺(tái)打印出來(lái)的一個(gè)包含user信息的這么一個(gè)對(duì)象。

我們使用到了幾個(gè)api? createStore創(chuàng)建store,store.getState()獲取store,也就是唯一數(shù)據(jù)源的根節(jié)點(diǎn)。

上文我們也講過(guò),action的情況可能會(huì)比較多,redux也提供了combineReducers Api。如果我們有多個(gè)reducer,我們就可以使用起來(lái)了。

那我們創(chuàng)建多個(gè)reducer測(cè)試一下,代碼如下:

import { createStore, combineReducers, applyMiddleware } from "redux"

function user(state = {name: "redux"}, action) {
  switch (action.type) {
    case "CHANGE_NAME":
      return {
        ...state,
        name: action.name
      }
  }

  return state
}

function project(state = {name: "min-react"}, action) {
  switch (action.type) {
    case "CHANGE_NAME":
      return {
        ...state,
        name: action.name
      }
  }

  return state
}


var rootReducer = combineReducers({
  user,
  project
})

var store = createStore(rootReducer)

console.log(store.getState())

如我們所預(yù)料一樣,我們得到擁有兩個(gè)字段的根store。

結(jié)合view使用

第一步我們把html改造成這個(gè)樣子,新增了一點(diǎn)標(biāo)簽




    
    Document
    


    

第二步,修改index.tsx,如下

import { createStore, combineReducers, applyMiddleware } from "redux"
import { func } from "prop-types"

function user(state = {name: "redux"}, action) {
  switch (action.type) {
    case "CHANGE_USER_NAME":
      return {
        ...state,
        name: action.name
      }
  }

  return state
}

function project(state = {name: "min-react"}, action) {
  switch (action.type) {
    case "CHANGE_PROJECT_NAME":
      return {
        ...state,
        name: action.name
      }
  }

  return state
}


var rootReducer = combineReducers({
  user,
  project
})

var store = createStore(rootReducer)

function render(state = store.getState()) {
  var $userName = document.getElementById("userName")
  $userName.innerHTML = state.user.name
}

render()

console.log(store.getState())

我們看到頁(yè)面正確的顯示了我們user的名稱。下一步我們需要做的就是通過(guò)用戶的操作,改變store的值,進(jìn)而觸發(fā)view的更新。

于是我們新增了這塊代碼:

store.subscribe(function() {
  render()
})

// 綁定用戶事件
var $userNameInput = document.getElementById("userNameInput")
var userNameButton = document.getElementById("userNameButton")
userNameButton.onclick = function() {
  var value = $userNameInput.value
  store.dispatch({
    type: "CHANGE_USER_NAME",
    name: value
  })
}

我們看到保存之后,當(dāng)我們輸入值之后,點(diǎn)擊更改,頁(yè)面的值隨著改變。

但是控制臺(tái)報(bào)了一個(gè)錯(cuò)誤,TS2339: Property "value" does not exist on type "HTMLElement".,這是由于typescript強(qiáng)類型校驗(yàn)沒(méi)通過(guò)導(dǎo)致的。只要加這段代碼就好了

var $userNameInput = document.getElementById("userNameInput") as HTMLInputElement

看到了吧,redux就是這么簡(jiǎn)單。

其他所有上層應(yīng)用,都是在此基礎(chǔ)上開(kāi)發(fā)的,所以開(kāi)發(fā)一個(gè)redux應(yīng)用的步驟就是

定義action和與之對(duì)應(yīng)的reducer

監(jiān)聽(tīng)store的變化,提供回調(diào)函數(shù)

dispatch一個(gè)action,等待好運(yùn)發(fā)生。

結(jié)合react,其他view類庫(kù),開(kāi)發(fā)步驟莫不如此。

高級(jí)應(yīng)用 異步action

我們也看到了,我們的reducer只能做同步應(yīng)用,如果我們需要在reducer,做一些延遲操作,可怎么辦

社區(qū)已經(jīng)有成熟的類庫(kù)做這件事件

npm install redux-thunk --save

redux本身已經(jīng)提高了很好的擴(kuò)展機(jī)制,就是中間件。這點(diǎn)很類似express的中間件。

//引入新的類庫(kù)
import { createStore, combineReducers, applyMiddleware, compose } from "redux"
import thunk from "redux-thunk"

...
//store部分做如下修改
const finalCreateStore = compose(applyMiddleware(thunk))(createStore)
const store = finalCreateStore(rootReducer, {})

redux-thunk的作用就是讓dispatch方法不僅僅只接收action對(duì)象,還可以包含一個(gè)方法。我們可以在這個(gè)方法內(nèi)部去調(diào)用異步代碼

我們把dom事件部分做了如下改造

userNameButton.onclick = function() {
  var value = $userNameInput.value
  store.dispatch(function(dispatch, getState) {
    setTimeout(() => {
      dispatch({
        type: "CHANGE_USER_NAME",
        name: value
      })
    }, 2000)

  })
}

可以看到頁(yè)面元素確實(shí)在2s之后發(fā)生了變化,實(shí)際業(yè)務(wù)中啊,我們這里可以做一些異步操作。

至于redux原理,以及源碼和中間件的源碼講解可以參照我的另外一篇文章 閱讀redux源碼

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

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

相關(guān)文章

  • do一下來(lái)了一個(gè)redux

    摘要:作為一個(gè)狀態(tài)樹(shù),來(lái)對(duì)狀態(tài)進(jìn)行管理。而對(duì)于組件來(lái)說(shuō),你只要一個(gè)就好了。好了,邏輯都明白了,接下來(lái)分析下內(nèi)部機(jī)制就有基礎(chǔ)了。一探分清一般我們的都是配合使用,但是和只是合作關(guān)系,并沒(méi)有血緣關(guān)系。這樣的就相當(dāng)于通過(guò)把和連接起來(lái)了。 導(dǎo)語(yǔ) 一開(kāi)看redux的時(shí)候還是比較蒙的,感覺(jué)比較繞,但是又好像是那么回事,接觸一個(gè)新概念的時(shí)候可能都是如此,多去接觸就熟悉了,今天就來(lái)分享下redux的三大核心為...

    Null 評(píng)論0 收藏0
  • 重新設(shè)計(jì) Redux

    摘要:相關(guān)狀態(tài)父組件傳遞給子組件的狀態(tài)。外部狀態(tài)狀態(tài)是可以從視圖庫(kù)中移出來(lái)的,然后可以使用提供者消費(fèi)者模式把狀態(tài)重新連接回視圖庫(kù)。重新設(shè)計(jì)在我看來(lái),重寫(xiě)是有其必要性的,至少有以下個(gè)方面可以改進(jìn)得更友好。 Redux 學(xué)習(xí)起來(lái)很困難?寫(xiě)起代碼來(lái)很啰嗦?一起來(lái)看看 Rematch 的作者對(duì) Redux 的思考和簡(jiǎn)化吧~ 原文:《Redesigning Redux》, Shawn McKay 都過(guò)...

    kidsamong 評(píng)論0 收藏0
  • 探索 Redux4.0 版本迭代 論基礎(chǔ)談?wù)雇▽?duì)比 React context)

    摘要:在幾天前發(fā)布了新版本,被合入。但是在版本迭代的背后很多有趣的設(shè)計(jì)值得了解。參數(shù)處理這項(xiàng)改動(dòng)由提出。對(duì)透明化處理中的,達(dá)到將包裹起來(lái)的目的。對(duì)的凍結(jié)認(rèn)為,在中使用和方法是一種反模式。尤其是這樣的新,某些開(kāi)發(fā)者認(rèn)為將逐漸取代。 showImg(https://segmentfault.com/img/remote/1460000014571148); Redux 在幾天前(2018.04....

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

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

0條評(píng)論

閱讀需要支付1元查看
<