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

資訊專欄INFORMATION COLUMN

手挽手帶你學(xué)React:四檔(上)一步一步學(xué)會(huì)react-redux (自己寫個(gè)Redux)

sixgo / 2218人閱讀

手挽手帶你學(xué)React入門四檔,用人話教你react-redux,理解redux架構(gòu),以及運(yùn)用在react中。學(xué)完這一章,你就可以開始自己的react項(xiàng)目了。

之前在思否看到過(guò)某個(gè)大神的redux搭建 忘記了大神的名字 這里只記得內(nèi)容了 憑借記憶和當(dāng)時(shí)的學(xué)習(xí)路線寫下本文 隔空感謝

本人學(xué)習(xí)react-redux的時(shí)候遇到了很多坎,特別是不理解為什么這么用,這是什么東西,用來(lái)做什么。加上各種名詞讓人無(wú)法理解,所以這里我決定用人話,從原理走起,一步一步教大家使用react-redux。

開始之前

本文開始之前,你需要先了解一些東西,當(dāng)然我會(huì)在文中都一一教給大家。

首先你要會(huì)React的基礎(chǔ)(這是廢話)
對(duì)高階函數(shù)有一定的了解
有ES6基礎(chǔ)
滿足這三項(xiàng)我們開始往下看。
React上下文 context

react官網(wǎng)說(shuō),context這個(gè)東西你可能永遠(yuǎn)用不到,但是如果你使用了react-redux那么你還是無(wú)意間就使用到了它了。
那么它是個(gè)什么東西呢?你可以把它理解為全局的一個(gè)可以傳遞數(shù)據(jù)的東西,畢竟官方都沒給出對(duì)于context的定義。

我們直接來(lái)看看它是怎么樣來(lái)讓數(shù)據(jù)可以全局使用的

在使用 context之前 你需要先認(rèn)識(shí)這幾個(gè)東西

首先需要

import PropTypes from "prop-types";

prop-types這個(gè)東西是一個(gè)幫你做類型檢測(cè)的 所以我們直接就使用好了

接下來(lái)是 childContextTypes 這個(gè)屬性 它是一個(gè)對(duì)象,里面規(guī)定我們要通過(guò)context來(lái)傳遞給下面的屬性名和類型 它通常在父組件中

然后是 getChildContext(){} 這是個(gè)規(guī)定好的方法 內(nèi)部retrun一個(gè)對(duì)象 用來(lái)初始化 context的數(shù)據(jù)

最后是 contextTypes 這個(gè)屬性 它也是一個(gè)對(duì)象,里面規(guī)定我們要接收context來(lái)傳遞給下面的屬性名和類型 它通常在子組件中

好了 了解了的話 我們開始寫第一個(gè) context了

    // App.js
import React,{Component} from "react"
import PropTypes from "prop-types"  //引入

export default class App extends Component {
    static childContextTypes = {  //聲明要通過(guò)context傳遞的東西
        propA: PropTypes.string,
        methodA: PropTypes.func
      }

        getChildContext () {  //初始化context
            return {
            propA: "propA",
            methodA: () => "methodA"
        }
    }

    constructor(){
        super()

        this.state={
          
        }
    }
    componentWillMount(){
        // console.log(hashHistory)
    }
    render() {
        return (
            
) } } // 為了展示效果定義子組件一 class Children extends Component{ constructor(){ super() this.state={ } } static contextTypes = { //規(guī)定要接收的東西 propA: PropTypes.string } render(){ console.log(this.context.methodA) // 因?yàn)闆]有規(guī)定 所以現(xiàn)在是 undefined return(

{this.context.propA}

{/* 展示propA */}
) } } // 為了展示效果定義子組件二 ChildrenTwo 是 Children的子組件 但是卻通過(guò)context拿到了App組件拿過(guò)來(lái)的值 (越級(jí)傳遞) class ChildrenTwo extends Component{ static contextTypes={ methodA: PropTypes.func } constructor(){ super() this.state={ } } render(){ return(

{this.context.methodA()}

{/* 展示methodA */}
) } }

通俗一點(diǎn)來(lái)說(shuō) 一個(gè)組件 通過(guò) getChildContext方法來(lái)返回一個(gè)對(duì)象 這就是我們的context 經(jīng)過(guò)了 childContextTypes 聲明后 它的下層組件都可以通過(guò) contextTypes 聲明。然后通過(guò)this.context獲取到內(nèi)容并且使用了。

