您好,登錄后才能下訂單哦!
1.組件的生命周期
實例化:
實例初次被創建,首次渲染時所調用的生命周期方法與其他各個后續實例被創建時所調用的方法略有不同。
在首次使用一個組件類時,下面方法依次調用順序:
--getDefaultProps
組件類的該方法只會被調用一次
任何復雜的值(如對象和數組),都會在所有實例中共享而不是復制或克隆
--getInitialState
每個實例都會且僅會調用一次該方法,初始化每個實例的state;
與getDefaultProps不同:每個實例創建都會調用一次改方法,在Initial法里已經可以調用到this.props
--componentWillMount
該方法會在完成首次渲染之前被調用,是在render方法調用前修改組件state的最后一次機會
--render
在這里創建一個虛擬DOM,用來表示組件的輸出。
對于一個組件來說,這是唯一一個必須的方法。
render需要滿足以下幾點:
--只能通過this.state和this.props訪問數據;
--可以返回null, false或任何react組件;
--只能出現一個頂級組件(不能返回一組元素);
--必須純凈,即不能改變組件的狀態或者修改DOM的輸出。
render方法返回的結果不是真正的DOM,而是一個虛擬的表現,React隨后會把他和真正的DOM(即內存中的DOM)做對比,來判斷是否有必要做出修改。
--componentDidMount
render方法成功被調用并真正的DOM已經被渲染之后,可以在componentDidMount內部通過this.getDOMNode()方法訪問到它。
可以用來訪問原始DOM的生命周期鉤子函數;
當React運行在服務端時,該方法不會被調用。
對于該組件的所有后續應用,下面方法依次調用:
--getInitialState
--componentWillMount
--render
--componentDidMount
存在期:
此時,組件已經渲染好,并且用戶可以與他進行交互。
隨著用戶的操作,組件或者整個應用的state逐漸受到影響,下面方法被依次調用:
--componentWillReceiveProps
任意時刻,組件的props都可以通過父輩組件來更改。出現這種情況時,該方法會被調用,將獲得更改props對象及更新state的機會。
--shouldComponentUpdate (一般不使用)
通過調用該方法在組件渲染時進行精確優化,即性能調優。
若確定某個組件或者它的任何子組件不需要渲染新的props或者state,則該方法會返回false(在首次渲染期間或調用forceUpdate()之后,這個方法不會被調用)。返回false是在告訴React要跳過調用render方法,以及位于render前后的鉤子函數:componentWillUpdate和componentDidUpdate。
React插件提供PureRenderMixin方法進行性能調優。若組件純凈,對于相同的props和state,它總會渲染出一樣的DOM,那么這個mixin會自動調用shouldComponentUpdate 方法來比較props和state,如果比較結果一致則返回false。
--componentWillUpdate
和componentWillMount 方法類似,組件會在接收到新的props或state進行渲染之前調用該方法。
注意:不可以在該方法中更新state或props。而應借助componentWillReceiveProps 方法在運行時進行更新state。
--render
--componentDidUpdate
和componentDidMount 方法類似,改方法給了我們更新已經渲染好的DOM的機會。
銷毀/清理期:
當組件被使用完成后,componentWillUnmount方法將會被調用,目的是給這個實例提供清理自身的機會。
該方法會將在componentDidMount方法添加的所有任務都在該方法中撤銷。
反模式:
即把計算后的值賦給state。
在getInitialState方法中,嘗試通過this.props來創建state的做法是一種反模式。
2.數據流
Props:
props是properties的縮寫,他可以把任意類型的數據傳遞給組件。
可以在掛載組件的時候(1)或通過調用組件實例的setProps方法(2)設置它的props:
eg1:
var surveys = [{title: 'Superheroes'}]; <ListSurveys surveys={surveys}/>
eg2:
var surveys = [{title: 'Superheroes'}];
var listSurveys = React.render(
<ListSurveys/>,
document.querySelector('body')
);
listSurveys.setProps({ surveys: surveys});
只能在組件(eg1)或者在組件樹外(eg2)通過調用setProps。不能調用this.setProps或者直接修改this.props,若真的需要,請使用state。一個組件不能修改自己的props。
PropTypes:
通過在組件中定義一個配置對象,React提供了一種驗證props的方式:
var SurveyTableRow = React.ceateClass({
propTypes: {
survey: React.PropTypes.shape({
id: React.PropTypes.number.isRequired
}).isRequired,
onClick: React.PropTypes.func
}
});
組件初始化時,如果傳遞的屬性和propTypes不匹配,則會打印一個console.warn日志。如果是可選的配置,則可去掉.isRequired。
getDefaultProps:
設置非必須屬性的默認值。
var SurveyTable = React.createClass({
getDefaultProps: function () {
return {
surveys: []
};
}
});
getDefaultProps并不是在組件實例化時被調用的,而是在React.createClass調用時就被調用了,返回值會被緩存起來。所以不能在getDefaultProps中使用任何特定的實例數據。
State:
每個React組件都有自己的state,state與props的區別在于前者只存在于組件的內部。
state可以通過setState來修改,也可以通過getInitialState方法提供一組默認值。只要setState被調用,render就會被調用。如果render函數返回值有變化,虛擬DOM就會更新,真實的DOM也會被更新,最終用戶就會在瀏覽器中看到變化。
不能直接修改this.state,永遠記得要通過this.setState方法修改。
state和props:
-- state中不保存計算出的值,值保存最簡單的數據,即組件正常工作時的必要數據;
-- 不要嘗試將props復制到state中。盡可能把props當做數據源使用;
-- 使用props在整個組件樹中傳遞數據和配置;
-- 避免在組件內部修改this.props或調用this.setProps,請把props當做是只讀的;
-- 使用props來做事件處理器,與子件通信;
-- 使用state存儲簡單的視圖狀態,比如下拉框是否可見;
-- 使用this.setState來設置狀態,而不是this.state直接修改狀態。
3.事件處理
從用戶輸入到更新用戶界面:
-- 在React組件上綁定事件處理器;
-- 在事件處理器當中更新組件內部狀態。組件狀態的更新會觸發重繪;
-- 實現組件的render函數用來渲染this.state的數據。
React對各種事件類型提供支持,具體支持類型:https://reactjs.org/docs/events.html
其中絕大部分事件不需要額外處理就能工作,但是觸控事件需要通過調用:React.initializeTouchEvents(true)手動啟動。
下面例子中的onChange就是一個時間處理
4.組件的復合
在傳統HTML中,元素師構成頁面的基礎單元。但在React中,React組件是構成頁面的基礎單元。React組件可以看成混入了JavaScript表達能力的HTML元素。實際上寫React代碼主要就是構建組件。
本質上,一個組件就是一個JavaScript函數,它接受屬性props和狀態state作為參數,并輸出渲染好的HTML。組件一般被用來呈現和表達應用的某部分數據,因此React可以理解為HTML的擴展。
當把表單渲染到屏幕上后,還沒有賦予組件獲取用戶的修改能力,子組件還沒有能力和它的父組件通信。
子組件和父組件通信的最簡單方式是通過使用屬性props。父組件需要通過屬性傳入一個回調函數,子組件在需要時進行回調。
eg:這里handleChanged是回調函數
var AnswerRadioInput = React.createClass({
mixins: [PropsMethodMixin],
propTypes: {
id: React.PropTypes.string,
name: React.PropTypes.string.isRequired,
label: React.PropTypes.string.isRequired,
value: React.PropTypes.string.isRequired,
checked: React.PropTypes.bool
},
getDefaultProps: function () {
return {
id: uniqueId('radio-'),
checked: false
};
},
getInitialState: function () {
return {
checked: !!this.props.checked
};
},
componentWillReceiveProps: function (nextProps) {
if(nextProps.checked !== undefined) {
this.setState({
checked: nextProps.checked
});
}
},
handleChanged: function (e) {
var checked = e.target.checked;
this.setState({checked: checked});
if(checked) {
this.callMethodOnProps('onChanged', this.props.value);
}
},
render: function () {
return (
<div className="radio">
<label>
<input type="radio"
name={this.props.name}
id={this.props.id}
value={this.props.value}
checked={this.state.checked}
onChange={this.handleChanged} />
{this.props.label}
</label>
</div>
);
}
});
復合組件只是React提供的用于定制和特殊化組件的方式之一。React的mixin提供了另一種途徑,幫助我們可以在多組件之間共享的方法。
5.mixin
mixin解決代碼重復,同時能讓組件保持專注于自身的業務邏輯。mixin允許我們使用強大的抽象功能。
幾種用法:
-- 一個監聽事件并修改state的mixin(如:flux store mixin)
-- 一個上傳mixin,它負責處理XHR上傳請求,同時將狀態以及上傳的進度同步到state
-- 渲染層mixin,簡化在</body>之前渲染子元素的過程(如渲染模態對話框)
Mixins有點類似AOP。所謂的mixins就是將組件里的方法抽出來。實際上Mixins里的this是指向組件的,使用了Mixins以后,組件也可以調用Mixins里的方法。
Mixins里也可以編寫組件生命周期的方法,需要注意的是:Mixins里的方法并不會覆蓋組件的生命周期方法,會在先于組件生命周期方法執行。
組件也可以使用多個Mixin,數組引入的順序,決定了Mxins里生命周期方法的執行順序。
除了生命周期方法可以重復以外,其他的方法都不可以重復,否則會報錯。
eg:
var AMixin = {
componentWillMount: function () {
console.log('AMixin Will Mount');
}
};
var BMixin = {
componentWillMount: function () {
console.log('BMixin Will Mount');
}
};
var Component = React.createClass({
mixins: [AMixin,BMixin],
componentWillMount: function () {
console.log('Component Will Mount');
},
render: function () {
return (
<div>Component</div>
)
}
});
控制臺打印:
$ AMixin Will Mount
$ BMixin Will Mount
$ Component Will Mount
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。