您好,登錄后才能下訂單哦!
DOM操作
操作底層DOM的使用場(chǎng)景:當(dāng)需要與一個(gè)沒(méi)有使用React的第三方類(lèi)庫(kù)進(jìn)行整合,或執(zhí)行一個(gè)React沒(méi)有原生支持的操作時(shí)。
訪問(wèn)受控的DOM節(jié)點(diǎn):
想要訪問(wèn)受React控制的DOM節(jié)點(diǎn),首先必須能夠訪問(wèn)到負(fù)責(zé)控制這些DOM的組件。這可以通過(guò)為子組件添加一個(gè)ref屬性來(lái)實(shí)現(xiàn)。
eg:
var DoodleArea = React.createClass({
render: function () {
return <canvas ref="mainCanvas"/>;
}
});
這樣可以通過(guò)this.refs.mainCanvas訪問(wèn)到<canvas>組件。同時(shí)必須保證每個(gè)子組件的ref值在所有子組件中是唯一的,如果有兩個(gè)子組件ref值相同則操作將失效。
一旦通過(guò)this.refs.mainCanvas訪問(wèn)到canvas子組件,就可以通過(guò)它的getDOMNode()方法訪問(wèn)到底層的DOM節(jié)點(diǎn)。但不能在render方法中調(diào)用getDOMNode()。因?yàn)閞ender方法完成并且React執(zhí)行更新之前,底層的DOM節(jié)點(diǎn)可能不是最新的(甚至尚未創(chuàng)建)。直到組件被掛載才能調(diào)用getDOMNode()方法,即componentDidMount事件處理器被觸發(fā)時(shí)。
注意:componentDidMount內(nèi)部并不是getDOMNode()方法的唯一執(zhí)行環(huán)境,事件處理器也可以在組件掛載后觸發(fā),所以也可以在事件處理器中調(diào)用getDOMNode().
使用this.refs.getDOMNode()方法會(huì)對(duì)React產(chǎn)生性能上的障礙,只有在沒(méi)有其他方法能夠?qū)崿F(xiàn)需要的功能時(shí)才能考慮使用。
整合非React類(lèi)庫(kù):
沒(méi)有使用React構(gòu)建的JavaScript類(lèi)庫(kù),一些類(lèi)庫(kù)不需要使用DOM,如果要使用它們,保持狀態(tài)和React的狀態(tài)之間的同步是成功整合的關(guān)鍵。
eg:autocomplelte類(lèi)庫(kù):
autocomplete({
target: document.getElementById("cities"),
data: [
"San Francisco",
"St. Louis",
"Amsterdam",
"Los Angeles"
],
events: {
select: function (city) {
alert("You have selected the city of " + city);
}
}
});
該autocomplete函數(shù)需要一個(gè)目標(biāo)DOM節(jié)點(diǎn)、一個(gè)用作數(shù)據(jù)展現(xiàn)的字符串清單,以及一些時(shí)間監(jiān)聽(tīng)器
使用該類(lèi)庫(kù)的React組件:
var AutocompleteCities = React.createClass({
render: function () {
/*/DOM節(jié)點(diǎn)*/
return <div id="cities" ref="autocompleteTarget"/>
},
getDefaultProps: function () {
return {
/*字符串清單*/
data: [
"San Francisco",
"St. Louis",
"Amsterdam",
"Los Angeles"
]
};
},
/* 事件監(jiān)聽(tīng)器*/
handleSelect: function (city) {
alert("You have selected the city of " + city);
},
componentDidMount: function () {
autocomplete({
target: this.refs.autocompleteTarget.getDOMNode(),
data: this.props.data,
events: {
select: this.handleSelect
}
});
}
});
componentDidMount方法只會(huì)為每個(gè)節(jié)點(diǎn)調(diào)用一次。因此我們不用擔(dān)心在一個(gè)節(jié)點(diǎn)上兩次調(diào)用autocomplete方法產(chǎn)生的影響。
也就是說(shuō)該組件可能被移除,然后在其他DOM節(jié)點(diǎn)上重新渲染,如果在componentDidMount方法內(nèi)導(dǎo)致了DOM節(jié)點(diǎn)無(wú)法被移除,有可能導(dǎo)致內(nèi)存泄漏或者其他問(wèn)題。為確保此現(xiàn)象的發(fā)生,可以指定一個(gè)componentWillUnmount監(jiān)聽(tīng)器,用于在組件的DOM節(jié)點(diǎn)移除時(shí)清理自身。
侵入式插件:
修改除了自己子元素以外的依附元素(如父元素)的插件。
面對(duì)這類(lèi)侵入式插件,保護(hù)好React的最好方式就是把DOM操控權(quán)完全交給我們自己。在componentDidMount方法中做一些初始化工作。這里也需要去完成清理工作。
還需要進(jìn)行處理更新??赏ㄟ^(guò)兩種方式觸發(fā):
-- 模擬卸載器而后重新掛載(更高效)
eg:
componentDidUpdate: function () {
this.componentWillUnmount();
this.componentDidMount();
}
-- 使用插件的更新操作API(更有效、清晰)
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。