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

資訊專欄INFORMATION COLUMN

React 數(shù)據(jù)為什么要使用immutable方式?淺復(fù)制與深復(fù)制思考

Gu_Yan / 3303人閱讀

摘要:深復(fù)制與淺復(fù)制淺復(fù)制同樣的方式深復(fù)制因?yàn)榇鎯?chǔ)對(duì)象都是存地址的,所以淺復(fù)制會(huì)導(dǎo)致和指向同一塊內(nèi)存地址,大概的示意圖如下。

深復(fù)制與淺復(fù)制
let obj = {
    a: 1,
    arr: [1, 2]
};
let obj1 = obj;            //淺復(fù)制
obj1.a = 2

console.log(obj) // { a:2, arr: [1,2] };

//同樣的方式
let obj = {
    a: 1,
    arr: [1, 2]
};
let obj2 = deepCopy(obj);  //深復(fù)制
obj2.a = 2
console.log(obj) // { a:1, arr: [1,2] };

因?yàn)镴avaScript存儲(chǔ)對(duì)象都是存地址的,所以淺復(fù)制會(huì)導(dǎo)致 obj 和 obj1
指向同一塊內(nèi)存地址,大概的示意圖如下。而深復(fù)制一般都是開辟一塊新的內(nèi)存地址,將原對(duì)象的各個(gè)屬性逐個(gè)復(fù)制出去。

es6-Object.assign()方法

深復(fù)制只有一層,之后為淺復(fù)制(除非再次使用Object.assign嵌套方式賦值)

let obj = {
    a: 1,
    arr: [1, 2]
};
let obj1 = Object.assign({}, obj);

obj1.a = 2
//不變
console.log(obj) // { a:1, arr: [1,2] };



let obj = {
    a: {
        b: 20
    },
    arr: [1, 2]
};
let obj1 = Object.assign({}, obj);

obj1.a.b = 2;
//除非再次使用Object.assign嵌套方式賦值
//變化
console.log(obj) // { a:{b:2}, arr: [1,2] };
為什么使用不可變(immutable)的數(shù)據(jù)? (pureRender結(jié)合immutable,見末尾)
下面是項(xiàng)目中實(shí)際的一個(gè)例子

第一種方式

//recduer.js(cart)第一種方式
case types.CART_PUT_MAIN + "_SUCCESS":
    //更新數(shù)據(jù)
    carts = state.main.carts; // carts 選中的id數(shù)組
    id = action.param.id;
    newState = {
        ...state,
        main:{
            ...state.main,
            itemObj:{
                ...state.main.itemObj,
                [id]:{
                    ...state.main.itemObj[id],
                    quantity:action.param.quantity
                    
                }
            }
        }
    };
    sum = sumCommon(carts, newState.main.itemObj);
    newState = {
        ...newState,
        main:{
            ...newState.main,
            ...sum
        }
    };
    return newState;

讓我們來看一下對(duì)數(shù)據(jù)層的變化:

componentWillReceiveProps(nextProps){
    console.log(nextProps); 
    //next:顧名思義是接收到的next->props,輸出的是上面方法中的newState的值
    console.log(this.props);
    //cur:是當(dāng)前的props的值,因?yàn)槭褂玫氖穷恑mmutable的方式,所以數(shù)據(jù)不變;
}

第二種方式

//recduer.js(cart)第一種方式
case types.CART_PUT_MAIN + "_SUCCESS":
    newState = Object.assign({}, state);
    carts = newState.main.carts; // carts 選中的id數(shù)組
    id = action.param.id;
    //淺復(fù)制
    newState.main.itemObj[id].quantity = action.param.quantity;;
    sum = sumCommon(carts, newState.main.itemObj);

    newState = Object.assign({}, newState, {
        main: Object.assign({}, newState.main, sum)
    });
    return newState;

讓我們來再來看一下對(duì)數(shù)據(jù)層的變化:

componentWillReceiveProps(nextProps){
    console.log(nextProps); 
    //next:顧名思義是接收到的next->props,輸出的是上面方法中的newState的值
    console.log(this.props);
    //cur:是當(dāng)前的props的值,而這個(gè)由于淺復(fù)制,這個(gè)值被改變了
}

