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

資訊專欄INFORMATION COLUMN

Redux之旅-2

liangzai_cool / 3162人閱讀

摘要:之旅時間作者三月懶驢入門配置文章鏈接之旅鏈接前言上一篇文章,很簡單的用代碼來說明了,,,各自的意義和相互的聯(lián)系以及在實際開發(fā)的應(yīng)用。分割你的,使每一個更有意義,之后再合并回來。分割和合并和不同。的只有一個只有一個就意味著只有一個。

Redux之旅-2

時間:2016.4.22-11:24
作者:三月懶驢
入門配置文章:鏈接
Redux之旅-1:鏈接

1. 前言

上一篇文章,很簡單的用代碼來說明了State,Action,Reducer,Store各自的意義和相互的聯(lián)系以及在實際開發(fā)的應(yīng)用。但是在現(xiàn)實開發(fā)環(huán)境用,我們的需求不僅僅上一篇文章那么簡單的。為了應(yīng)付這些復(fù)雜的開發(fā)環(huán)境,我們還需要用到以下這些東西:

Action Creator / bindActionCreators:動態(tài)去生成Action。

combineReducers:分割你的reducers,使每一個reducer更有意義,之后再合并回來。

applyMiddleware / createStoreWithMiddleware:往store里面添加中間件。使得它的功能更加強大。

很明顯,我們將要學(xué)習(xí)的這三個功能,對應(yīng)回上一篇文章的Action,reducer,store。你可以認為這是它們各自的一些擴展。

2. 新的需求

在上一篇文章我們的需求很簡單。就是一個按鈕,點擊就讓數(shù)字遞增,那么今天為了學(xué)習(xí)新的東西,我們就增加一些新的需求。我們需求加兩個按鈕,一個按鈕就是點擊數(shù)字是+2,一個按鈕是切換數(shù)字顏色。那么為了更方便我們的開發(fā),我們的開發(fā)目錄也應(yīng)該修改一下。

主要寫代碼的還是在app這個文件夾里面,里面的目錄分布

component -->放置組件的

index.js

redux -->放置redux

action -->action相關(guān)的

types.js

creator.js

reducer -->reducer相關(guān)的

rootReducer.js

increaseReducer.js --> 處理增加按鈕用的

themeReducer.js --> 處理切換主題按鈕用的

store -->store相關(guān)的

store.js

index.js -->把組件和store connect在一起生成一個新組件

main.js -->程序入口

3. Action Creator 3.1 為什么需要Creator

在Redux之旅-1里面,我們創(chuàng)建了一個很簡單的例子:點擊按鈕遞增。那么在更多的時候,我們的開發(fā)需求是很復(fù)雜的。那么增加一個點擊就+2的按鈕。這時候我們要怎么做?
還記得我們上次定義的Action是這樣的:

let IncreaseAction = {type:"increase"}

其中字符串increase的意思就是增加,那么我們現(xiàn)在的需求里面,一個點擊+2的按鈕,也符合increase這個意思。這時候的Action就不能像之前那樣,直接寫死。因為寫死了就沒辦法讓reducer知道,這個Action是+1還是+2了!而需要引入一個新的概念:Action Creator

let IncreaseAction = (num = 1)=>{
 return{
     type:"increaseAction",
     num  //看注1
 }
}

注1:這里用到了ES6的新語法,增強字面量。具體看文章最后的注釋

上面就是一個Action Creator,聽起來很高大上的英文名詞,其實就是一個幫我們返回Action的函數(shù)。那還記得Action的本質(zhì)其實是什么嗎?一個我們規(guī)定最了低限度要帶著type屬性的對象。那么其實就很簡單了。Creator每次幫我們生成type都是increaseAction,但num不同的Action出來。這樣,reducer就能分辨出我們的這個Action要+1還是+2

3.2 代碼實現(xiàn)

文件位置: app/redux/action/types.js

//為了更加直觀,我們把每個Action的type屬性的值額外用一個文件去描述
export const INCREASE = "increase"  //增加數(shù)字的
export const THEME = "theme"  //切換主題的

文件位置: app/redux/action/creator.js

import * as types from "./types"

export let increaseAction = (num = 1)=>{
  return {
    type:types.INCREASE,
    num
  }
}

export let themeAction = ()=>{
  return {
    type:types.THEME,
  }
}

