亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

【教程】Pastate.js 響應(yīng)式框架(二)多組件應(yīng)用

Leo_chen / 3103人閱讀

摘要:這一章,我們?cè)谏弦徽碌慕Y(jié)構(gòu)中添加多一些信息,并用多個(gè)組件來組織應(yīng)用。是的響應(yīng)式影子可以對(duì)任何節(jié)點(diǎn)進(jìn)行直接賦值修改,會(huì)把修改結(jié)果作用到,并異步觸發(fā)視圖更新。因此在中的是對(duì)象而在中的是對(duì)象。

這是 pastate 系列教程的第二章,歡迎關(guān)注,持續(xù)更新。

這一章,我們?cè)谏弦徽碌?state 結(jié)構(gòu)中添加多一些信息,并用多個(gè)組件來組織 pastate 應(yīng)用。

更新 state 結(jié)構(gòu)

我們把上一章的個(gè)人基本信息數(shù)據(jù)包裝為 state.basicInfo 屬性的對(duì)象,并向 state 中添加 address 屬性,保存?zhèn)€人地址信息:

const initState = {
    basicInfo: {
        name: "Peter",
        isBoy: true,
        age: 10
    },
    address: {
        country: "China",
        city: "Guangzhou"
    }
}

由于 JavaScript 語言的限制,pastate 不能檢測(cè)到通過賦值來為對(duì)象添加新屬性,以自動(dòng)把新屬性轉(zhuǎn)化為響應(yīng)式節(jié)點(diǎn)。所以你應(yīng)該在 initState 中把需要用到的 state 屬性都定義出來,把屬性值初始化為 null 或空數(shù)組都是可以的。下面是個(gè)錯(cuò)誤的例子

const initState = {
    basicInfo: ...,
    address: ...
}
const store = new Pastore(initState)
const state = store.state

state.hobby = "coding"  // 錯(cuò)誤,state.hobby 屬性不具有受 pastate 控制,不具有響應(yīng)式特點(diǎn)

即使支持這種特性,它也會(huì)使開發(fā)者難以完全把握 state 的結(jié)構(gòu),導(dǎo)致應(yīng)用難以開發(fā)和維護(hù),所以我們應(yīng)該在 initState 里對(duì) state 的結(jié)構(gòu)進(jìn)行完整的定義。

分別開發(fā) basicInfo 和 address 的視圖組件

我們先使用一種簡(jiǎn)單臨時(shí)的方式來構(gòu)建子組件:

...
/** @type {initState} */
const state = store.state;

class BasicInfoView extends Component {
    render(){
        return (
            
Basic info:
My name is {state.basicInfo.name}.
I am a {state.basicInfo.isBoy == true ? "boy" : "girl"}.
I am {state.basicInfo.age} years old.
) } }
class AddressView extends Component {
    render(){
        return (
            
Address:
My country is {state.address.country}.
My city is {state.address.city}.
) } }

可以看到,BasicInfoView 組件直接引用 store.state.basicInfo 的值,AddressView 組件直接引用 store.state.address 的值。接著修改原來的 AppView 父組件,把這兩個(gè)子組件嵌套進(jìn)去,同時(shí)增加一個(gè)方法來修改 address.city 的值:

...
class AppView extends Component {
    increaseAge(){
        state.basicInfo.age += 1
    }
    decreaseAge(){
        state.basicInfo.age -= 1
    }
    changeCity(){
        state.address.city += "!"
    }
    render() {
        return (
            
) } } ...

完成!讓我們運(yùn)行一下:

點(diǎn)擊按鈕,看起來一切正常!我們通過 Chrome 的 react dev tools 來觀察一下當(dāng) state 改變時(shí),各個(gè)組件的渲染情況。打開瀏覽器的開發(fā)者工具,選擇 react 標(biāo)簽,勾選上 Highlight Updates, 這時(shí)當(dāng)組件重新渲染時(shí),會(huì)被帶顏色的方框框起來。

我們點(diǎn)擊頁面上 decrease age 按鈕試試,組件重新渲染的結(jié)果如下:

