A. react中如何創(chuàng)建元素呢?
說(shuō)明一點(diǎn):
屬性都改為駝峰形式(無(wú)障礙屬性aria-*除外),
class改成className

B. 變量或表達(dá)式如何表示呢?大括號(hào){ }包起來(lái)

C. 元素和組件的區(qū)別
元素是構(gòu)成 React 應(yīng)用的最小磚塊。元素描述了你在屏幕上想看到的內(nèi)容。
const element = <h1>Hello, world</h1>;
組件允許你將 UI 拆分為獨(dú)立可復(fù)用的代碼片段,并對(duì)每個(gè)片段進(jìn)行獨(dú)立構(gòu)思。
組件,從概念上類似于 JavaScript 函數(shù)。它接受任意的入?yún)?/code>(即 props),并返回用于描述頁(yè)面展示內(nèi)容的 React 元素。

D. React元素與瀏覽器的 DOM 元素的區(qū)別
React 元素是不可變對(duì)象。一旦被創(chuàng)建,你就無(wú)法更改它的子元素或者屬性。一個(gè)元素就像電影的單幀:它代表了某個(gè)特定時(shí)刻的 UI。那如何才能刷新頁(yè)面上的數(shù)據(jù)呢?看下面計(jì)時(shí)器的例子:

但:React 元素是創(chuàng)建開(kāi)銷極小的普通對(duì)象?React 只更新它需要更新的部分
React DOM 會(huì)將元素和它的子元素與它們之前的狀態(tài)進(jìn)行比較,并只會(huì)進(jìn)行必要的更新來(lái)使 DOM 達(dá)到預(yù)期的狀態(tài)。
你可以使用瀏覽器的檢查元素工具查看上一個(gè)例子來(lái)確認(rèn)這一點(diǎn)。

盡管
每一秒我們都會(huì)新建一個(gè)描述整個(gè) UI 樹的元素,React DOM只會(huì)更新實(shí)際改變了的內(nèi)容
E1. 組件入?yún)?code>props:只讀,不可修改

所有 React 組件都必須像純函數(shù)一樣保護(hù)它們的 props 不被更改。
純函數(shù)
function sum(a, b) {
return a + b;
}
不純函數(shù)
function withdraw(account, amount) {
account.total -= amount;
}
E2. React中的占位符:類似vue中的slot

E3. 如何像使用vue的$attrs一樣使用React的props
在react中傳遞props,如果一層一層傳遞,只需要使用 <Component {...props}></Component>
F. class 組件中添加 state:請(qǐng)使用setState()修改

關(guān)于state的幾點(diǎn)說(shuō)明:
① 不要直接修改 state,代碼this.state.comment = 'Hello'不會(huì)重新渲染組件
② 而是應(yīng)該使用 setState(): this.setState({comment: 'Hello'})
③ 構(gòu)造函數(shù)是唯一可以給 this.state 賦值的地方
④ state 的更新可能是異步的:

⑤ setState的更新會(huì)被合并

⑥ 組件可以選擇把它的
state 作為 props 向下傳遞到它的子組件中
G. 事件處理

使用 React 時(shí),你一般不需要使用 addEventListener 為已創(chuàng)建的 DOM 元素添加監(jiān)聽(tīng)器。你只需要在該元素初始渲染的時(shí)候添加監(jiān)聽(tīng)器即可。
當(dāng)你使用 ES6 class 語(yǔ)法定義一個(gè)組件的時(shí)候,通常的做法是將事件處理函數(shù)聲明為 class 中的方法。例如,下面的 Toggle 組件會(huì)渲染一個(gè)讓用戶切換開(kāi)關(guān)狀態(tài)的按鈕:

向事件處理程序傳遞參數(shù)
在循環(huán)中,通常我們會(huì)為事件處理函數(shù)傳遞額外的參數(shù)。例如,若 id 是你要?jiǎng)h除那一行的 ID,以下兩種方式都可以向事件處理函數(shù)傳遞參數(shù):
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
上述兩種方式是等價(jià)的,分別通過(guò)箭頭函數(shù)和 Function.prototype.bind 來(lái)實(shí)現(xiàn)。
在這兩種情況下,React 的事件對(duì)象 e 會(huì)被作為第二個(gè)參數(shù)傳遞。如果通過(guò)箭頭函數(shù)的方式,事件對(duì)象必須顯式的進(jìn)行傳遞,而通過(guò) bind 的方式,事件對(duì)象以及更多的參數(shù)將會(huì)被隱式的進(jìn)行傳遞。
H. 條件渲染if & 列表 for


