1. 程式人生 > >React基本概念(三)

React基本概念(三)

react

DOM操作

操作底層DOM的使用場景:當需要與一個沒有使用React的第三方類庫進行整合,或執行一個React沒有原生支持的操作時。


訪問受控的DOM節點:

想要訪問受React控制的DOM節點,首先必須能夠訪問到負責控制這些DOM的組件。這可以通過為子組件添加一個ref屬性來實現。

eg:

var DoodleArea = React.createClass({

render: function () {

return <canvas ref="mainCanvas"

/>;

}

});

這樣可以通過this.refs.mainCanvas訪問到<canvas>組件。同時必須保證每個子組件的ref值在所有子組件中是唯一的,如果有兩個子組件ref值相同則操作將失效。

一旦通過this.refs.mainCanvas訪問到canvas子組件,就可以通過它的getDOMNode()方法訪問到底層的DOM節點。但不能在render方法中調用getDOMNode()。因為render方法完成並且React執行更新之前,底層的DOM節點可能不是最新的(甚至尚未創建)。直到組件被掛載才能調用getDOMNode()方法,即componentDidMount事件處理器被觸發時。

註意:componentDidMount內部並不是getDOMNode()方法的唯一執行環境,事件處理器也可以在組件掛載後觸發,所以也可以在事件處理器中調用getDOMNode().

使用this.refs.getDOMNode()方法會對React產生性能上的障礙,只有在沒有其他方法能夠實現需要的功能時才能考慮使用。


整合非React類庫:

沒有使用React構建的JavaScript類庫,一些類庫不需要使用DOM,如果要使用它們,保持狀態和React的狀態之間的同步是成功整合的關鍵。

eg:autocomplelte類庫:

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函數需要一個目標DOM節點、一個用作數據展現的字符串清單,以及一些時間監聽器

使用該類庫的React組件:

var AutocompleteCities = React.createClass({

render: function () {

/*/DOM節點*/

return <div id="cities" ref="autocompleteTarget"/>

},

getDefaultProps: function () {

return {

/*字符串清單*/

data: [

"San Francisco",

"St. Louis",

"Amsterdam",

"Los Angeles"

]

};

},

/* 事件監聽器*/

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方法只會為每個節點調用一次。因此我們不用擔心在一個節點上兩次調用autocomplete方法產生的影響。

也就是說該組件可能被移除,然後在其他DOM節點上重新渲染,如果在componentDidMount方法內導致了DOM節點無法被移除,有可能導致內存泄漏或者其他問題。為確保此現象的發生,可以指定一個componentWillUnmount監聽器,用於在組件的DOM節點移除時清理自身。


侵入式插件:

修改除了自己子元素以外的依附元素(如父元素)的插件。

面對這類侵入式插件,保護好React的最好方式就是把DOM操控權完全交給我們自己。在componentDidMount方法中做一些初始化工作。這裏也需要去完成清理工作。

還需要進行處理更新。可通過兩種方式觸發:

-- 模擬卸載器而後重新掛載(更高效)

eg:

componentDidUpdate: function () {

this.componentWillUnmount();

this.componentDidMount();

}

-- 使用插件的更新操作API(更有效、清晰)


React基本概念(三)