好了 context這里就講完了,大家把它放到你大腦的后臺(tái)里運(yùn)行著,可能在這里你一頭霧水,講這個(gè)干毛。好的,我們接下來(lái)實(shí)現(xiàn)一個(gè)redux架構(gòu)!

從零開始Redux

我們創(chuàng)建一個(gè)HTML文件,就叫redux.html 所有東西我們寫在這一個(gè)html里面。




    
    
    
    Document


    

上面的代碼,通過(guò)函數(shù)渲染把狀態(tài)內(nèi)的東西渲染到了視圖中,但是,這里的狀態(tài)是暴露在外面的,任何一個(gè)地方都可以修改這個(gè)數(shù)據(jù)。這樣就不存在穩(wěn)定性可言了,我們想象一下,如果我們現(xiàn)在規(guī)定,你主動(dòng)修改的state讓程序直接無(wú)視掉,只有你通過(guò)我給你的方法去修改,我才會(huì)認(rèn)可這個(gè)狀態(tài)。因此 dispatch就出現(xiàn)了,這是修改數(shù)據(jù)唯一的地方。




    
    
    
    Document


    

現(xiàn)在 你可以通過(guò)dispatch來(lái)修改state內(nèi)容了,并且必須要按照它的聲明方式,和修改方式有規(guī)律地修改了。

是時(shí)候創(chuàng)建一個(gè)store了

我們現(xiàn)在有了數(shù)據(jù),并且可以修改數(shù)據(jù)了,我們是不是可以創(chuàng)建我們的倉(cāng)庫(kù)了?它的名字叫做 store ,當(dāng)然,如果我們手動(dòng)把這些東西塞進(jìn)去,那就顯得太low了,使用函數(shù)作為一個(gè)工廠,幫我們生成這個(gè)那是極其舒坦的。




    
    
    
    Document


    

到這里我們看到了一點(diǎn)Redux的雛形了,但是我們每次都要手動(dòng)調(diào)用渲染,這是不是就非常地不爽。接下來(lái)我們要監(jiān)聽數(shù)據(jù)變化,讓它自己渲染數(shù)據(jù)。那么這個(gè)監(jiān)聽在哪里呢?沒錯(cuò)store里面

設(shè)置數(shù)據(jù)監(jiān)聽

大家可能想到 我們?nèi)绻唁秩緮?shù)據(jù)加入到dispatch里面不就好了嗎?沒錯(cuò),不過(guò)我們確實(shí)要在dispatch里面做文章。

    function creatStore(state,stateChanger){  //這里我們創(chuàng)建一個(gè)函數(shù)  第一個(gè)參數(shù)是我們要用的狀態(tài)倉(cāng) 第二個(gè)是我們自己做的dispatch 
        const getState = () => state
        const dispatch = (action)=> {
              stateChanger(state,action) 
            // 這里我們改變了狀態(tài) 然后我們需要刷新視圖
              renderApp(state)
        }  //state就是我們放進(jìn)來(lái)的狀態(tài)  action是我們調(diào)用時(shí)候傳進(jìn)來(lái)
        return{getState,dispatch}
    }

    const store = creatStore(state,dispatch) //  這里我們生成了store 

    renderApp(store.getState())  // 渲染
    store.dispatch({type:"UPDATE_HEAD_COLOR",color:"black"})  //改變state數(shù)值
    store.dispatch({type:"UPDATE_HEAD_CONTEXT",context:"我變了"}) //改變state數(shù)值
    // 現(xiàn)在我們可以監(jiān)聽數(shù)據(jù)變化了

