React 核心概念

JSX

JSX 是一個表達式,JSX的值是一個JS對象,因此可以再if for代碼塊中使用JSX,也可以將JSX賦給變量或把JSX當作參數(shù)傳入,以及從函數(shù)中返回JSX

JSX 最終會被編譯為 React.createElement() 函數(shù)調(diào)用,返回稱為 “React 元素” 的普通 JavaScript 對象

元素渲染

React元素是開銷極小的普通對象,React DOM 會負責更新DOM來與React元素保持一致

更新已渲染的元素:

React元素是不可變對象,更新UI的唯一方式是創(chuàng)建一個全新的元素,重新ReactDOM.render()

React 只更新它需要更新的部分

React DOM 會將元素和它的子元素與它們之前的狀態(tài)進行比較,并只會進行必要的更新來使 DOM 達到預期的狀態(tài)。

組件 & Props

定義組件兩種方式:

通過JS函數(shù):

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

通過ES6 的 class:

class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

如何選擇:如果你想寫的組件只包含一個 render 方法,并且不包含 state,那么使用函數(shù)組件就會更簡單。

注意: 組件名稱必須以大寫字母開頭。
React 會將以小寫字母開頭的組件視為原生 DOM 標簽

渲染組件:

const element = <Welcome name="Sara" />;

關(guān)于提取組件:

何時需要將組件拆分為更下的組件?

如果 UI 中有一部分被多次使用(Button,Panel,Avatar),或者組件本身就足夠復雜(App,F(xiàn)eedStory,Comment),那么它就是一個可復用組件的候選項。

Props 的只讀性:

首先了解下純函數(shù)的定義:即不會更改入?yún)⒌暮瘮?shù)。

React 組件都必須像純函數(shù)一樣保護它們的 props 不被更改

State & 生命周期

State與生命周期的使用需要在class組件中。

State 與 props 類似,但是 state 是私有的,并且完全受控于當前組件。

使用this.setState() 來更新組件 state, 這時React會重新調(diào)用render()

生命周期:

componentDidMount() 在組件已經(jīng)被渲染到 DOM 中后運行

componentWillUnmount() 組件被刪除前

注意的幾個點:

構(gòu)造函數(shù)是唯一可以給 this.state 賦值的地方

State 的更新可能是異步的

出于性能考慮,React 可能會把多個 setState() 調(diào)用合并成一個調(diào)用。
因為 this.props 和 this.state 可能會異步更新,所以你不要依賴他們的值來更新下一個狀態(tài)。

事件處理

React 中你不能通過返回 false 的方式阻止默認行為,必須顯式的使用 preventDefault。

e 是一個合成事件。React 根據(jù) W3C 規(guī)范來定義這些合成事件,所以你不需要擔心跨瀏覽器的兼容性問題

表單

React 中,HTML 表單元素的工作方式和其他的 DOM 元素有些不同,表單元素通常會保持一些內(nèi)部的 state。

受控組件(類似vue中使用:value或v-model綁定數(shù)據(jù)):

  1. React 的 state 成為“唯一數(shù)據(jù)源”。
  2. 渲染表單的 React 組件控制著用戶輸入過程中表單發(fā)生的操作。

文件input標簽 <input type="file" />非受控組件,因為它的value只讀。

狀態(tài)提升

多個組件中需要共享的 state 向上移動到它們的最近共同父組件中,便可實現(xiàn)共享 state。這就是所謂的“狀態(tài)提升”。
即通過自上而下的數(shù)據(jù)流,將state放入父組件通過props傳入子組件。

狀態(tài)提升 vs 雙向綁定

提升 state 方式比雙向綁定方式需要編寫更多的“樣板”代碼,但帶來的好處是,排查和隔離 bug 所需的工作量將會變少。由于“存在”于組件中的任何 state,僅有組件自己能夠修改它,因此 bug 的排查范圍被大大縮減了。

組合 vs 繼承

父組件中的所有內(nèi)容內(nèi)容都會作為名為childrenprop傳遞給子組件

React vs Vue

Vue: 使用slot。
React: 沒有slot槽的概念,因為React 元素本質(zhì)就是對象,所以一切都可通過props傳入子組件。

React 哲學

React 最棒的部分之一是引導我們思考如何構(gòu)建一個應用。

用React 哲學實現(xiàn)一個可搜索數(shù)據(jù)表格

第一步:劃分組件層級

根據(jù)單一功能原則劃分組價你的范圍,一個組件原則上只負責一個功能。

第二步:創(chuàng)建一個靜態(tài)版本

核心思想是渲染UI和添加交互這兩個過程應該分開。因為編寫應用的靜態(tài)版本時往往需要編寫大量代碼,而不需要考慮太多交互細節(jié);添加交互功能時則要考慮大量細節(jié),不需要寫大量代碼。所以這兩個過程分開更為合適。

構(gòu)建應用的靜態(tài)版本時,使用props傳數(shù)據(jù)(即使需要使用state,這一步也不應該使用state,而是把state替換props留到添加交互這一步驟中實現(xiàn))

構(gòu)建順序:
你可以自上而下或者自下而上構(gòu)建應用。
當你的應用比較簡單時,使用自上而下的方式更方便;對于較為大型的項目來說,自下而上地構(gòu)建,并同時為低層組件編寫測試是更加簡單的方式。

第三步:確定UI state 的最小(且完整)表示

即找到應用所需的最少數(shù)量state的表示方式,其余數(shù)據(jù)均可由它們計算產(chǎn)生。遵循DRY(Don't Repeat Yourself)原則

通過問自己以下三個問題,你可以逐個檢查相應數(shù)據(jù)是否屬于 state:

  • 該數(shù)據(jù)是否是由父組件通過 props 傳遞而來的?如果是,那它應該不是 state。
  • 該數(shù)據(jù)是否隨時間的推移而保持不變?如果是,那它應該也不是 state。
  • 你能否根據(jù)其他 state 或 props 計算出該數(shù)據(jù)的值?如果是,那它也不是 state。

第四步:確定 state 放置的位置

你可以嘗試通過以下步驟來判斷

對于應用中的每一個 state:

  • 找到根據(jù)這個 state 進行渲染的所有組件。
  • 找到他們的共同所有者(common owner)組件(在組件層級上高于所有需要該 state 的組件)。
  • 該共同所有者組件或者比它層級更高的組件應該擁有該 state。
  • 如果你找不到一個合適的位置來存放該 state,就可以直接創(chuàng)建一個新的組件來存放該 state,并將這一新組件置于高于共同所有者組件層級的位置。

第五步:添加反向數(shù)據(jù)流

React 通過一種比傳統(tǒng)的雙向綁定略微繁瑣的方法來實現(xiàn)反向數(shù)據(jù)傳遞。盡管如此,但這種需要顯式聲明的方法更有助于人們理解程序的運作方式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容