我們可以發(fā)現(xiàn),當(dāng)只有 state.basicInfo.age 更改時(shí),AppView、BasicInfoView 和 AddressView 3個(gè)組件都會(huì)被重新渲染,即使 AddressView 所引用的數(shù)據(jù)沒有發(fā)生任何改變!這是 react 多組件渲染的通常情況,當(dāng)應(yīng)用組件簡(jiǎn)單、嵌套層級(jí)不多時(shí),我們不會(huì)感覺到這種模式會(huì)帶來什么明顯的影響;但是當(dāng)應(yīng)用組件的嵌套關(guān)系變得比較復(fù)雜的時(shí)候,會(huì)帶來性能隱患,我們需要來關(guān)注這個(gè)問題。

store.imState 與 store.state

先介紹一下 store 中的兩個(gè)不同的 state:store.imStatestore.state ,你可以嘗試了解一下:

store.imState 是應(yīng)用狀態(tài)的數(shù)據(jù)實(shí)體,它被 pastate 使用 immutable 的機(jī)制進(jìn)行管理,當(dāng)節(jié)點(diǎn)的內(nèi)容更新時(shí),該節(jié)點(diǎn)的所有祖先的“引用”都會(huì)被更新。imState 的每個(gè)節(jié)點(diǎn)值除了 null 或 undefined 外,都是包裝類型(String, Number, Boolean, Object, Array)。

store.state 是 store.imState 的 響應(yīng)式影子, 可以對(duì) store.state 任何節(jié)點(diǎn)進(jìn)行直接賦值修改,pastate 會(huì)把修改結(jié)果作用到 store.imState,并異步觸發(fā)視圖更新。

或者簡(jiǎn)化為以下兩點(diǎn):

store.imState 用來渲染視圖

store.state 用來操作數(shù)據(jù)

這兩個(gè)概念對(duì)于沒有使用過 redux 和沒了解過 vue.js 原理的人來說可能有點(diǎn)難以理解。不過沒關(guān)系,不理解這兩個(gè)概念并不妨礙你使用 pastate,你可以在使用 pastate 的過程中完全感覺不到 imState 的存在。pastate 的理念就是封裝復(fù)雜概念,讓你可以用一種簡(jiǎn)單的方式去實(shí)現(xiàn)復(fù)雜的功能。

如果你想要理解 pastate 的詳細(xì)原理,可以查看原理章節(jié)。

使用 props 接收 imState,實(shí)現(xiàn)組件的按需渲染

當(dāng)一個(gè) component 與 store 連接時(shí),store 會(huì)把 imState 傳遞到 component 的 props
.state 中,因此我們可以在 AppView 組件的 props 中接收 state,同時(shí)把 AppView 組件的基類改為 react 純組件 PureComponent,這樣就開啟了組件按需渲染效果:

import React, { PureComponent } from "react"; // 1. 改用 PureComponent 代替 Component
...
class AppView extends PureComponent { // 1. 改用 PureComponent
    ...
    render() {
        /** @type {initState} */
        let state = this.props.state; // 2. 從 props 接收 state
        return (
            
{/** 3. 把 state 的子節(jié)點(diǎn)傳遞給對(duì)于的子組件 */} ...
) } } ...

注意上面代碼的第3點(diǎn)注釋,我們把 state 數(shù)據(jù)的子節(jié)點(diǎn)通過 props 傳遞給子組件:
。對(duì)于不直接與 store 直接連接的子組件,我們同樣也需要修改為從
props 獲取 state, 并把組件的基類改成 PureComponent:

class BasicInfoView extends PureComponent { // 1. 基類改為 PureComponent
    render(){
        let state = this.props.state; // 2. 從 props 接收 state
        return (
            
Basic info:
{/** 3. 這里的 state 是 basicInfo 對(duì)象 */} My name is {state.name}.
I am a {state.isBoy == true ? "boy" : "girl"}.
I am {state.age} years old.
) } }
class AddressView extends PureComponent { // 1. 基類改為 PureComponent
    render(){
        let state = this.props.state;  // 2. 從 props 接收 state
        return (
            
Address:
{/** 3. 這里的 state 是 address 對(duì)象 */} My country is {state.country}.
My city is {state.city}.
) } }