但是這里我們遇到一個(gè)問(wèn)題,這個(gè)creatStore只適用于我們當(dāng)前的項(xiàng)目啊,不能夠通用啊。這該怎么辦呢?
其實(shí)簡(jiǎn)單 我們動(dòng)態(tài)傳入渲染的方法不就好了嗎 于是我們把代碼改成這樣

    function creatStore(state,stateChanger){  //這里我們創(chuàng)建一個(gè)函數(shù)  第一個(gè)參數(shù)是我們要用的狀態(tài)倉(cāng) 第二個(gè)是我們自己做的dispatch 
        const getState = () => state
        const listenerList = []
        const subscribe = (listener) => listenerList.push(listener)
        const dispatch = (action)=> {
              stateChanger(state,action) 
            // 這里我們改變了狀態(tài) 然后我們需要刷新視圖
              listenerList.map(item=>item())
        }  //state就是我們放進(jìn)來(lái)的狀態(tài)  action是我們調(diào)用時(shí)候傳進(jìn)來(lái)

        return{getState,dispatch,subscribe}
    }

    const store = creatStore(state,stateChanger) //  這里我們生成了store 
    store.subscribe(()=>renderApp(store.getState()))
    renderApp(store.getState())  // 渲染
    store.dispatch({type:"UPDATE_HEAD_COLOR",color:"black"})  //改變state數(shù)值
    store.dispatch({type:"UPDATE_HEAD_CONTEXT",context:"我變了"}) //改變state數(shù)值
    // 現(xiàn)在我們可以動(dòng)態(tài)加入監(jiān)聽了
性能優(yōu)化

寫到這里 問(wèn)題又出現(xiàn)了,每次我們改動(dòng)一個(gè)數(shù)據(jù) 或者數(shù)據(jù)沒有改動(dòng) 只要是調(diào)用了 dispatch 我們就會(huì)觸發(fā)全部的刷新 我們加上console.log看一下

    // 然后我們聲明三個(gè)渲染函數(shù)    function renderMyHead(myHead){
    function renderMyHead(myHead){
        console.log("渲染了Head")
        var DOM = document.getElementById("myHead")
        DOM.innerHTML = myHead.context
        DOM.style.color = myHead.color
    }

    function renderMyBody(myBody){
        console.log("渲染了Body")
        var DOM = document.getElementById("myBody")
        DOM.innerHTML = myBody.context
        DOM.style.color = myBody.color
    }

    function renderApp(state){
        console.log("渲染了App")

        renderMyHead(state.myHead)
        renderMyBody(state.myBody)
    }

加上這些console以后 你會(huì)發(fā)現(xiàn) 我們只改變了head 但是 body也被重新渲染了 這就大大浪費(fèi)了性能啊 我們?cè)趺崔k呢?沒錯(cuò) 渲染之前檢測(cè)一下數(shù)據(jù)變沒變

不過(guò)我們先拋出一個(gè)問(wèn)題

    function renderMyHead(newMyHead,oldMyHead={}){
        if(newMyHead==oldMyHead){
            return 
        }
        console.log("渲染了Head")
        var DOM = document.getElementById("myHead")
        DOM.innerHTML = newMyHead.context
        DOM.style.color = newMyHead.color
    }
    function renderMyBody(newMyBody,oldMyBody={}){
        if(newMyBody===oldMyBody){
            return
        }
        console.log("渲染了Body")
        var DOM = document.getElementById("myBody")
        DOM.innerHTML = newMyBody.context
        DOM.style.color = newMyBody.color
    }

    function renderApp (newState, oldState = {}) {
        if (newState === oldState) {
            return
        }
        renderMyHead(newState.myHead, oldState.myHead)
        renderContent(newState.myBody, oldState.myBody)
    }

    const store = creatStore(state,dispatch) //  這里我們生成了store 
    let oldState = store.getState()

    store.subscribe(()=>{
        const newState = store.getState() // 數(shù)據(jù)可能變化,獲取新的 state
        renderApp(newState,oldState)  //把新舊數(shù)據(jù)傳禁區(qū)
        oldState = newState //記錄數(shù)據(jù)
    })
    renderApp(store.getState())  // 渲染
    store.dispatch({type:"UPDATE_HEAD_COLOR",color:"black"})  //改變state數(shù)值
    store.dispatch({type:"UPDATE_HEAD_CONTEXT",context:"我變了"}) //改變state數(shù)值

好的 到這里 問(wèn)題來(lái)了,我們寫這個(gè)有用嗎?

答案顯然易見 我們做這個(gè)等同于

    let obj = {cc:1}
    let oldObj = obj
    obj.cc = 3 
    obj===oldObj  // true

他們都指向了同一個(gè)地址呀 這有什么作用