為了讓數(shù)據(jù)變化更加可測(cè),我們應(yīng)當(dāng)使用深復(fù)制相關(guān),讓我們自己的數(shù)據(jù)更加安全

處理方法一:es7 ... 的方式

直接{...obj}賦值屬于淺復(fù)制,在修改值時(shí){...obj,a:1}就起到了類深復(fù)制的效果
更新一個(gè) Object ,則:

let obj = {
    a: 0,
    b: 20,
}
obj = {...obj, a: obj.a + 1}

而不是:

obj.a = obj.a + 1

同樣的為了避免對(duì) Object 的 in-place editing,數(shù)組也是一樣:

let arr = [
    { id: 1,a: 1}
]
arr = [...arr, { id: 2,a: 2} ]

而不是:

let arr = [
    { id: 1, a:1}
]
arr.push({ id: 2, a,2});

以這樣的方式,無需 Immutable.js ,我們可以讓應(yīng)用程序狀態(tài)是 不可變(Immutable) 的。

...注意事項(xiàng)及要求
let obj = {
    a: 20,
    arr: [1, 2]
};
let obj1 = { ...obj }; //于obj1=obj一樣
// 保持統(tǒng)一,盡量不要使用這樣的替換(有可能造成不必要的麻煩)
obj1.a = 2
//...盡量使用這樣的賦值形式
obj1 = { ...obj1 , a:2 }
//深復(fù)制
console.log(obj) // { a:20, arr: [1,2] };
console.log(obj1) // { a:2, arr: [1,2] };

...與Object.assign屬于一個(gè)道理(這里和層級(jí)相關(guān))

//你可以將其轉(zhuǎn)化為
let obj = {
    a: {
        b: 20
    },
    arr: [1, 2]
};
let obj1 = obj
obj1 = Object.assign({}, obj1, {
    a: Object.assign({}, obj1.a,{b:2})
});
console.log(obj) //{ a:{b:20}, arr: [1,2] }
console.log(obj) //{ a:{b:2}, arr: [1,2] }

所以盡量使用...代替Object.assign
處理方法二:使用immutable.js
為什么需要使用immutable.js

之前方式的多層嵌套

//深復(fù)制(類immutable)
newState = {
    ...state,
    main:{
        ...state.main,
        itemObj:{
            ...state.main.itemObj,
            [id]:{
                ...state.main.itemObj[id],
                prop:action.param.props_str,
                product_id:action.param.product_id,
                price:action.param.price
            }
        }
    }
};
//淺復(fù)制
newState.main.itemObj[id].prop = action.param.props_str;
//immutable.js方式
...參考immutable的api吧,暫時(shí)就不提供了--!
PureRenderMixin使用請(qǐng)參考以下內(nèi)容

簡(jiǎn)單的說就是數(shù)據(jù)變化,比較前后兩次的數(shù)據(jù)是否相同,判斷是否重新render;否則你的父容器一改變數(shù)據(jù),所有的子組件都重新渲染了,為了增加性能請(qǐng)使用pureRender;

Immutable.js及在React中的應(yīng)用

Immutable 詳解及 React 中實(shí)踐

Immutable as React state

(封裝好的PureRender如下:)

"use strict";

import { is } from "immutable";

let hasOwnProperty = Object.prototype.hasOwnProperty;
function shallowEqual(objA, objB) {
    if (objA === objB || is(objA, objB)) {
        return true;
    }

    if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
        return false;
    }

    let keysA = Object.keys(objA);
    let keysB = Object.keys(objB);

    if (keysA.length !== keysB.length) {
        return false;
    }
    let bHasOwnProperty = hasOwnProperty.bind(objB);
    for (let i = 0; i < keysA.length; i++) {
        if (!bHasOwnProperty(keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
            return false;
        }
    }

    return true;
}
function shallowCompare(instance, nextProps, nextState) {
    return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState);
}
function shouldComponentUpdate(nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
}
function pureRenderDecorator(component) {
    component.prototype.shouldComponentUpdate = shouldComponentUpdate;
}
module.exports = pureRenderDecorator;

/*使用方式*/
import pureRender from "pure-render-decorator";
//babel配置中引入一個(gè)transform-decorators-legacy插件
@pureRender
class XXX extends React.Component {
    //...
}

