W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
React讓你可以使用任何你想要的數(shù)據(jù)管理風(fēng)格,包括數(shù)據(jù)可變風(fēng)格。然而,如果你能夠在你應(yīng)用中講究性能的部分使用不可變數(shù)據(jù),就可以很方便地實(shí)現(xiàn)一個(gè)快速的shouldComponentUpdate()
方法來(lái)顯著提升你應(yīng)用的速度。
在JavaScript中處理不可變數(shù)據(jù)比在語(yǔ)言層面上就設(shè)計(jì)好要難,像 Clojure。但是,我們提供了一個(gè)簡(jiǎn)單的不可變輔助工具,update()
,這就讓處理這種類型的數(shù)據(jù)更加簡(jiǎn)單了,根本不會(huì)改變你數(shù)據(jù)的表示的形式。(Dealing with immutable data in JavaScript is more difficult than in languages designed for it, like Clojure. However, we've provided a simple immutability helper, update()
, that makes dealing with this type of data much easier, without fundamentally changing how your data is represented.)
如果你像這樣改變數(shù)據(jù):
myData.x.y.z = 7;// or... myData.a.b.push(9);
你無(wú)法確定哪個(gè)數(shù)據(jù)改變了,因?yàn)橹暗母北颈桓采w了。相反,你需要?jiǎng)?chuàng)建一個(gè)新的myDate
副本,僅僅改變需要改變的部分。然后你就能夠在shouldComponentUpdate()
中使用第三方的相等判斷來(lái)比較myData
的舊副本和新對(duì)象:
var newData = deepCopy(myData); newData.x.y.z = 7; newData.a.b.push(9);
不幸的是,深拷貝是很昂貴的,而且某些時(shí)候還不可能完成。你可以通過(guò)僅拷貝需要改變的對(duì)象,重用未改變的對(duì)象來(lái)緩解這個(gè)問(wèn)題。不幸的是,在當(dāng)今的JavaScript里面,這會(huì)變得很笨拙:
var newData = extend(myData, { x: extend(myData.x, { y: extend(myData.x.y, {z: 7}), }), a: extend(myData.a, {b: myData.a.b.concat(9)}) });
雖然這能夠非常好地提升性能(因?yàn)閮H僅淺復(fù)制log n
個(gè)對(duì)象,重用余下的),但是寫起來(lái)很痛苦??纯此械闹貜?fù)書(shū)寫!這不僅僅是惱人,也提供了一個(gè)巨大的出bug的區(qū)域。
update()
在這種情形下提供了簡(jiǎn)單的語(yǔ)法糖,使得寫這種代碼變得更加簡(jiǎn)單。代碼變?yōu)椋?/p>
var newData = React.addons.update(myData, { x: {y: {z: {$set: 7}}}, a: {b: {$push: [9]}} });
雖然這種語(yǔ)法糖需要花點(diǎn)精力適應(yīng)(盡管這是受MongoDB's query language的啟發(fā)),但是它沒(méi)有冗余,是靜態(tài)可分析的,并且比可變的版本少打了很多字。(While the syntax takes a little getting used to (though it's inspired by MongoDB's query language) there's no redundancy, it's statically analyzable and it's not much more typing than the mutative version.)
以$
為前綴的鍵被稱作命令。他們“改變”的數(shù)據(jù)結(jié)構(gòu)被稱為目標(biāo)。( The $
-prefixed keys are called commands. The data structure they are "mutating" is called the target.)
{$push: array}
利用push()
把目標(biāo)上所有的元素放進(jìn)數(shù)組
(push()
all the items in array
on the target.)。
{$unshift: array}
利用unshift()
把目標(biāo)上所有的元素放進(jìn)數(shù)組
(unshift()
all the items in array
on the target.)。
{$splice: array of arrays}
對(duì)于array
中的每一個(gè)元素,用元素提供的參數(shù)在目標(biāo)上調(diào)用splice()
(for each item in arrays
call splice()
on the target with the parameters provided by the item.)。
{$set: any}
整體替換目標(biāo)(replace the target entirely.)。
{$merge: object}
合并目標(biāo)和object
的鍵。
{$apply: function}
傳入當(dāng)前的值到函數(shù),然后用新返回的值更新它(passes in the current value to the function and updates it with the new returned value.)。
var initialArray = [1, 2, 3];var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]
initialArray
仍然是[1, 2, 3]
。
var collection = [1, 2, {a: [12, 17, 15]}];var newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}});// => [1, 2, {a: [12, 13, 14, 15]}]
獲取collection
中索引是2
的對(duì)象,然后取得該對(duì)象鍵為a
的值,刪掉索引從1
開(kāi)始的一個(gè)元素(即移除17
),插入13
和14
。(This accesses collection
's index 2
, key a
, and does a splice of one item starting from index 1
(to remove 17
) while inserting 13
and 14
.)
var obj = {a: 5, b: 3};var newObj = update(obj, {b: {$apply: function(x) {return x * 2;}}});// => {a: 5, b: 6}// This is equivalent, but gets verbose for deeply nested collections:var newObj2 = update(obj, {b: {$set: obj.b * 2}});
var obj = {a: 5, b: 3};var newObj = update(obj, {$merge: {b: 6, c: 7}}); // => {a: 5, b: 6, c: 7}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: