定義組件的兩種方式
- 函數(shù)定義
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
- 類定義
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
使用React時个盆,值得注意的點:
所有的React組件必須像純函數(shù)那樣使用它們的props,不要修改傳入的props。(純函數(shù)拌牲,也就是不改變傳入值的函數(shù))
正確使用狀態(tài):關于
setState()
有三點值得注意:
- 不要直接更新狀態(tài),使用
setState()
更新
// Correct
this.setState({comment: 'Hello'});
- 狀態(tài)更新可能是異步的(
this.props
,this.state
可能異步更新歌粥,不應依靠它們?nèi)ビ嬎阈碌膕tate值)塌忽,如
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
可使用setState()
的第二種形式,傳入一個函數(shù)(函數(shù)的第一個參數(shù)為上一個state的值失驶,第二個參數(shù)為此次更新的props)
// Correct
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
- 狀態(tài)更新合并
當你調用setState()
時土居,React 將你提供的對象合并(淺合并)到當前狀態(tài)。
(這里的淺合并是什么意思嬉探?擦耀?)
數(shù)據(jù)自頂向下流動
任何狀態(tài)始終由某些特定組件所有,并且從該狀態(tài)導出的任何數(shù)據(jù)或 UI 只能影響樹中下方的組件甲馋。
父組件或子組件都不能知道某個組件是有狀態(tài)還是無狀態(tài)埂奈,并且它們不應該關心某組件是被定義為一個函數(shù)還是一個類。這就是為什么狀態(tài)通常被稱為局部或封裝定躏。 除了擁有并設置它的組件外账磺,其它組件不可訪問芹敌。
組件可以選擇將其狀態(tài)作為屬性傳遞給其子組件。事件處理:若用類的方法垮抗,需要綁定事件的this
// 兩種綁定this方法
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
值得注意的是氏捞,通過 bind 方式向監(jiān)聽函數(shù)傳參,在類組件中定義的監(jiān)聽函數(shù)冒版,事件對象 e 要排在所傳遞參數(shù)的后面
class Popper extends React.Component{
constructor(){
super();
this.state = {name:'Hello world!'};
}
preventPop(name, e){ //事件對象e要放在最后
e.preventDefault();
alert(name);
}
render(){
return (
<div>
<p>hello</p>
{/* Pass params via bind() method. */}
<a onClick={this.preventPop.bind(this,this.state.name)}>Click</a>
</div>
);
}
}
- 阻止組件渲染:讓 render 方法返回 null 而不是它的渲染結果即可實現(xiàn)液茎。
- key會作為給React的提示,但不會傳遞給你的組件辞嗡。如果需要使用和key相同的值捆等,請將其作為屬性傳遞
const content = posts.map((post) =>
<Post
key={post.id}
id={post.id}
title={post.title} />
);
受控組件:在React中,可變的狀態(tài)通常保存在組件的狀態(tài)屬性中续室,并且只能用
setState()
方法進行更新栋烤。我們通過使react變成一種單一數(shù)據(jù)源的狀態(tài)來結合二者。React負責渲染表單的組件仍然控制用戶后續(xù)輸入時所發(fā)生的變化挺狰。相應的明郭,其值由React控制的輸入表單元素稱為“受控組件”。狀態(tài)提升:狀態(tài)都是首先添加在需要渲染數(shù)據(jù)的組件中丰泊。此時薯定,如果另一個組件也需要這些數(shù)據(jù),你可以將數(shù)據(jù)提升至離它們最近的父組件中瞳购。你應該在應用中保持自上而下的數(shù)據(jù)流话侄,而不是嘗試在不同組件中同步狀態(tài)。
組合VS繼承:建議使用組合而不是繼承來復用組件之間的代碼学赛。
一些組件不能提前知道它們的子組件是什么满葛。這些組件使用 children 屬性將子元素直接傳遞到輸出。
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
請記住罢屈,組件可以接受任意元素,包括基本數(shù)據(jù)類型篇亭、React 元素或函數(shù)缠捌。