PureRender的使用要求:對(duì)于子組件需要什么參數(shù)傳遞什么,不要把一大塊無用的數(shù)據(jù)引入,否則兩次傳入的this.props可能始終會(huì)不一樣,導(dǎo)致PureRender無效

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

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

相關(guān)文章

  • React系列之 Immutable

    摘要:原文地址什么是是指一旦被創(chuàng)建就不可以被改變的數(shù)據(jù),通過使用不可變數(shù)據(jù)可以讓我們很方便的去處理數(shù)據(jù)的狀態(tài)變化檢測(cè)等問題,而且讓我們的程序變得更加的可預(yù)見怎么用大體使用深度轉(zhuǎn)換和為和淺轉(zhuǎn)換給倒數(shù)第一個(gè)賦值更多可以查看這里為什么要用其實(shí)從上面 原文地址:https://gmiam.com/post/react-... 什么是 Immutable Data ? Immutable Data 是...

    cc17 評(píng)論0 收藏0
  • React 的性能優(yōu)化(一)當(dāng) PureComponent 遇上 ImmutableJS

    摘要:四是在年出的持久性數(shù)據(jù)結(jié)構(gòu)的庫(kù),持久性指的是數(shù)據(jù)一旦創(chuàng)建,就不能再被更改,任何修改或添加刪除操作都會(huì)返回一個(gè)新的對(duì)象。避免大量使用操作,這樣會(huì)浪費(fèi)性能。盡量將設(shè)計(jì)成扁平狀的。 一、痛點(diǎn) 在我們的印象中,React 好像就意味著組件化、高性能,我們永遠(yuǎn)只需要關(guān)心數(shù)據(jù)整體,兩次數(shù)據(jù)之間的 UI 如何變化,則完全交給 React Virtual Dom 的 Diff 算法 去做。以至于我們很...

    plus2047 評(píng)論0 收藏0
  • JavaScript中的拷貝與深拷貝

    摘要:所以,深拷貝是對(duì)對(duì)象以及對(duì)象的所有子對(duì)象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對(duì)于深拷貝的對(duì)象,改變?cè)磳?duì)象不會(huì)對(duì)得到的對(duì)象有影響。 上一篇 JavaScript中的繼承 前言 文章開始之前,讓我們先思考一下這幾個(gè)問題: 為什么會(huì)有淺拷貝與深拷貝 什么是淺拷貝與深拷貝 如何實(shí)現(xiàn)淺拷貝與深拷貝 好了,問題出來了,那么下面就讓我們帶著這幾個(gè)問題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處...

    AZmake 評(píng)論0 收藏0
  • React組件性能優(yōu)化:PureRender和Immutable Data

    摘要:插件允許我們?cè)诘恼Z(yǔ)法中使用在傳遞數(shù)據(jù)時(shí),可以通過進(jìn)一步提升組件的渲染性能,是針對(duì)可變對(duì)象和不可變對(duì)象所做的折衷。使用之后,僅僅改變狀態(tài)了的組件及其父組件被重新渲染。 1 前言 網(wǎng)頁(yè)性能最大的限制因素是瀏覽器重繪(reflow)和重排版(repaint),React的虛擬DOM就是為了盡可能減少瀏覽器的重繪和重排版,從React的渲染過程看,避免不必要的渲染可以進(jìn)一步提高性能。 2 Pu...

    megatron 評(píng)論0 收藏0
  • JavaScript中的拷貝與深拷貝

    摘要:所以,深拷貝是對(duì)對(duì)象以及對(duì)象的所有子對(duì)象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對(duì)于深拷貝的對(duì)象,改變?cè)磳?duì)象不會(huì)對(duì)得到的對(duì)象有影響。 為什么會(huì)有淺拷貝與深拷貝什么是淺拷貝與深拷貝如何實(shí)現(xiàn)淺拷貝與深拷貝好了,問題出來了,那么下面就讓我們帶著這幾個(gè)問題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處,還請(qǐng)看到的小伙伴多多指教,先行謝過 以下↓ 數(shù)據(jù)類型在開始了解 淺拷貝 與 深拷貝 之前,讓我們先...

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

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

0條評(píng)論

閱讀需要支付1元查看
<