React 基礎(chǔ)學(xué)習(xí)總結(jié)
1、創(chuàng)建虛擬DOM對(duì)象的兩種方式
- React.createElement(type, props, ...children)
- <h1></h1> jsx語(yǔ)法
- virtual-dom可以看做js對(duì)象
2、React 的 jsx 語(yǔ)法
- 作用:用來(lái)創(chuàng)建虛擬DOM對(duì)象
- 語(yǔ)法:
- 以<開(kāi)頭就會(huì)去解析,如果式html同名標(biāo)簽就解析html同名元素,如果不是就以其他方式解析
- 以{開(kāi)頭就會(huì)去解析,將其中的代碼當(dāng)作js代碼解析
- if / for循環(huán) 不能用
3、定義組件兩種方式
- 工廠函數(shù) --> 簡(jiǎn)單組件
function MyComponent() { return <h1></h1> } - ES6類 --> 復(fù)雜組件
class MyComponent extends React.Component{ render() { return <h1></h1> } } - 注意事項(xiàng):
- 組件首字母大寫(xiě)
- 標(biāo)簽必須是閉合的
- 有且只有一個(gè)根標(biāo)簽
4、React 組件的實(shí)例對(duì)象上 三大屬性(what why how)
- state
- 作用:
- 用來(lái)定義組件內(nèi)部狀態(tài)數(shù)據(jù)
- 用來(lái)更新頁(yè)面
- 使用:
- 初始化 在constructor中 this.state = {xxx: xxx}
- 讀取 this.state.xxx
- 更新 this.setState({xxx: xxx})
- 作用:
- props
- 作用:
- 用來(lái)組件外向組件內(nèi)傳遞數(shù)據(jù)
- 使用:
- 約束屬性的類型和必要性 static propTypes = {xxx: PropTypes.func.isRequired}
- 定義屬性的默認(rèn)值 static defaultProps = {xxx: xxx}
- 讀取 this.props.xxx
- 設(shè)置 <List name={xxx}>
- 作用:
- refs
- 作用:
- 用來(lái)獲取DOM元素
- 使用:
- 設(shè)置:
- 在constructor中 this.xxx = React.createRef()
- 在虛擬DOM對(duì)象上 <input ref={this.xxx} />
- 使用:this.xxx.current
- 設(shè)置:
- 作用:
- 屬性擴(kuò)展:
- static屬性 不會(huì)傳送給實(shí)例對(duì)象,永遠(yuǎn)在組件(類)上
- 普通屬性 會(huì)傳給實(shí)例對(duì)象
5、組件化編碼流程和套路
- 拆分組件: 根據(jù)頁(yè)面功能進(jìn)行拆分
App
AddTodo
TodoList - 實(shí)現(xiàn)靜態(tài)組件
先實(shí)現(xiàn)大的組件(最外層組件),再實(shí)現(xiàn)里面的組件。
有一個(gè)基本的顯示效果 - 實(shí)現(xiàn)動(dòng)態(tài)組件
- 需不需要定義狀態(tài)數(shù)據(jù)?
看頁(yè)面是否有變化,有變化就要定義狀態(tài)數(shù)據(jù) - 狀態(tài)數(shù)據(jù)定義再哪里?
如果數(shù)據(jù)是單個(gè)組件需要,就定義再單個(gè)組件內(nèi)
如果數(shù)據(jù)是多個(gè)組件需要,就定義再公共的父組件中 - 狀態(tài)數(shù)據(jù)定義成什么?
定義成對(duì)象、數(shù)組、基本數(shù)據(jù)類型。
方便插入數(shù)據(jù)和遍歷展示,所以用數(shù)組 - 子組件如何操作父組件的數(shù)據(jù)?
父組件定義操作數(shù)據(jù)的方法(數(shù)據(jù)再哪,操作數(shù)據(jù)的就在在哪)
父組件將操作數(shù)據(jù)的方法傳給子組件,子組件調(diào)用就改父組件的數(shù)據(jù)
- 組件特別注意事項(xiàng):
- 組件內(nèi)置的方法中的this為組件對(duì)象
- 在組件類中自定義的方法中this為null
a. 強(qiáng)制綁定this: 通過(guò)函數(shù)對(duì)象的bind()
b. 箭頭函數(shù)(ES6模塊化編碼時(shí)才能使用)
- 在組件類中自定義的方法中this為null
6、 收集表單數(shù)據(jù)(受控組件與非受控組件)
- 受控組件(官方推薦使用)
- 定義組件狀態(tài),綁定觸發(fā)事件,再通過(guò)事件目標(biāo)信息更新組件狀態(tài)
- 非受控組件
- 通過(guò)ref操作DOM節(jié)點(diǎn)的方式操作form信息
-
組件間的數(shù)據(jù)傳輸(重點(diǎn))--------->
- 父組件傳送給子組件 --利用props屬性傳值
- 子組件對(duì)父組件傳值 簡(jiǎn)單來(lái)說(shuō)就是利用回調(diào)來(lái)完成
- 兄弟之間傳值 傳值者先將值傳給父組件,再由父組件傳送給需要收值者
7、 組件的生命周期(Component-lifecycle)
-
概念:
- 組件對(duì)象從創(chuàng)建到死亡它會(huì)經(jīng)歷特定的生命周期階段
- React組件對(duì)象包含一系列的勾子函數(shù)(生命周期回調(diào)函數(shù)), 在生命周期特定時(shí)刻回調(diào)
- 我們?cè)诙x組件時(shí), 可以重寫(xiě)特定的生命周期回調(diào)函數(shù), 做特定的工作
-
第一部分: 初始化加載,生命周期函數(shù)執(zhí)行順序
- construtor (只會(huì)執(zhí)行一次)
- 初始化狀態(tài)數(shù)據(jù)
- 初始話Rreat.createRef()
- 綁定自定義函數(shù)this指向
- componetWillMount (18將廢棄) (只會(huì)執(zhí)行一次) 將要插入回調(diào)
- Render 渲染DOM (每當(dāng)組件狀態(tài)有變化就執(zhí)行) 用于插入虛擬dom回調(diào)
- componetDidMout (只會(huì)執(zhí)行一次) // 已經(jīng)插入回調(diào)
- 發(fā)送請(qǐng)求
- 設(shè)置異步任務(wù) ---> 綁定事件或者設(shè)置定時(shí)器
- construtor (只會(huì)執(zhí)行一次)
-
第二部分: 組件接收數(shù)據(jù),生命周期函數(shù)執(zhí)行順序
- componentWillReviceProps (將廢棄) 第一次props不會(huì)調(diào), 在有新的props才調(diào)用
- shouldComponentUpdate (this.setState觸發(fā))
- 專門用來(lái)做React性能優(yōu)化的:將之前的狀態(tài)/屬性和當(dāng)前的狀態(tài)/屬性進(jìn)行對(duì)比,如果一樣,就不更新,如果不一樣就更新
- 返回值為true就更新
- 返回值為false就不更新
- componentWillUpdate (this.forceUpdate觸發(fā)) 將廢棄
- render()
- componentDidUpdate
- 可以獲取更新后DOM元素,進(jìn)而進(jìn)行操作
-
第三部分: 組件將移出
- componentWillUnmout (unmountComponentAtNode 1秒執(zhí)行) 組件將要移出的回調(diào)
- 做一些首尾工作,清除定時(shí)器,局部變量,取消ajax請(qǐng)求
- componentWillUnmout (unmountComponentAtNode 1秒執(zhí)行) 組件將要移出的回調(diào)
Diff算法------->
- 總結(jié):
React 通過(guò)制定大膽的 diff 策略,將 O(n3) 復(fù)雜度的問(wèn)題轉(zhuǎn)換成 O(n) 復(fù)雜度的問(wèn)題;
React 通過(guò)分層求異的策略,對(duì) tree diff 進(jìn)行算法優(yōu)化;
-
React 通過(guò)相同類生成相似樹(shù)形結(jié)構(gòu),不同類生成不同樹(shù)形結(jié)構(gòu)的策略,對(duì) component diff 進(jìn)行算法優(yōu)化;
- React 通過(guò)設(shè)置唯一 key的策略,對(duì) element diff 進(jìn)行算法優(yōu)化;
-
建議,在開(kāi)發(fā)組件時(shí),保持穩(wěn)定的 DOM 結(jié)構(gòu)會(huì)有助于性能的提升;
- 建議,在開(kāi)發(fā)過(guò)程中,盡量減少類似將最后一個(gè)節(jié)點(diǎn)移動(dòng)到列表首部的操作,當(dāng)節(jié)點(diǎn)數(shù)量過(guò)大或更新操作過(guò)于頻繁時(shí),在一定程度上會(huì)影響 React 的渲染性能。
- 作用:
- 最小化頁(yè)面重繪、減少重排重繪的次數(shù)
key 與 index 對(duì)比
- 為什么列表的key盡量不要用index
- 簡(jiǎn)單來(lái)說(shuō): 當(dāng)數(shù)組中的數(shù)據(jù)發(fā)生變化時(shí): React 比較更新前后的元素 key 值,
- 如果相同則更新,如果不同則銷毀之前的,重新創(chuàng)建一個(gè)元素
- 結(jié)論:
- 如果今后需要往數(shù)組最前面插入數(shù)據(jù),必須用id作為key的值,
- 如果不是,而是往最后追加,可以用index作為key的值,(如果數(shù)據(jù)中有id屬性,就用id)
react-scaff 腳手架
1.簡(jiǎn)述:
* 1) xxx腳手架: 用來(lái)幫助程序員快速創(chuàng)建一個(gè)基于xxx庫(kù)的模板項(xiàng)目
* a. 包含了所有需要的配置
* b. 指定好了所有的依賴
* c. 可以直接安裝/編譯/運(yùn)行一個(gè)簡(jiǎn)單效果
* 2) react提供了一個(gè)用于創(chuàng)建react項(xiàng)目的腳手架庫(kù): create-react-app
* 3) 項(xiàng)目的整體技術(shù)架構(gòu)為: react + webpack + es6 + eslint + babel
* 4) 使用腳手架開(kāi)發(fā)的項(xiàng)目的特點(diǎn): 模塊化, 組件化, 工程化
- 安裝啟動(dòng):
npm install -g create-react-app
create-react-app hello-react
cd hello-react
npm start
- json配置含義:
"scripts": {
"start": "react-scripts start", //啟動(dòng)服務(wù)器端口監(jiān)聽(tīng)
"build": "react-scripts build", //生產(chǎn)環(huán)境指令
"test": "react-scripts test", // 測(cè)試文件是否有問(wèn)題
"eject": "react-scripts eject" //會(huì)webpack配置打包,在要大量修改時(shí)使用(一般不用)
},
PubSubJS 利用第三方庫(kù)組件進(jìn)行交互
antD-UI構(gòu)建庫(kù)項(xiàng)目
-
創(chuàng)建項(xiàng)目,引入adtd
- create-react-app react-admin
- npm i antd
- create-react-app react-admin
-
在根目錄配置按需打包文件 config-overrides.js
- 安裝: yarn add react-app-rewired customize-cra babel-plugin-import -D
- 配置: config-overrides.js
const { override, fixBabelImports} = require('customize-cra'); module.exports = override( fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: true, }), );
- 安裝: yarn add react-app-rewired customize-cra babel-plugin-import -D
在應(yīng)用中使用antd組件
-
自定義antd主題
- 安裝: yarn add less less-loader -D
- 功能: 編譯less,和主題顏色配置
-
引入路由
- 安裝: yarn add react-router-dom
- 配置路由: 項(xiàng)目應(yīng)該首先設(shè)置路由
- 安裝: yarn add react-router-dom
-
靜態(tài)組件引入
- 按需引入
import {Form, Icon, Input, Button} from 'antd' //按需引入 const Item = Form.Item; //替換成Item -
表單驗(yàn)證
- 利用高階函數(shù) 給Form創(chuàng)建form屬性
@Form.create() class Login extends Component {...} export default Login- 引入驗(yàn)證函數(shù)
// 引入 render() { const { getFieldDecorator } = this.props.form; ... // 驗(yàn)證語(yǔ)法
antd-UI項(xiàng)目包管理
- antd-UI下載
yarn add antd - 路由管理
react-router-dom - 組件按需打包
react-app-rewired -D
customize-cra -D
babel-plugin-import -D - 修改主題顏色,編譯文件
less less-loader -D - mongodb數(shù)據(jù)庫(kù)
- postman接口測(cè)試
- ajax請(qǐng)求
axios - 本地存儲(chǔ)
store - 文件路徑配置
node原生模塊 path - 輕量的處理時(shí)間和日期庫(kù)
apm i dayjs --save - 跨域處理...
npm i jsonp
redux狀態(tài)管理
- React Component 組件
- react-redux的Provider時(shí)store的抽象實(shí)例對(duì)象
- 使用react-redux 的connect方法連接redux的store
- actions creator 事件行為定義,創(chuàng)造新的store行為
- reducers 新?tīng)顟B(tài)生成,并不更新
- redux的combineReducers方法將處理后多狀態(tài)同時(shí)返回給store
- store 存儲(chǔ)比較新舊狀態(tài)
- redux的createStore方法將reducers的新?tīng)顟B(tài)創(chuàng)建為新的store
- redux的applyMiddleware方法應(yīng)用中間件
- redux-thunk是一個(gè)redux-store日志記錄的中間件
- redux-devtools-extension的composeWithDevTools是一個(gè)調(diào)試擴(kuò)展工具的方法
context
高階組件
* 是一個(gè)函數(shù),接收一個(gè)組件,返回一個(gè)組件
* 新組件
擴(kuò)展:
Virtual-DOM(虛擬DOM) 和 真實(shí)DOM 的比較:
真實(shí)DOM會(huì)有其他的一些屬性,例如事件,屬性等特性
虛擬DOM就是真實(shí)DOM變?yōu)閖s對(duì)象, 再比較虛擬DOM變化,是比較js對(duì)象的變化, 所以加快了react的性能