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

資訊專欄INFORMATION COLUMN

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

linkin / 955人閱讀

摘要:但是如果多實(shí)例組件的含義明顯不具有通用性,特別是用于顯示數(shù)組元素的情況下,使用這種模式會(huì)引發(fā)多余的渲染過(guò)程。假設(shè)我們還有數(shù)組,數(shù)組元素的格式與一樣我們要用相同的元素組件來(lái)同時(shí)顯示和操作這兩個(gè)數(shù)組時(shí),這種數(shù)組渲染模式就不適用了。

這是 Pastate.js 響應(yīng)式 react state 管理框架系列教程的第三章,歡迎關(guān)注,持續(xù)更新。

這一章我們來(lái)看看在 pastate 中如何渲染和處理 state 中的數(shù)組。

渲染數(shù)組

首先我們更新一下 state 的結(jié)構(gòu):

const initState = {
    basicInfo: ...,
    address: ...,
    pets: [{
        id:"id01",
        name: "Kitty",
        age: 2
    }]
}

我們定義了一個(gè)有對(duì)象元素構(gòu)成的數(shù)組 initState.pets, 且該數(shù)組有一個(gè)初始元素。

接著,我們定義相關(guān)組件來(lái)顯示 pets 的值:

class PetsView extends PureComponent {
    render() {
        /** @type {initState["pets"]} */
        let state = this.props.state;
        return (
            
My pets:
{state.map(pet => )}
) } }
class PetView extends PureComponent {
    render() {
        /** @type {initState["pets"][0]} */
        let state = this.props.state;
        return (
            
  • {state.name}: {state.age} years old.
  • ) } }

    這里定義了兩個(gè)組件,第一個(gè)是 PetsView,用來(lái)顯示 pets 數(shù)組; 第二個(gè)是 PetView,用來(lái)顯示 pet 元素。
    接下來(lái)把 PetsView 組件放入 AppView 組件中顯示:

    ...
    class AppView extends PureComponent {
        render() {
            /** @type {initState} */
            let state = this.props.state;
            return (
                
    ) } } ...

    完成!我們成功渲染了一個(gè)數(shù)組對(duì)象,這與用原生 react 渲染數(shù)組的模式一樣,頁(yè)面結(jié)果如下:

    修改數(shù)組

    首先,我們想添加或減少數(shù)組元素,這用 pasate 實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單。受 vue.js 啟發(fā),pastate 對(duì) store.state 的數(shù)組節(jié)點(diǎn)的以下7個(gè) 數(shù)組變異方法 都進(jìn)行了加強(qiáng),你可以直接調(diào)用這些數(shù)組函數(shù),pastate 會(huì)自動(dòng)觸發(fā)視圖的更新。這 7 個(gè)數(shù)組變異方法如下

    push()

    pop()

    shift()

    unshift()

    splice()

    sort()

    reverse()

    我們來(lái)嘗試使用 push 和 pop 來(lái)更新數(shù)組:

    class PetsView extends PureComponent {
    
        pushPet(){
            state.pets.push({
                id: Date.now() + "",
                name: "Puppy",
                age: 1
            })
        }
    
        popPet(){
            state.pets.pop()
        }
    
        render() {
            /** @type {initState["pets"]} */
            let state = this.props.state;
            return (
                
    My pets:
    {state.map(pet => )}
    ) } }

    非常容易!我們還添加了兩個(gè)按鈕并指定了點(diǎn)擊處理函數(shù),運(yùn)行體驗(yàn)一下:

    打開(kāi) react dev tools 的 Highlight Updates 選項(xiàng),并點(diǎn)擊 push 或 pop 按鈕,可以觀察到視圖更新情況如我們所愿:

    空初始數(shù)組與編輯器 intelliSence

    通常情況下,數(shù)組節(jié)點(diǎn)的初始值是空的。為了實(shí)現(xiàn)編輯器 intelliSence, 我們可以在外面定義一個(gè)元素類型,并注釋這個(gè)數(shù)組節(jié)點(diǎn)的元素為該類型:

    const initState = {
        ...
        /** @type {[pet]} */
        pets: []
    }
    const pet = {
        id: "id01",
        name: "Kitty",
        age: 2
    }

    你也可以使用泛型的格式來(lái)定義數(shù)組類型: /** @type {Array} */

    多實(shí)例組件的內(nèi)部動(dòng)作處理

    上一章我們提到了單實(shí)例組件,是指組件只被使用一次;而我們可以到 PetView 被用于顯示數(shù)組元素,會(huì)被多次使用。我們把這類在多處被使用的組件稱為多實(shí)例組件。多實(shí)例組件內(nèi)部動(dòng)作的處理邏輯由組件實(shí)例的具體位置而定,與單實(shí)例組件的處理模式有差別,我們來(lái)看看。

    我們?cè)囍谱饕粋€(gè)每個(gè)寵物視圖中添加兩個(gè)按鈕來(lái)調(diào)整寵物的年齡,我們用兩種傳統(tǒng)方案和pastate方案分別實(shí)現(xiàn):

    react 傳統(tǒng)方案 傳統(tǒng)方案1:父組件處理

    父組件向子組件傳遞綁定index的處理函數(shù):這種模式是把子組件的動(dòng)作處理邏輯實(shí)現(xiàn)在父組件中,然后父組件把動(dòng)作綁定對(duì)應(yīng)的 index 后傳遞給子組件

    class PetsView extends PureComponent {
        ...
        addAge(index){
            state.pets[index].age += 1
        }
        reduceAge(index){
            state.pets[index].age -= 1
        }
        render() {
            /** @type {initState["pets"]} */
            let state = this.props.state;
            return (
                
    ... { state.map((pet, index) => this.addAge(index)} // 綁定 index 值,傳遞給子組件 reduceAge={() => this.reduceAge(index)} // 綁定 index 值,傳遞給子組件 />) } ...
    ) } }
    class PetView extends PureComponent {
        render() {
            /** @type {initState["pets"][0]} */
            let state = this.props.state;
            return (
                
  • {state.name}: {/* 使用已綁定 index 值得動(dòng)作處理函數(shù) */} {state.age} {/* 使用已綁定 index 值得動(dòng)作處理函數(shù) */} years old.
  • ) } }

    這種模式可以把動(dòng)作的處理統(tǒng)一在一個(gè)組件層級(jí),如果多實(shí)例組件的視圖含義不明確、具有通用性,如自己封裝的 Button 組件等,使用這種動(dòng)作處理模式是最好的。但是如果多實(shí)例組件的含義明顯、不具有通用性,特別是用于顯示數(shù)組元素的情況下,使用這種模式會(huì)引發(fā)多余的渲染過(guò)程。

    打開(kāi) react dev tools 的 Highlight Updates 選項(xiàng),點(diǎn)擊幾次 push pet 增加一些元素后,再點(diǎn)擊 +- 按鈕看看組件重新渲染的情況:

    可以發(fā)現(xiàn)當(dāng)我們只修改某一個(gè)數(shù)組元素內(nèi)部的值(pet[x].age)時(shí),其他數(shù)組元素也會(huì)被重新渲染。這是因?yàn)?Pet.props.addAge 和 Pet.props.reduceAge 是每次父組件 PetsView 渲染時(shí)都會(huì)重新生成的匿名對(duì)象,PureComponent 以此認(rèn)為組件依賴的數(shù)據(jù)更新了,所以觸發(fā)重新渲染。雖然使用 React.Component 配合 自定義的 shouldComponentUpdate 生命周期函數(shù)可以手動(dòng)解決這個(gè)問(wèn)題,但是每次渲染父組件 PetsView 時(shí)都重新生成一次匿名子組件屬性值,也在消耗運(yùn)算資源。

    傳統(tǒng)方案2:子組件結(jié)合 index 實(shí)現(xiàn)

    父組件向子組件傳遞 index 值:這種模式是父組件向子組件傳遞 index 值,并在子組件內(nèi)部實(shí)現(xiàn)自身的事件處理邏輯,如下:

    class PetsView extends PureComponent {
        ...
        render() {
            ...
            return (
                
    ... { state.map((pet, index) => ) } ...
    ) } }
    class PetView extends PureComponent {
    
        // 在子組件實(shí)現(xiàn)動(dòng)作邏輯
    
        // 調(diào)用時(shí)傳遞 index
        addAge(index){
            state.pets[index].age += 1
        }
    
        // 或函數(shù)自行從 props 獲取 index
        reduceAge = () => { // 函數(shù)內(nèi)部使用到 this 對(duì)象,使用 xxx = () => {...} 來(lái)定義組件屬性更方便
            state.pets[this.props.index].age -= 1
        }
    
        render() {
            /** @type {initState["pets"][0]} */
            let state = this.props.state;
            let index = this.props.index;
            return (
                
  • {state.name}: {/* 使用閉包傳遞 index 值 */} {state.age} {/* 或讓函數(shù)實(shí)現(xiàn)自己去獲取index值 */} years old.
  • ) } }

    這種模式可以使子組件獲取 index 并處理自身的動(dòng)作邏輯,而且子組件也可以把自身所在的序號(hào)顯示出來(lái),具有較強(qiáng)的靈活性。我們?cè)賮?lái)看看其當(dāng)元素內(nèi)部 state 改變時(shí),組件的重新渲染情況:

    我們發(fā)現(xiàn),數(shù)組元素組件可以很好地按需渲染,在渲染數(shù)組元素的情況下這種方法具有較高的運(yùn)行效率。

    但是,由于元素組件內(nèi)部操作函數(shù)綁定了唯一位置的 state 操作邏輯,如addAge(index){ state.pets[index].age += 1}。假設(shè)我們還有 state.children 數(shù)組,數(shù)組元素的格式與 state.pets 一樣, 我們要用相同的元素組件來(lái)同時(shí)顯示和操作這兩個(gè)數(shù)組時(shí),這種數(shù)組渲染模式就不適用了。我們可以用第1種方案實(shí)現(xiàn)這種情況的需求,但第1種方案在渲染效率上不是很完美。

    pastate 數(shù)組元素操作方案

    Pastate 的 imState 的每個(gè)節(jié)點(diǎn)本身帶有節(jié)點(diǎn)位置的信息和 store 歸宿信息,我們可以利用這一點(diǎn)來(lái)操作數(shù)組元素!

    pastate 方案1:獲取對(duì)于的響應(yīng)式節(jié)點(diǎn)

    我們使用 getResponsiveState 函數(shù)獲取 imState 對(duì)于的響應(yīng)式 state,如下:

    class PetsView extends PureComponent {
        ...
        render() {
            ...
            return (
                
    ... { state.map((pet, index) => ) } ...
    ) } }
    import {..., getResponsiveState } from "pastate"
    
    class PetView extends PureComponent {
        addAge = () => {
            /** @type {initState["pets"][0]} */
            let pet = getResponsiveState(this.props.state); // 使用 getResponsiveState 獲取響應(yīng)式 state 節(jié)點(diǎn)
            pet.age += 1
        }
        reduceAge = () => {
            /** @type {initState["pets"][0]} */
            let pet = getResponsiveState(this.props.state); // 使用 getResponsiveState 獲取響應(yīng)式 state 節(jié)點(diǎn)
            pet.age -= 1
        }
        render() {
            /** @type {initState["pets"][0]} */
            let state = this.props.state;
            return (
                
  • {state.name}: {state.age} years old.
  • ) } }

    我們可以看到,子組件通過(guò) getResponsiveState 獲取到當(dāng)前的 props.state 對(duì)應(yīng)的響應(yīng)式 state,從而可以直接對(duì) state 進(jìn)行復(fù)制修改,你無(wú)需知道 props.state 究竟在 store.state 的什么節(jié)點(diǎn)上! 這種模式使得復(fù)用組件可以在多個(gè)不同掛載位置的數(shù)組中使用,而且可以保證很好的渲染性能:

    pastate 方案2:使用 imState 操作函數(shù)

    Pastate 提供個(gè)三個(gè)直接操作 imState 的函數(shù),分別為 set, merge, update。我們來(lái)演示用這些操作函數(shù)來(lái)代替 getResponsiveState 實(shí)現(xiàn)上面操作寵物年齡的功能:

    import {..., set, merge, update } from "pastate"
    
    class PetView extends PureComponent {
        addAge = () => {
            set(this.props.state.age, this.props.state.age + 1); 
        }
        reduceAge = () => {
            merge(this.props.state, {
                age: this.props.state.age - 1
            });
        }
        reduceAge_1 = () => {
            update(this.props.state.age, a => a - 1);
        }
        ...
    }

    可見(jiàn),這種 imState 操作函數(shù)的模式也非常簡(jiǎn)單!

    使用 pastate 數(shù)組元素操作方案的注意事項(xiàng):當(dāng)操作的 state 節(jié)點(diǎn)的值為 null 或 undefined 時(shí), 只能使用 merge 函數(shù)把新值 merge 到父節(jié)點(diǎn)中,不可以使用 getResponsiveStatesetupdate。我們?cè)谠O(shè)計(jì) state 結(jié)構(gòu)時(shí),應(yīng)盡量避免使用絕對(duì)空值,我們完全可以用 "", [] 等代替絕對(duì)空值。

    下一章,我們來(lái)看看如何在 pastate 中渲染和處理表單元素。

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

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

    相關(guān)文章

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

      摘要:這一章,我們?cè)谏弦徽碌慕Y(jié)構(gòu)中添加多一些信息,并用多個(gè)組件來(lái)組織應(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è)組件來(lái)組織 pastate 應(yīng)用。 更新 state 結(jié)構(gòu) 我們把上一章...

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

      摘要:簡(jiǎn)介是什么是一個(gè)響應(yīng)式管理框架,實(shí)現(xiàn)了對(duì)的異步響應(yīng)式管理。可靠性已經(jīng)通過(guò)個(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
    • 實(shí)例講解基于 React+Redux 的前端開(kāi)發(fā)流程

      摘要:宅印前端基于的模式開(kāi)發(fā),我們指定了一套分工明確的并行開(kāi)發(fā)流程。下面通過(guò)一個(gè)蘋果籃子實(shí)例,來(lái)看看整個(gè)應(yīng)用開(kāi)發(fā)流程。容器負(fù)責(zé)接收中的和并發(fā)送大多數(shù)時(shí)候需要和直接連接,容器一般不需要多次使用,比如我們這個(gè)應(yīng)用的蘋果籃子。 前言:在當(dāng)下的前端界,react 和 redux 發(fā)展得如火如荼,react 在 github 的 star 數(shù)達(dá) 42000 +,超過(guò)了 jquery 的 39000+,...

      chaosx110 評(píng)論0 收藏0
    • 校招社招必備核心前端面試問(wèn)題詳細(xì)解答

      摘要:本文總結(jié)了前端老司機(jī)經(jīng)常問(wèn)題的一些問(wèn)題并結(jié)合個(gè)人總結(jié)給出了比較詳盡的答案。網(wǎng)易阿里騰訊校招社招必備知識(shí)點(diǎn)。此外還有網(wǎng)絡(luò)線程,定時(shí)器任務(wù)線程,文件系統(tǒng)處理線程等等。線程核心是引擎。主線程和工作線程之間的通知機(jī)制叫做事件循環(huán)。 showImg(https://segmentfault.com/img/bVbu4aB?w=300&h=208); 本文總結(jié)了前端老司機(jī)經(jīng)常問(wèn)題的一些問(wèn)題并結(jié)合個(gè)...

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

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

    0條評(píng)論

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