OK!上面的代碼中,我還順便把切換主題的Action也寫了,雖然它不需要傳入?yún)?shù)去處理,但是為了以后的拓展性,用Action Creator總比用寫死了的Action更佳,畢竟產(chǎn)品經(jīng)理要改需求,誰也擋不住。

4. combineReducers 4.1 分割和合并

和Flux不同。Redux的store只有一個!只有一個store就意味著只有一個state。那么我們設(shè)計state的時候就很會糾結(jié)了。像現(xiàn)在這樣子:

let state = {
    count:0,  //增加數(shù)字
    theme:"#ffffff"  //主題顏色
}

這并不是一個理想的state。一個理想的state應(yīng)該要設(shè)計得很純粹。不應(yīng)該把無關(guān)得兩個東西交錯在一起。因為,我們需要分割開我們的reducer。每個不同的reducer下面僅僅處理自己擁有的state.

let CountState = {
    count:0,  //增加數(shù)字
}
let ThemeState = {
    theme:"#ffffff"  //主題顏色
}

這樣的話,我們的state就可以設(shè)計得很小,并且很純粹。而作為匯總,我們會用combineReducers把這些reducers合并回來。實際上state還是一大塊,但是在reducer的角度來看,每個reducer都指示一小塊。

4.2 代碼實現(xiàn)

文件位置: app/redux/reducer/increaseReducer.js

//處理數(shù)字增加的reducer
import * as types from "../action/types"

let reducer = (state={count:0},action)=>{
    let count = state.count
    switch(action.type){
        case types.INCREASE:
            //注意這里使用的action.num,明白是從哪里來的嗎?
            return {count:count+action.num}
            break
        default:
            return state
    }
}
export default reducer

文件位置: app/redux/reducer/themeReducer.js

//處理主題的reducer
import * as types from "../action/types"

const writeColor = "#ffffff"
const grayColor = "#cccccc"
let reducer = (state={color:writeColor},action)=>{
    let count = state.count
    switch(action.type){
        case types.THEME:
            if(state.color == writeColor){
              return {color:grayColor}
            }
            else {
              return {color:writeColor}
            }
            break
        default:
            return state
    }
}
export default reducer

文件位置: app/redux/reducer/rootReducer.js

//合并兩個reducer
import { combineReducers } from "redux"
import Increase from "./increaseReducer"
import Theme from "./themeReducer"

const rootReducer = combineReducers({
    Increase,
    Theme
})

export default rootReducer
5. Middleware 5.1 什么叫做中間件

在這里我并不打算深入去描述中間件這種概念,如果你是做node開發(fā)的話,又剛好用上了KOA的話,你會對這個東西很熟識。那么這里我簡單的介紹一下什么是中間件。

你可能認為它是一個使用包含自定義功能的(可以讓你包裝 store 的 dispatch 方法來達到你想要的功能),用來擴展 Redux 是一種方式。

在這里,有兩個中間件是推薦使用的。

//用來打log的,開發(fā)時候用很方便
npm install --save-dev redux-logger  
//這個會在異步Action的時候用到,這篇文章沒有到,不細說。
npm install --save redux-thunk

注2:thunk,推薦閱讀阮一峰老師的Thunk 函數(shù)的含義和用法

5.2 代碼實現(xiàn)

文件位置: app/redux/store/store.js

"use strick"
import {createStore,applyMiddleware} from "redux"
import createLogger from "redux-logger"
import rootReducer from "../reducer/rootReducer"
/*
    以前創(chuàng)建store的方式:
    let store = createStore(reducers)
*/
let createStoreWithMiddleware = applyMiddleware(
  createLogger(),
)(createStore)
let store = createStoreWithMiddleware(rootReducer)

export default store
6. 連接組件和redux

這里面和以前的差不多,但又有一些細節(jié)上的東西,我們需要注意的

文件位置: app/redux/index.js

"use strict"

import React from "react"
//注意這里引入:bindActionCreators
import { bindActionCreators } from "redux"
import { Provider,connect } from "react-redux"

//這里引入了組件
import Index from "../component/index"

//引入了action creator 和 store。為啥沒有引入reducer?
//因為reducer在上面創(chuàng)建store的時候已經(jīng)用到了
import * as actions from "./action/creator"
import store from "./store/store"

let {Component} = React

