1.基礎(chǔ)的React
1.1 Context與ContextType
Context提供了一種方式,能夠讓數(shù)據(jù)在組件樹中傳遞而不必一級一級的手動傳遞,但會讓組件失去獨立性。

context結(jié)構(gòu)
API:createContext(defaultValue?)
import {createContext} from 'react'
const BatteryContext = createContext()
<BatteryContext.Provider value={}>
</BatteryContext.Provider>
<BatteryContext.Consumer>
{
battery=><h1>{battert}</h1>
}
</BatteryContext.Consumer>
static contextType = BatteryContext
render(){
const battery = this.context
}
1.2 lazy與Suspense
暫時沒有資源展示---->延遲加載:
- Webpack - Code Splitting
把一個頁面人為的劃分為模塊進行導(dǎo)入 - import
1.做靜態(tài)模塊導(dǎo)入
import 。。。 from
2.動態(tài)模塊導(dǎo)入
import('').then(...)
typeof import
webpack就會做一次代碼拆分,把import的依賴打包成一個獨立的文件,默認情況下,不會馬上加載它,只有用到的時候才會導(dǎo)入。指組件渲染的時候。封裝的是組件導(dǎo)入的行為,而不是組件本身。而且導(dǎo)入意味著網(wǎng)絡(luò)請求。
const About = lazy=(()=>import(/*webpackChunkName:'about'*/'./about.jsx'))
lazy的返回就是一個組件
用了lazy后,會存在一個加載中的空檔,不知道什么時候加載
這時候用Suspense
<Suspense fallback=(<div>About</div>)>
<About>
</About>
</Suspense>
block request url阻止獲取請求(當(dāng)出現(xiàn)加載錯誤的時候,suspense不能捕獲,但錯誤邊界可以)
//ErrorBoundary錯誤邊界
componentDidCatch(){
this.setState({
hasError:true
})
}
//一旦發(fā)生錯誤,就返回一個新的state數(shù)據(jù),并合并到新的state之中
static getDerivedStateFromError(){
return {
hasError:true
}
}
頁面首次加載時的性能問題
1.3 memo
shouldComponentUpdate(nextProps,nextState){
if(nextProps.name === this.props.name){
//下一次屬性中的name和當(dāng)前屬性中的name,如果相等就不再重新渲染,不想等就重新渲染
return false
}else{
return true
}
}
//或者用PureCompent,需要導(dǎo)入{PureCompent } from React,只有傳入數(shù)據(jù)的本身對比
//(第一級發(fā)生變化,比如對象內(nèi)部不算)2.傳入回調(diào)函數(shù)每次都會重新渲染),內(nèi)部的數(shù)據(jù)變化就不行
class Foo extends PureCompent{
}
memo
//函數(shù)式的不能用Pure,但是有memo
import {memo} from 'react'
const Foo = memo(function Foo(props){//返回一個組件
return ()
})
2.React Hooks
類組件的問題:
- 狀態(tài)難以復(fù)用(渲染組件,高階組件)
- 渲染屬性和高階組件導(dǎo)致層級冗余
- 生命周期函數(shù)混雜不相干邏輯
- 相干邏輯分散在不同的生命周期
- this指向復(fù)雜
hooks優(yōu)勢: - 函數(shù)組件無this問題
- 自定義hooks方便復(fù)用狀態(tài)邏輯
- 副作用關(guān)注點分離
2.1 useState
import {useState} from 'react'
const [count ,setCount] = useState(0)
onClick={()=>{setCount(count +1)}}
use每次渲染按照穩(wěn)定的順序和穩(wěn)定的次數(shù)。
2.2 useEffect
副作用:
- 綁定事件
- 網(wǎng)絡(luò)請求
- 訪問DOM
副作用的時期:
- Mount之后
- Update之前
- Unmount之前

useEffect
useEffect(()=>{
window.addEventListener('resize',onResize)
console.log('count')
return () => {
//清空狀態(tài)函數(shù)
window.removeEventListener('resize',onResize)
}
},[])
傳入空數(shù)組說明只執(zhí)一次。
2.3 useContext與useMemo/useCallback
import {createContext,useContext} from 'react'
const CountContext = createContext()
<CountContext.Provider value={}></>
function Counter(){
const count = useContext(CountContext)
console.log(count)
}
useMemo:
僅僅用來做性能優(yōu)化使用,不能做改變渲染邏輯的用途
const double = useMemo(()=>{
return count *3
},[count])調(diào)用時機在渲染期間,而useEffect是在副作用時期,useMemo是有返回值,可以參與渲染,不能循環(huán)依賴
useCallback:
const onClick = useMemo(()=>{
return ()=>{
console.log('click')
}
},[])
const onClick = useCallback(()=>{
console.log('click')
},[])
useMemo返回值是一個函數(shù)。則等價于useCallback
使onclick函數(shù)不會變化,useCallback會創(chuàng)建函數(shù),但是如果沒有變化,則不會返回,當(dāng)依賴變化時,才會執(zhí)行。
2.4 useRef
- 獲取子組件或者DOM節(jié)點的句柄
- 渲染周期之間共享數(shù)據(jù)的存儲
state也能儲存數(shù)據(jù),但state會觸發(fā)重渲染。
import {useRef} from "react"
const counterRef = useRef()
<Counter ref= {counterRef}>
console.log(counterRef.current)
//注意只能是類組件
const it = useRef()
it.current = ....
下一次渲染就能獲取到了
2.5 Redux
redux:狀態(tài)容器與數(shù)據(jù)流管理
- 單一數(shù)據(jù)源
- 狀態(tài)不可變(修改完之后不再是以前的Redux)
- 用純函數(shù)來修改狀態(tài)