所以我們現(xiàn)在要做的就是需要對(duì) stateChanger內(nèi)部的state返回模式進(jìn)行改動(dòng),我們不再返回值,而是返回對(duì)象,當(dāng)有對(duì)象返回的時(shí)候,我們的newState肯定就不等于oldState了,說(shuō)到就做,嘗試一下




    
    
    
    Document


    

到這里我們已經(jīng)搭建了自己的一個(gè)簡(jiǎn)單的redux了,我們繼續(xù)往react-redux靠近

reducer

我們上面寫 creatStore的時(shí)候 傳入了兩個(gè)參數(shù) state和 stateChanger 我們是不是可以把這兩個(gè)也合并到一起呢?沒問(wèn)題 合并完了就是我們r(jià)eact-redux的reducer

    // 我們就從stateChanger這個(gè)函數(shù)開始改
    function stateChanger(state,action){
        // 這里我們多加一個(gè)判斷 是否有state 如果沒有 我們就return一個(gè) 
        if(!state){
            return{
                myHead:{
                    color:"red",
                    context:"我是腦袋"
                },
                myBody:{
                    color:"blue",
                    context:"我是身體"
                }
            }
        }
        switch (action.type){
            case "UPDATE_HEAD_COLOR":
                return{   //這里我們使用ES6 不再去修改原來(lái)的state 而是 返回一個(gè)新的state 我們 creatStore里面的 dispatch方法也要跟著改動(dòng)
                    ...state,
                    myHead:{
                        ...state.myHead,
                        color:action.color
                    }
                }
            break;
            case "UPDATE_HEAD_CONTEXT":
               return{
                    ...state,
                    myHead:{
                        ...state.myHead,
                        context:action.context
                    }
               }
            break;
            default:
                return{...state}
            break;
        }
    }

    function creatStore(stateChanger){  //現(xiàn)在我們不需要傳入state了 只需要傳入stateChanger 就好了 因?yàn)槲覀兛梢阅玫剿?        let state = null
        const getState = () => state
        const listenerList = []
        const subscribe = (listener) => listenerList.push(listener)
        const dispatch = (action)=> {
             state = stateChanger(state,action)   //這里我們直接覆蓋原來(lái)是state 
            // 這里我們改變了狀態(tài) 然后我們需要刷新視圖
              listenerList.map(item=>item())
        }
        dispatch({}) // 這里初始化 state
        // 我們一切都聲明完成 只需要調(diào)用一次 dispatch({}) 因?yàn)槲覀兊膕tate是null 所以 執(zhí)行了  state = stateChanger(state,action) 從而得到了我們stateChanger內(nèi)部設(shè)置的state了
        return{getState,dispatch,subscribe}
    }

        const store = creatStore(stateChanger) //  這里我們生成了store 并且不用傳入state了 只要把我們寫好的 stateChanger放進(jìn)去就好了  
        // 這個(gè) stateChanger 官方稱之為 reducer
            let oldStore = store.getState()   //緩存舊數(shù)據(jù)
            store.subscribe(()=>{
                let newState = store.getState()  //獲得新數(shù)據(jù)
                renderApp(newState,oldStore)   //調(diào)用比較渲染
                oldStore = newState   //數(shù)據(jù)緩存
            }) 
            renderApp(store.getState())
            store.dispatch({type:"UPDATE_HEAD_COLOR",color:"black"})  //改變state數(shù)值
            store.dispatch({type:"UPDATE_HEAD_CONTEXT",context:"我變了"}) //改變state數(shù)值
            // 經(jīng)過(guò)我們一番改進(jìn) 我們不再去調(diào)用Body的渲染了

到這里 你會(huì)突然發(fā)現(xiàn),自己竟然動(dòng)手實(shí)現(xiàn)了一套redux!我們要和react結(jié)合起來(lái) 還需要一個(gè)過(guò)程。

總結(jié)

在我們四檔上篇里面,從零開始搭建了一個(gè)自己的redux,這里面涉及到了太多高級(jí)的東西,大家需要好好消化,不理解的一定要留言提問(wèn)~~

視頻制作中

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

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