/*
    mapStateToProps里面需要注意的是,由于我們的reducer是合并起來的,因此我們的state也是幾個state拼起來。至于是哪幾個state拼起來?
    可以看回去rootReducer.js里面combineReducers的時候,里面的對象名字就是這里state的名字。
    當然這里的return可以寫成:return {state}也沒所謂。但是為了大家能認清這個state里面有什么東西,這里寫的稍微復(fù)雜一點
*/
let mapStateToProps = (state) =>{
    //return {state}
    return {
        reduxState:{
            Increase:state.Increase,
            Theme:state.Theme,
        }
    }
}
/*
    mapDispatchToProps里面用到了bindActionCreators。關(guān)于bindActionCreators的作用看下面注釋3
*/
let mapDispatchToProps = (dispatch) =>{
    return{
        reduxActions:bindActionCreators(actions,dispatch)
    }
}
let Content = connect(mapStateToProps,mapDispatchToProps)(Index)



class App extends Component{
    render(){
        return 
    }
}

export default App

注3: bindActionCreators(actionCreators, dispatch):是把 action creators 轉(zhuǎn)成擁有同名 keys 的對象,而使用 dispatch 把每個 action creator 包圍起來,這樣可以直接調(diào)用它們。

7. 組件開發(fā)

關(guān)于redux的開發(fā)在上面已經(jīng)完成了,現(xiàn)在進入的是組件的開發(fā),這里面更多的是滿足例子而寫的。沒有太多的現(xiàn)實開發(fā)價值。但是我們可以在這里面很好的觀察,我們寫好的程序是怎樣工作的。

文件位置: app/component/index.js

"use strict"

import React from "react"
let {Component}  = React
class Index extends Component{
    constructor(props){
        super(props)
    }
    //點擊增加按鈕事件
    _addHandle(num){
    /*
    這里面可以想一下increaseAction的名字是怎么來的,同樣下面主題切換按鈕事件的themeAction又是怎么來的,代碼之后為你揭秘。
    */
        let {increaseAction} = this.props.reduxActions
        increaseAction(num)
    }
    //主題切換按鈕事件
    _ThemeHandle(){
        let { themeAction } = this.props.reduxActions
        themeAction()
    }
    render(){
        //這里面輸出props看看里面有什么東西
        //console.log(this.props)
        let { reduxState } = this.props
        return (
            
{reduxState.Increase.count}
切換主題
{this._addHandle(1)}}>+1
{this._addHandle(2)}}>+2
) } } //樣式定義,不用細看 const styles = { circle:{ width:"400px", height:"400px", position:"absolute", left:"50%", top:"50%", margin:"-200px 0 0 -200px", borderRadius:"50px", fontSize:"60px", color:"#545454", backgroundColor:"#ececec", lineHeight:"100px", textAlign:"center", }, btnAddOne:{ width:"100px", height:"50px", lineHeight:"50px", backgroundColor:"#fcfcfc", fontSize:"20px", position:"absolute", left:"40px", bottom:"10px", cursor:"pointer", }, btnAddTwo:{ width:"100px", height:"50px", lineHeight:"50px", backgroundColor:"#fcfcfc", fontSize:"20px", position:"absolute", right:"40px", bottom:"10px", cursor:"pointer", }, btnTheme:{ width:"80%", height:"50px", lineHeight:"50px", backgroundColor:"#fcfcfc", fontSize:"20px", position:"absolute", right:"10%", bottom:"100px", cursor:"pointer", } } export default Index

需要注意:在redux里面action/creator/reducer/store各種定義太多了。有時候你很難找到這個東西的名稱是哪里定義過來的感覺。輸出組件的props的話,我們得到這么一個東西

{
    reduxAction:{
        increaseAction:fn(),
        themeAction:fn(),
    },
    reduxState:{
      Increase:count,
      Theme:color,
    }
}

reduxAction:來自redux/index.js里面,我們mapDispatchToProps的時候return 的一個對象時候自己定義的一個對象名字

increaseAction:fn()/themeAction:fn():因為bindActionCreators的轉(zhuǎn)化造成的和creator的同名函數(shù)。因此這兩個函數(shù)的名稱定義出自redux/action/creator.js

reduxState:來自redux/index.js里面,我們mapStateToProps的時候return 的一個對象時候自己定義的一個對象名字

Increase/Theme 也是在mapStateToProps里面自己定義的。

這里順便貼出入口文件

文件位置: app/main.js

"use strict"
import "babel-polyfill"
import React from "react";
import { render } from "react-dom"

import App from "./redux/index";

render(
    ,
    document.getElementById("main")
);

如果沒有做錯,我們的程序能跑起來,如同下圖一般

