react提供useMemo/useCallback/memo方法,提高頁面刷新效率勋乾。若組件依賴的屬性沒有發(fā)送變化,組件可以不刷新句狼。以下提供兩個場景的具體使用
單組件內(nèi)使用
使用語法
import React, { useMemo } from 'react'
useMemo(() => {}, [] )
- 1.
useMemo
第一個參數(shù)是函數(shù)许起,第二個參數(shù)是數(shù)組 - 2.如果第二個參數(shù)不傳遞十偶,與
useEffect
類似,意味著每次都會執(zhí)行第一個函數(shù)參數(shù)园细,則使用useMem
就毫無意義 - 3.如果第二個參數(shù)傳的是空數(shù)組
[]
惦积, 與useEffect
類似,只執(zhí)行一次,類似類組件componentDidmount
- 4.
useMemo
與useEffect
有不一樣的一點(diǎn)就是調(diào)用時機(jī) —— useEffect執(zhí)行的是副作用猛频,所以一定是在渲染之后運(yùn)行的狮崩;而useMemo
是需要有返回值的,返回值會參與渲染鹿寻,所以useMemo是是在渲染期間完成的睦柴。 - 5.
useMemo
,定義了一段函數(shù)邏輯毡熏,根據(jù)第二個參數(shù)判斷是否執(zhí)行第一個函數(shù)執(zhí)行
useMemo
case1 (不設(shè)置第二個參數(shù)坦敌,無優(yōu)化效果)
-
useMemo
第二個參數(shù)不設(shè)置 - 代碼表現(xiàn):每次點(diǎn)擊
點(diǎn)擊+1
,控制臺打印double
痢法,同時標(biāo)簽Double
每次刷新 - 代碼解析:
useMemo
第二個參數(shù)不設(shè)置狱窘,頁面首次加載和頁面更新,都會重新加載<div>Double is :{double}</div>
import React, {useState, useCallback, useEffect, useMemo, memo} from 'react'
// 函數(shù)組件财搁,當(dāng)前組件中useMemo的使用
function App() {
const [count, setCount] = useState(0)
const double = useMemo(()=>{
console.log('double')
return count * 2
})//關(guān)注點(diǎn)
return (
<div>
<button onClick={() => {
setCount(count + 1)
}}>點(diǎn)擊+1
</button>
<div>Count is :{count}</div>
<div>Double is :{double}</div>
</div>
)
}
case2 (設(shè)置第二個參數(shù)為[]蘸炸,首次加載更新)
-
useMemo
第二個參數(shù)設(shè)置為[]
,這組件只會在頁面首次加載更新妇拯,類似類組件的componentDidMount
- 代碼表現(xiàn):頁面首次加載幻馁,控制臺打印
double
;每次點(diǎn)擊點(diǎn)擊+1
越锈,控制臺打印無打印日志仗嗦,同時標(biāo)簽Double
始終為0 - 代碼解析:
useMemo
第二個參數(shù)設(shè)置[]
,<div>Double is :{double}</div>
只有在首次頁面加載甘凭,即double變化了稀拐,也不會改變標(biāo)簽的
import React, {useState, useCallback, useEffect, useMemo, memo} from 'react'
// 函數(shù)組件,當(dāng)前組件中useMemo的使用
function App() {
const [count, setCount] = useState(0)
const double = useMemo(()=>{
console.log('double')
return count * 2
},[]) //關(guān)注點(diǎn)
return (
<div>
<button onClick={() => {
setCount(count + 1)
}}>點(diǎn)擊+1
</button>
<div>Count is :{count}</div>
<div>Double is :{double}</div>
</div>
)
}
case3 (設(shè)置第二個參數(shù)為[count===2])
-
useMemo
第二個參數(shù)設(shè)置為[count===2]
- 代碼表現(xiàn):頁面首次加載丹弱,控制臺打印
double
德撬;點(diǎn)擊點(diǎn)擊+1
,當(dāng)count=2躲胳,count=3的時候控制臺打印double
蜓洪,同時標(biāo)簽<div>Double is :{double}</div>
更新兩次,分別為Double is :4
和Double is :6
- 代碼解析:
useMemo
第二個參數(shù)設(shè)置[count===2]
坯苹,表示當(dāng)count===2
的時候才會更新組件隆檀,count
從1,2,3
對應(yīng)count===2
變化為false, true, false
恐仑,因此只有2次刷新
import React, {useState, useCallback, useEffect, useMemo, memo} from 'react'
// 函數(shù)組件泉坐,當(dāng)前組件中useMemo的使用
function App() {
const [count, setCount] = useState(0)
const double = useMemo(()=>{
console.log('double')
return count * 2
},[count===2]) //關(guān)注點(diǎn)
return (
<div>
<button onClick={() => {
setCount(count + 1)
}}>點(diǎn)擊+1
</button>
<div>Count is :{count}</div>
<div>Double is :{double}</div>
</div>
)
}
父子組件內(nèi)使用
目標(biāo):
子組件的依賴屬性更新,才會重新加載子組件
操作:
- 1.子組件用
memo
聲明裳仆, - 2.子組件對父組件依賴的
所有屬性
用useCallback
或者useMemo
聲明
子組件沒用memo
聲明
程序響應(yīng):
-
<Counter counter = {double}></Counter>
當(dāng)count為2腕让,3的時候,double發(fā)生變化
-
- 2.每次
count
變化歧斟,子組件都會重新渲染(控制臺打印日志counter
)
代碼如下
function Counter(props) {
console.log('counter')
return (
<div>
double is : {props.counter}
</div>
)
}
function App (){
const [count, setCount] = useState(0)
const double = useMemo(()=>{
return count * 2
}, [count === 2])
return (
<div>
<button onClick={()=>{setCount(count + 1)}}>點(diǎn)擊+1</button>
<div>count is : {count}</div>
<Counter counter = {double}></Counter>
</div>
)
}
子組件用memo
聲明
程序響應(yīng):
-
<Counter counter = {double}></Counter>
當(dāng)count為2纯丸,3的時候,double發(fā)生變化
-
- 2.當(dāng)count為2构捡,3的時候液南,子組件會重新渲染(控制臺打印日志
counter
)
代碼如下
const Counter = memo(function Counter(props) {
console.log('counter')
return (
<div>
double is : {props.counter}
</div>
)
})
function App (){
const [count, setCount] = useState(0)
const double = useMemo(()=>{
return count * 2
}, [count === 2])
return (
<div>
<button onClick={()=>{setCount(count + 1)}}>點(diǎn)擊+1</button>
<div>count is : {count}</div>
<Counter counter = {double}></Counter>
</div>
)
}
子組件用部分屬性useMemo
聲明
程序響應(yīng):
-
<Counter counter = {double}></Counter>
當(dāng)count為2,3的時候勾徽,double發(fā)生變化
-
- 2.每次
count
變化滑凉,子組件都會重新渲染(控制臺打印日志counter
),原因
是btnClick是箭頭函數(shù)定義的,react頁面更新都會重新渲染子組件
代碼
//函數(shù)組件喘帚,父組件畅姊,子組件
const Counter = memo(function Counter(props) {
console.log('counter')
return (
<div>
double is : {props.counter}
</div>
)
})
function App (){
const [count, setCount] = useState(0)
const double = useMemo(()=>{
return count * 2
}, [count === 2])
const btnClick = ()=>{
console.log('click')
}
return (
<div>
<button onClick={()=>{setCount(count + 1)}}>點(diǎn)擊+1</button>
<div>count is : {count}</div>
<Counter counter = {double} onClick={btnClick}></Counter>
</div>
)
}
子組件用全部屬性useMemo/useCallback
聲明
程序響應(yīng):
-
<Counter counter = {double}></Counter>
當(dāng)count為2,3的時候吹由,double發(fā)生變化
-
- 2.當(dāng)count為2若未,3的時候,子組件會重新渲染(控制臺打印日志
counter
) -
const btnClick = useCallback(()=>{console.log('click')}, [])
倾鲫, 關(guān)注useCallback第二個參數(shù)粗合,
** a.當(dāng)?shù)诙€參數(shù)不設(shè)置,則每次count變化乌昔,子組件都會重新加載隙疚,即使counter = {double}
不發(fā)生變化,因?yàn)閎tnClick是首次加載和更新都會重新加載磕道,導(dǎo)致子組件也會重新加載
** b.當(dāng)?shù)诙€參數(shù)為[]
出現(xiàn)2的現(xiàn)象供屉,原因是子組件的double發(fā)生變化
** c.當(dāng)?shù)诙€參數(shù)為[double]
出現(xiàn)2的現(xiàn)象,原因是double發(fā)生比變化
-
代碼
//函數(shù)組件溺蕉,父組件伶丐,子組件
const Counter = memo(function Counter(props) {
console.log('counter')
return (
<div>
double is : {props.counter}
</div>
)
})
function App (){
const [count, setCount] = useState(0)
const double = useMemo(()=>{
return count * 2
}, [count === 2])
const btnClick = useCallback(()=>{
console.log('click')
}, [])
return (
<div>
<button onClick={()=>{setCount(count + 1)}}>點(diǎn)擊+1</button>
<div>count is : {count}</div>
<Counter counter = {double} onClick={btnClick}></Counter>
</div>
)
}