核心概念
1. JSX
- JSX是javascript的語(yǔ)法擴(kuò)展硕糊,讓我們可以在JS中編寫常規(guī)html代碼庵寞,在JSX中可以在大括號(hào)
{}
內(nèi)放置任何有效的javascript表達(dá)式湃密。 - JSX也是一個(gè)表達(dá)式占调,可以在
if
和for
循環(huán)代碼塊中使用JSX正什。 - 通過(guò)引號(hào)將屬性值指定為字符串字面量蝌焚,使用大括號(hào)將屬性值指定為j s表達(dá)式裹唆。
- React DOM 使用
camelCase
(小駝峰命名)來(lái)定義屬性的名稱,而不使用 HTML 屬性名稱的命名約定只洒。例如在JSX中class變?yōu)閏lassName品腹。
const name = 'Jade';
const element = <div>
<h1 className='weclome'>Hello, {name}</h1>
<input type='text' defaultValue={name} />
</div>;
ReactDOM.render(
element,
document.getElementById('root')
);
2. props
- 當(dāng) React 元素為用戶自定義組件時(shí),它會(huì)將 JSX 所接收的屬性以及子組件轉(zhuǎn)換為單個(gè)對(duì)象傳遞給組件红碑,這個(gè)對(duì)象被稱之為 “props”舞吭。
- 組件無(wú)論是使用函數(shù)聲明還是class聲明泡垃,都不能修改自身的 props,props為只讀羡鸥。
3. State
- state是組件私有化蔑穴,且完全受控于當(dāng)前組件,簡(jiǎn)單說(shuō)惧浴,完全props存和,state在組件內(nèi)可以隨意修改。定義state應(yīng)該在class構(gòu)造函數(shù)
constructor
中衷旅,state可以傳遞給子組件捐腿,數(shù)據(jù)是向下流動(dòng)。 - 關(guān)于修改state柿顶,應(yīng)該使用
setState()
茄袖,而不是直接賦值。this.setState({name: 'Jade'}); //correct
this.state.name = 'jade'; // wrong
-
setState()
為異步嘁锯,多個(gè)setState()
會(huì)合并為一個(gè)調(diào)用宪祥。所以最好不要依賴它們的值來(lái)更新下一個(gè)狀態(tài)。 - 關(guān)于異步的問(wèn)題家乘,可以讓
setState()
接受一個(gè)函數(shù)來(lái)解決蝗羊,該函數(shù)接受兩個(gè)參數(shù),用上一個(gè) state 作為第一個(gè)參數(shù)仁锯,將此次更新被應(yīng)用時(shí)的 props 做為第二個(gè)參數(shù)耀找。
4. 事件處理
不能通過(guò)
return false;
阻止默認(rèn)行為,只能是e.preventDefault()
业崖。-
JSX中回調(diào)問(wèn)題野芒,事件回調(diào)必須綁定
this
,不然回調(diào)中this
為undefined
腻要。原因在于js函數(shù)工作原理:const obj = { name: 'Jade', say: function () { console.log(this); } }; const test = obj.say; obj.say(); // {name: "Jade", say: ?} test(); // undefined
在js中复罐,傳遞一個(gè)函數(shù)名給一個(gè)變量涝登,然后在變量后加上()調(diào)用這個(gè)方法雄家,此時(shí)方法內(nèi)部的this的指向就丟失。在React中胀滚,OnClick其實(shí)就是一個(gè)中間變量趟济,所以
this
會(huì)丟失。 -
關(guān)于事件回調(diào)中
this
丟失的解決辦法有以下:- 使用
bind
綁定this
咽笼,<a onClick={this.click.bind(this)}>點(diǎn)擊</a>
顷编。 - 使用箭頭函數(shù)定義事件回調(diào)
this.click = () => { //do something }
- 使用箭頭函數(shù)調(diào)用事件回調(diào)
<a onClick={() => this.click()}>點(diǎn)擊</a>
- 使用
-
事件傳遞參數(shù)的方法有兩種,分別是通過(guò)箭頭函數(shù)和
bind
剑刑,事件對(duì)象e會(huì)被視為第二個(gè)參數(shù)媳纬,不同的是双肤,箭頭函數(shù)的方式必須顯式的傳入e,bind
則不需要钮惠,如下:<a onClick={(e) => this.click(id, e)}>點(diǎn)擊</a>
<a onClick={this.click.bind(this, id)}>點(diǎn)擊</a>
5. 表單
- 受控組件:表單中存在一個(gè)input茅糜,其value值必須是我們?cè)O(shè)置在constructor構(gòu)造函數(shù)中的state的值,通過(guò)onChange事件改變state中的值素挽,最終形成一個(gè)循環(huán)的回路影響蔑赘。
- 非受控組件:非受控也就意味著我可以不需要設(shè)置它的state屬性,而通過(guò)ref來(lái)操作真實(shí)的DOM预明。
6. 組件之間通訊
-
父子通訊:
// Context 可以讓我們無(wú)須明確地傳遍每一個(gè)組件缩赛,就能將值深入傳遞進(jìn)組件樹。 // 使用場(chǎng)景: 嵌套多層的組件撰糠,且每層組件可能都會(huì)用到某個(gè)變量 // 缺點(diǎn):導(dǎo)致組件的復(fù)用性降低 const NameContext = React.createContext('Jade'); // 默認(rèn)值‘Jade’ class App extends React.Component { render() { return ( // 使用Provider酥馍,將變量傳遞給下面的所有組件 <NameContext.provider value='Jadeee'> <PageHeader /> </NameContext> ) } } class PageHeader extends React.Component { render() { // 中組件不用在手動(dòng)傳遞了 return <UserName /> } } class UserName extends React.Component { static contentType = NameContext; render() { return <p> {this.context} </P> } }
// 父子通訊主要通過(guò)props傳遞參數(shù),數(shù)據(jù)自上而下流動(dòng)窗慎,實(shí)現(xiàn)父子通訊 class ChildrenComponent extends React.Component { constructor(props) { super(props); } render() { return ( {/* 接受從父組件傳遞而來(lái)的title */} <h1> {this.props.title} </h1> ) } } class ParentComponent extends React.Component { constructor(props) { super(props); this.state = { title: '標(biāo)題' } } render() { return ( {/* 將this.state.title傳遞給子組件 */} <ChildrenComponent title={this.state.title} /> ) } }
-
子父通訊:
class ChildrenComponent extends React.Component { constructor(props) { super(props); this.state = { name: 'children component' } } clickBtn() { // 調(diào)用父組件方法并將參數(shù)傳遞給父組件 this.props.onClickChildren(this.state.name); } render() { return ( <button type="button" onClick={this.clickBtn.bind(this)}> Click Me! </button> ) } } class ParentComponent extends React.Component { constructor(props) { super(props); } // 子組件調(diào)用综慎,val參數(shù)為子組件傳遞過(guò)來(lái) onClickChildren(val) { console.log(val); // children component } render() { return ( <div> {/* 將onClickChildren()方法作為props傳遞給子組件 */} <ChildrenComponent onClickChildren={this.onClickChildren.bind(this)} /> </div> ) } }
-
子子通訊:
- eventBus
- Redux