而控制臺會在每次按鈕之后,會如同下圖一樣

8. 總結(jié)

和上一次說明state/Action/reducer/store的各種比如不同,這次需要說的分別是Action/reducer/store的一些擴展,為了更好的寫程序,這些擴展是必不可少的,但會給新手一種把程序切割得很零散從而無從下手得感覺。所以這次我更加偏重于說明,每一個擴展存在得意義以及代碼得實現(xiàn),希望大家能看懂。

9.一些ES6的小知識

在3.1的注1的時候,我們說了一個ES6的新特性:字面量增強
ES6里面我們定義一個對象的時候

let c = "abc"
let obj = {
   a,   //這個叫做鍵名簡寫
   b(){   
       //這個是函數(shù)定義的簡寫
       .... 
   },
   [c]:12   // 這個是自定義鍵值寫法,一個很有趣的語法糖
}

等于號后面我們叫做 字面量
以上代碼等價于以下

let obj = {
   a:a,    
   b:function(){   
      ....
   },
   abc:12    
}

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

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

相關(guān)文章

  • Redux之旅-1

    摘要:我們約定,內(nèi)使用一個字符串類型的字段來表示將要執(zhí)行的動作。多數(shù)情況下,會被定義成字符串常量。要進去工廠加工產(chǎn)品,就得帶上相應(yīng)得鑰匙,不同的鑰匙對應(yīng)工廠中上不同的生產(chǎn)線里面的函數(shù),從而有不同的產(chǎn)出改變之后的 時間:2016.4.7-17:24作者:三月懶驢入門配置文章:鏈接 準備 在你的項目下面加入redux / react-redux npm install redux --s...

    hiyang 評論0 收藏0
  • MobX學(xué)習(xí)之旅

    摘要:一其實是一個比較輕便的可擴展的狀態(tài)管理工具,是一個由以及一些其他團隊的人共同維護的開源項目。當應(yīng)用公共狀態(tài)的組件在狀態(tài)發(fā)生變化的時候,會自動完成與狀態(tài)相關(guān)的所有事情,例如自動更新自動緩存數(shù)據(jù),自動通知等。 一、MobX MobX其實是一個比較輕便的可擴展的狀態(tài)管理工具,是一個由Facebook以及一些其他團隊的人共同維護的開源項目。 當應(yīng)用公共狀態(tài)的組件在狀態(tài)發(fā)生變化的時候,會自動完...

    劉福 評論0 收藏0
  • [譯]看這些文章,足夠你學(xué)好redux

    摘要:原文地址我想分享一些文章,來幫你學(xué)習(xí)的概念和架構(gòu)在開始之前我們先來看這兩篇文章,用代替和然后我們通過一個代碼教程我翻譯地址深入了解,然后看一看超級介紹完成你對的探索之旅現(xiàn)在是時候去學(xué)習(xí)和再往前走理解并且看一看關(guān)于的一切注盡量中文地址的我用的 原文地址 我想分享一些文章,來幫你學(xué)習(xí)redux的概念和架構(gòu) 在開始redux之前我們先來看這兩篇文章,用High Order Component...

    fengxiuping 評論0 收藏0
  • 我的源碼閱讀之路:redux源碼剖析

    摘要:到月底了,小明的爸爸的單位發(fā)了工資總計塊大洋,拿到工資之后第一件的事情就是上交,毫無疑問的,除非小明爸爸不要命了。當小明的爸爸收到這個通知之后,心的一塊大石頭也就放下來了。下面我們正式開始我們的源碼閱讀之旅。 前言 用過react的小伙伴對redux其實并不陌生,基本大多數(shù)的React應(yīng)用用到它。一般大家用redux的時候基本都不會單獨去使用它,而是配合react-redux一起去使用...

    CloudwiseAPM 評論0 收藏0
  • 滾蛋吧!constant 君

    摘要:引入,有效解決事件分發(fā)時,事件類型的一致性以及清晰邏輯性。其實,細心思考,不難發(fā)現(xiàn),隨著項目增大。目錄將會隨著數(shù)據(jù)處理事件迅速膨脹。大家一直維護著這個事件命名機制,身心疲憊有木有。其實,隨著項目增大,獨立出來的也會導(dǎo)致非常麻煩的維護問題。 作者:Jogis原文鏈接:https://github.com/yesvods/Blog/issues/4轉(zhuǎn)載請注明原文鏈接以及作者信息 前言 事情...

    huangjinnan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<