相關(guān)文章

  • 手挽手帶你學(xué)React四檔(下篇)步一學(xué)會(huì)react-redux

    摘要:手挽手帶你學(xué)入門四檔用人話教你,理解架構(gòu),以及運(yùn)用在中。學(xué)完這一章,你就可以開始自己的項(xiàng)目了。結(jié)合搭建基礎(chǔ)環(huán)境我們上一章講過(guò)了的原理,內(nèi)部是有一個(gè)的,只有才可以控制它變化。 手挽手帶你學(xué)React入門四檔,用人話教你react-redux,理解redux架構(gòu),以及運(yùn)用在react中。學(xué)完這一章,你就可以開始自己的react項(xiàng)目了。 視頻教程 上一篇我們自己實(shí)現(xiàn)了Redux,這一篇我們來(lái)...

    FullStackDeveloper 評(píng)論0 收藏0
  • 手挽手帶你學(xué)React:一檔 React環(huán)境搭建,語(yǔ)法規(guī)則,基礎(chǔ)使用

    摘要:當(dāng)屬性是一個(gè)回調(diào)函數(shù)時(shí),函數(shù)接收底層元素或類實(shí)例取決于元素的類型作為參數(shù)。 手挽手帶你學(xué)React入門第一期,帶你熟悉React的語(yǔ)法規(guī)則,消除對(duì)JSX的恐懼感,由于現(xiàn)在開發(fā)中都是使用ES6語(yǔ)法開發(fā)React,所以這次也使用ES6的模式進(jìn)行教學(xué),如果大家對(duì)ES6不熟悉的話,先去看看class相關(guān)內(nèi)容吧,這里我也慢慢帶大家一步一步學(xué)會(huì)React。 視頻教程 視頻教程可移步我的個(gè)人博客:h...

    BicycleWarrior 評(píng)論0 收藏0
  • 手挽手帶你學(xué)React:二檔 React生命周期以及組件開發(fā)

    摘要:手挽手帶你學(xué)入門二檔組件開發(fā)的開始,合理運(yùn)用生命周期和組件,能夠讓你的開發(fā)變地流利又這篇文章帶你學(xué)會(huì)創(chuàng)建組件,運(yùn)用組建。 手挽手帶你學(xué)React入門二檔,組件開發(fā)的開始,合理運(yùn)用生命周期和組件,能夠讓你的開發(fā)變地流利又happy,這篇文章帶你學(xué)會(huì)創(chuàng)建組件,運(yùn)用組建。學(xué)起來(lái)吧! React 組件生命周期 學(xué)習(xí)React,生命周期很重要,我們了解完生命周期的各個(gè)組件,對(duì)寫高性能組件會(huì)有很大...

    izhuhaodev 評(píng)論0 收藏0
  • 手挽手帶你學(xué)VUE:一檔 VUE簡(jiǎn)介以及常用內(nèi)部指令

    摘要:這樣,我們用寫的就寫好了。真的假的大家可以看到,這些在插值表達(dá)式內(nèi)的表達(dá)式直接返回了運(yùn)行完成的結(jié)果,值得一提的是,差值表達(dá)式內(nèi)的規(guī)則和標(biāo)簽內(nèi)的規(guī)則是類似的。 視頻教程 由于思否不能插入視頻,視頻請(qǐng)大家移步,http://www.henrongyi.top 什么是VUE VUE是一套用于構(gòu)建用戶界面的漸進(jìn)式框架,VUE并不是一個(gè)真正意義上的mvvm框架,它更傾向是一種數(shù)據(jù)驅(qū)動(dòng)框架.所以我...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • 手挽手帶你學(xué)VUE:一檔 VUE簡(jiǎn)介以及常用內(nèi)部指令

    摘要:這樣,我們用寫的就寫好了。真的假的大家可以看到,這些在插值表達(dá)式內(nèi)的表達(dá)式直接返回了運(yùn)行完成的結(jié)果,值得一提的是,差值表達(dá)式內(nèi)的規(guī)則和標(biāo)簽內(nèi)的規(guī)則是類似的。 視頻教程 由于思否不能插入視頻,視頻請(qǐng)大家移步,http://www.henrongyi.top 什么是VUE VUE是一套用于構(gòu)建用戶界面的漸進(jìn)式框架,VUE并不是一個(gè)真正意義上的mvvm框架,它更傾向是一種數(shù)據(jù)驅(qū)動(dòng)框架.所以我...

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

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

0條評(píng)論

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