1.組件使你可以將ui劃分為一個一個獨立歇由,可復用的小部件仅孩,并可以對每個部件進行單獨的設計。
2.從定義上來說印蓖,組件就像JavaScript的函數(shù)辽慕,組件可以接收任意輸入(成為“props”),并返回react元素赦肃,用以描述屏幕顯示內(nèi)容溅蛉。
PS:可以把組件看出一個一個的函數(shù),props就是一個傳入到函數(shù)的對象參數(shù)他宛,里面就是組件所需的一個一個的變量船侧。state就是函數(shù)內(nèi)部定義的變量,可以直接操作
3.組件名稱總是以大寫字母開始厅各。PS:<div/>代表一個DOM標簽镜撩,而<welcome/>則代表一個組件,并且需要在 作用域中 有一個Welcome組件
4.提取組件:不要害怕把一個組件分為多個更小的組件队塘,因為過分復雜的組件一方面不利于復用袁梗,修改起來也麻煩,所以可以根據(jù)情況將其分解為多個小的組件憔古,注意組件的名稱定義要從組件本身的角度命名遮怜,而不是他被使用的上下文環(huán)境。
提取組件可能看起來是一個繁瑣的工作鸿市,但是在大型的 Apps 中可以回報給我們的是大量的可復用組件锯梁。一個好的經(jīng)驗準則是如果你 UI 的一部分需要用多次 (Button,Panel焰情,Avatar)陌凳,或者本身足夠復雜(App,F(xiàn)eedStory内舟,Comment)合敦,最好的做法是使其成為可復用組件。
5.Props是只讀的谒获。無論你用函數(shù)或類的方法來聲明組件蛤肌,它都無法修改其自身props壁却。所有react組件必須都是純函數(shù),并禁止修改其自身props裸准。如果有UI的需求展东,需要動態(tài)的改變,可以使用state炒俱,state允許react組件在不違反規(guī)則的情況下盐肃,根據(jù)用戶操作,網(wǎng)絡影響权悟,或者其他隨便什么東西砸王,來動態(tài)改變其輸出
6.更新UI的方式:
1.ReactDOM.render()方法來更新渲染的輸出
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(
element,
document.getElementById('root')
);
}
setInterval(tick, 1000);
5.this.props 由 React 本身設定, 而 this.state 具有特殊的含義,但如果需要存儲一些不用于視覺輸出的內(nèi)容峦阁,則可以手動向類中添加額外的字段谦铃。
如果在 render() 方法中沒有被引用, 它不應該出現(xiàn)在 state 中。
注意我們把計時器ID直接存在 this 中榔昔。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
我們來快速回顧一下該過程驹闰,以及調(diào)用方法的順序:
當 <Clock /> 被傳入 ReactDOM.render() 時, React 會調(diào)用 Clock組件的構造函數(shù)。 因為 Clock 要顯示的是當前時間撒会,所以它將使用包含當前時間的對象來初始化 this.state 嘹朗。我們稍后會更新此狀態(tài)。
然后 React 調(diào)用了 Clock 組件的 render() 方法诵肛。 React 從該方法返回內(nèi)容中得到要顯示在屏幕上的內(nèi)容屹培。然后,React 然后更新 DOM 以匹配 Clock 的渲染輸出怔檩。
當 Clock 輸出被插入到 DOM 中時褪秀,React 調(diào)用 componentDidMount() 生命周期鉤子。在該方法中珠洗,Clock 組件請求瀏覽器設置一個定時器來一次調(diào)用 tick()溜歪。
瀏覽器會每隔一秒調(diào)用一次 tick()方法若专。在該方法中许蓖, Clock 組件通過 setState() 方法并傳遞一個包含當前時間的對象來安排一個 UI 的更新。通過 setState(), React 得知了組件 state(狀態(tài))的變化, 隨即再次調(diào)用 render() 方法调衰,獲取了當前應該顯示的內(nèi)容膊爪。 這次,render() 方法中的 this.state.date 的值已經(jīng)發(fā)生了改變嚎莉, 從而米酬,其輸出的內(nèi)容也隨之改變。React 于是據(jù)此對 DOM 進行更新趋箩。
如果通過其他操作將 Clock 組件從 DOM 中移除了, React 會調(diào)用 componentWillUnmount() 生命周期鉤子, 所以計時器也會被停止赃额。
6.正確地使用 State(狀態(tài))
關于 setState() 有三件事是你應該知道的:
(1) 不要直接修改 state(狀態(tài))
例如加派,這樣將不會重新渲染一個組件:
// 錯誤
this.state.comment = 'Hello';
用 setState() 代替:
// 正確
this.setState({comment: 'Hello'});
唯一可以分配 this.state 的地方是構造函數(shù)。
(2)state(狀態(tài)) 更新可能是異步的
React 為了優(yōu)化性能跳芳,有可能會將多個 setState() 調(diào)用合并為一次更新芍锦。
因為 this.props 和 this.state 可能是異步更新的,你不能依賴他們的值計算下一個state(狀態(tài))飞盆。
例如, 以下代碼可能導致 counter(計數(shù)器)更新失斅α稹:
// 錯誤
this.setState({
counter: this.state.counter + this.props.increment,
});
要彌補這個問題,使用另一種 setState() 的形式吓歇,它接受一個函數(shù)而不是一個對象孽水。這個函數(shù)將接收前一個狀態(tài)作為第一個參數(shù),應用更新時的 props 作為第二個參數(shù):
// 正確
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
我們在上面使用了一個[箭頭函數(shù)]但是也可以使用一個常規(guī)的函數(shù):
// 正確
this.setState(function(prevState, props) {
return {
counter: prevState.counter + props.increment
};
});
(3)state(狀態(tài))更新會被合并
當你調(diào)用 setState()城看, React 將合并你提供的對象到當前的狀態(tài)中女气。
例如,你的狀態(tài)可能包含幾個獨立的變量:
constructor(props) {
super(props);
this.state = {
posts: [],
comments: []
};
}
然后通過調(diào)用獨立的 setState() 調(diào)用分別更新它們:
componentDidMount() {
fetchPosts().then(response => {
this.setState({
posts: response.posts
});
});
fetchComments().then(response => {
this.setState({
comments: response.comments
});
});
}
合并是淺合并测柠,所以 this.setState({comments}) 不會改變 this.state.posts 的值主卫,但會完全替換this.state.comments 的值。
7.數(shù)據(jù)向下流動
無論作為父組件還是子組件鹃愤,它都無法獲悉一個組件是否有狀態(tài)簇搅,同時也不需要關心另一個組件是定義為函數(shù)組件還是類組件。
這就是 state(狀態(tài)) 經(jīng)常被稱為 本地狀態(tài) 或 封裝狀態(tài)的原因软吐。 它不能被擁有并設置它的組件 以外的任何組件訪問瘩将。
一個組件可以選擇將 state(狀態(tài)) 向下傳遞,作為其子組件的 props(屬性):
8.處理事件
通過 React 元素處理事件跟在 DOM 元素上處理事件非常相似凹耙。但是有一些語法上的區(qū)別:
React 事件使用駝峰命名姿现,而不是全部小寫。
通過 JSX , 你傳遞一個函數(shù)作為事件處理程序肖抱,而不是一個字符串备典。
在 React 中略有不同:
<button onClick={activateLasers}>
Activate Lasers
</button>
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// 這個語法確保 `this` 被綁定在 handleClick 中
return (
<button onClick={(e) => this.handleClick(e)}>
Click me
</button>
);
}
}
這個語法的問題是,每次 LoggingButton 渲染時都創(chuàng)建一個不同的回調(diào)意述。在多數(shù)情況下提佣,沒什么問題。然而荤崇,如果這個回調(diào)被作為 prop(屬性) 傳遞給下級組件拌屏,這些組件可能需要額外的重復渲染。我們通常建議在構造函數(shù)中進行綁定术荤,以避免這類性能問題倚喂。