JSX 允許在大括號(hào)中嵌入任何表達(dá)式,所以我們可以內(nèi)聯(lián) map() 返回的結(jié)果
function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) =>
<ListItem key={number.toString()} value={number} />
)}
</ul>
);
}
I. 表單Form:受控組件

- 表單元素設(shè)置了
value屬性,因此顯示的值將始終為this.state.value,這使得React的state成為唯一數(shù)據(jù)源。 - 由于
handlechange在每次按鍵時(shí)都會(huì)執(zhí)行并更新state,因此顯示的值將隨著用戶輸入而更新。 - 對(duì)于受控組件來(lái)說(shuō),每個(gè)
state突變都有一個(gè)相關(guān)的處理函數(shù)。這使修改或驗(yàn)證用戶輸入變得簡(jiǎn)單。如要求所有輸入都大寫,可以將handlechange改為:
handleChange(event) {
this.setState({value: event.target.value.toUpperCase()});
}
處理多個(gè)輸入:當(dāng)需要處理多個(gè) input 元素時(shí),我們可以給每個(gè)元素添加 name 屬性,并讓處理函數(shù)根據(jù) event.target.name 的值選擇要執(zhí)行的操作。
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label> 參與:
<input name="isGoing" type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label><br />
<label>來(lái)賓人數(shù):
<input name="numberOfGuests" type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
受控輸入空值:在受控組件上指定 value 的 prop 可以防止用戶更改輸入。如果指定了 value,但輸入仍可編輯,則可能是意外地將value 設(shè)置為 undefined 或 null。
ReactDOM.render(<input value="hi" />, mountNode);
setTimeout(function() {
ReactDOM.render(<input value={null} />, mountNode);
}, 1000);
成熟的解決方案: 如果你想尋找包含驗(yàn)證、追蹤訪問(wèn)字段以及處理表單提交的完整解決方案,使用 Formik 是不錯(cuò)的選擇。
文件 input 標(biāo)簽:<input type="file" />,它的 value 只讀,所以它是 React 中的一個(gè)非受控組件。
J. 非受控組件
- 在大多數(shù)情況下,我們推薦使用 受控組件 來(lái)處理表單數(shù)據(jù)。在一個(gè)受控組件中,表單數(shù)據(jù)是由 React 組件來(lái)管理的。
- 另一種替代方案是使用非受控組件,這時(shí)表單數(shù)據(jù)將交由 DOM 節(jié)點(diǎn)來(lái)處理。

文件輸入:在 React 中,<input type="file" /> 始終是一個(gè)非受控組件,因?yàn)樗闹抵荒苡捎脩粼O(shè)置,而不能通過(guò)代碼控制
class FileInput extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.fileInput = React.createRef();
}
handleSubmit(event) {
event.preventDefault();
alert(
`Selected file - ${
this.fileInput.current.files[0].name
}`
);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Upload file:
<input type="file" ref={this.fileInput} />
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
}
ReactDOM.render(
<FileInput />,
document.getElementById('root')
);
K. 狀態(tài)提升【官網(wǎng)案例就不重復(fù)了】
- 狀態(tài)提升是什么意思? 一個(gè)最簡(jiǎn)單的例子:
-
兩個(gè)子組件需要利用對(duì)方的狀態(tài),這時(shí)我們就需要用到狀態(tài)提升 - 具體做法:把兩個(gè)子組件的狀態(tài)寫到它們的父組件中,然后父組件把狀態(tài)傳遞到子組件的props中去,這樣子組件也相當(dāng)于有狀態(tài)
- 父組件相當(dāng)于是數(shù)據(jù)源,這樣的話,子組件是沒(méi)有控制權(quán)的
- 那么之前子組件的state怎么辦呢?像:
<input value = {this.state.value} onChange = {this.handleChange}/> - 那就在父組件中寫出對(duì)應(yīng)的處理函數(shù),并在函數(shù)中更改
state