可以看到,分配到子組件的 props 中的 state 是 根state 的子節(jié)點(diǎn)。因此在 BasicInfoView 中的 this.props.state 是 basicInfo 對(duì)象, 而在 AddressView 中的 this.props.state 是 address 對(duì)象。

完成!我們來看看運(yùn)行效果!

點(diǎn)擊 decrease age 按鈕或 increase age 按鈕,我們看到的組件重新渲染情況是:

點(diǎn)擊 change city 按鈕,我們看到的組件重新渲染情況是:

Amazing!可以看到當(dāng)我們點(diǎn)擊按鈕改變 state 節(jié)點(diǎn)時(shí),只有引用被改變的 state 節(jié)點(diǎn)的組件才會(huì)進(jìn)行重新渲染, 我們成功地實(shí)現(xiàn)了多組件按需渲染的效果!當(dāng)應(yīng)用具有大量不與 store 直接連接的子組件時(shí),這種按需渲染的策略可以大幅提高應(yīng)用的渲染性能。

使用 imState 渲染視圖的注意事項(xiàng)

從 props 中接收到的 state 的每個(gè)節(jié)點(diǎn)都是特殊的包裝類型 , 當(dāng)需要在 if(...) 語句或 ... ? A : B 使用其布爾值結(jié)果時(shí), 需要使用 == 進(jìn)行顯式比較來獲取,如下

class BasicInfoView extends PureComponent {

    render() {
        /** @type {initState["basicInfo"]} */
        let state = this.props.state;
        return (
            
{state.isBoy == true ? "boy" : "girl"} {/* 正確 */} {state.isBoy ? "boy" : "girl"} {/* 錯(cuò)誤 */} {state.age != 0 ? "Not 0" : "0"} {/* 正確 */} {state.age ? "Not 0" : "0"} {/* 錯(cuò)誤 */}
) } }
了解 PureComponent

React 的 PureComponent 會(huì)在渲染前對(duì)新的 props / state 與老的 props / state 進(jìn)行淺層比較( shallow comparison),僅當(dāng)發(fā)現(xiàn) props / state 發(fā)生改變時(shí),才執(zhí)行重新渲染。淺層比較即是比較 props / state 的根級(jí)屬性值是否改變,如果屬性值是數(shù)組 / 對(duì)象類型,比較的結(jié)果使其引用是否相等:

console.log(["a"] == ["a"]) // 結(jié)果是 false

let a = ["a"]
console.log(a == a) // 結(jié)果是 true
console.log({a: "a"} == {a: "a"}) // 結(jié)果是 false

let a = {a: "a"} 
console.log(a == a) // 結(jié)果是 true

Pastate 符合 immutable data 規(guī)范的 state 數(shù)據(jù),可以確保當(dāng)某個(gè) state 節(jié)點(diǎn)改變時(shí),其祖先節(jié)點(diǎn)的引用都會(huì)進(jìn)行更新,所以可以配合使用 PureComponent 實(shí)現(xiàn)高效的按需渲染。

按需渲染時(shí)需要對(duì) state 的結(jié)構(gòu)進(jìn)行模塊化設(shè)計(jì),如果把所有的屬性都放在 state 根節(jié)點(diǎn)上,就沒法實(shí)現(xiàn)按需渲染了:

// 注意:這樣的 state 設(shè)計(jì)無法實(shí)現(xiàn)子組件的按需渲染
initState = {
     name: "Peter",
     isBoy: true,
     age: 10,
     country: "China",
     city: "Guangzhou"
}

當(dāng)然,只有當(dāng)應(yīng)用的 state 比較復(fù)雜且對(duì) state 的操作比較繁多時(shí)候,才會(huì)體現(xiàn)按需渲染對(duì)性能的提升;當(dāng)應(yīng)用比較簡(jiǎn)單的時(shí)候,不一定要對(duì) state 和視圖進(jìn)行太詳細(xì)的劃分。

子組件 state 的 intelliSense

同樣,我們可以使用 jsDoc 注釋讓子組件中 state 的具有智能提示,如下:

class BasicInfoView extends PureComponent {
    render(){
        /** @type {initState["basicInfo"]} */
        let state = this.props.state;
        ...
    }
}
class AddressView extends PureComponent {
    render(){
        /** @type {initState["address"]} */
        let state = this.props.state;
        ...
    }
}

請(qǐng)使用 xxx["xxx"] 的格式指明對(duì)象的子節(jié)點(diǎn): /** @type {initState["address"]} */。在 vs code 里,暫時(shí)無法使用 xxx.xxx 的嵌套格式指定一個(gè)變量的類型。

單實(shí)例子組件

如果某組件只在視圖中出現(xiàn)一次,那么這種組件被稱為單實(shí)例組件。這種組件可以把對(duì)子組件設(shè)計(jì)的 state 操作函數(shù)簡(jiǎn)單地封裝在子組件內(nèi)部,提高組件的內(nèi)聚性,便于維護(hù)管理。下面以 BasicInfoView 為例,把操作按鈕移入子組件,并把兩個(gè)操作函數(shù)移入子組件

...
class BasicInfoView extends PureComponent {

    increaseAge(){
        state.basicInfo.age += 1
    }
    
    decreaseAge(){
        state.basicInfo.age -= 1
    }

    render(){
        /** @type {initState["basicInfo"]} */
        let state = this.props.state;
        return (
            
...
) } } ...

同樣,你也可以對(duì) AddressView 做類似的處理。

下一章, 我們將會(huì)介紹如何在 pastate 中渲染和操作 state 中的數(shù)組。

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

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

相關(guān)文章

  • 教程Pastate.js 響應(yīng)框架(三)數(shù)組渲染與操作

    摘要:但是如果多實(shí)例組件的含義明顯不具有通用性,特別是用于顯示數(shù)組元素的情況下,使用這種模式會(huì)引發(fā)多余的渲染過程。假設(shè)我們還有數(shù)組,數(shù)組元素的格式與一樣我們要用相同的元素組件來同時(shí)顯示和操作這兩個(gè)數(shù)組時(shí),這種數(shù)組渲染模式就不適用了。 這是 Pastate.js 響應(yīng)式 react state 管理框架系列教程的第三章,歡迎關(guān)注,持續(xù)更新。 這一章我們來看看在 pastate 中如何渲染和處理...

    linkin 評(píng)論0 收藏0
  • Pastate.js : 響應(yīng) react state 管理框架

    摘要:簡(jiǎn)介是什么是一個(gè)響應(yīng)式管理框架,實(shí)現(xiàn)了對(duì)的異步響應(yīng)式管理。可靠性已經(jīng)通過個(gè)測(cè)試用例的全面測(cè)試,穩(wěn)定可靠。安裝是一個(gè)狀態(tài)管理框架,需要配合使用。 Pastate 簡(jiǎn)介 Pastate 是什么 Pastate 是一個(gè)響應(yīng)式 react state 管理框架,實(shí)現(xiàn)了對(duì) state 的異步響應(yīng)式管理。Pastate 是一個(gè)精益框架,它對(duì)很多高級(jí)概念進(jìn)行了友好封裝,這意味著你不必學(xué)習(xí)一些難以理解...

    jonh_felix 評(píng)論0 收藏0
  • Spring Boot 2 快速教程:WebFlux 快速入門(

    摘要:響應(yīng)式編程是基于異步和事件驅(qū)動(dòng)的非阻塞程序,只是垂直通過在內(nèi)啟動(dòng)少量線程擴(kuò)展,而不是水平通過集群擴(kuò)展。三特性常用的生產(chǎn)的特性如下響應(yīng)式編程模型適用性內(nèi)嵌容器組件還有對(duì)日志消息測(cè)試及擴(kuò)展等支持。 摘要: 原創(chuàng)出處 https://www.bysocket.com 「公眾號(hào):泥瓦匠BYSocket 」歡迎關(guān)注和轉(zhuǎn)載,保留摘要,謝謝! 02:WebFlux 快速入門實(shí)踐 文章工程: JDK...

    gaara 評(píng)論0 收藏0
  • 關(guān)于Vue2一些值得推薦的文章 -- 五、六月份

    摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長(zhǎng)安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...

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

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

0條評(píng)論

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