react hooks提供的两个API,用于缓存数据,优化性能。
useMemo
用来缓存数据,当 组件内部某一个渲染的数据,需要通过计算而来,这个计算是依赖与特定的state、props数据,我们就用useMemo来缓存这个数据,以至于我们在修改她们没有依赖的数据源的情况下,多次调用这个计算函数,浪费计算资源。
直接上代码
import React, { useState, useMemo } from 'react';
function Info(props) {
let [personalInfo , setPersonalInfo] = useState({
name: 'kevin kang',
gender: 'male'
})
function formatGender(gender) {
console.log('---调用了翻译性别的方法---')
return gender === 'male' ? '男' : '女'
}
// BAD
// 不使用useMemo的情况下,修改其他属性,也会重新调用formatGender方法,浪费计算资源
// let gender = formatGender(personalInfo.gender)
// GOOD
let gender = useMemo(()=>{
return formatGender(personalInfo.gender)
},
[personalInfo.gender])
return (
<>
<div>
姓名: {personalInfo.name} -- 性别: { gender } <br/>
<button onClick={
()=> {
setPersonalInfo({
...personalInfo,
name: 'Will Kang'
})
}
}> 点击修改名字</button>
</div>
</>
)
}
export default Info
useCallback
用来缓存函数,这个函数如果是由父组件传递给子组件,或者自定义hooks里面的函数【通常自定义hooks里面的函数,不会依赖于引用它的组件里面的数据】,这时候我们可以考虑缓存这个函数,好处:
1,不用每次重新声明新的函数,避免释放内存、分配内存的计算资源浪费
2,子组件不会因为这个函数的变动重新渲染。【和React.memo搭配使用】
import React, { Component, useState, useEffect, useCallback } from 'react';
// BAD
// function ListItem(props) {
// let addItem = props.addItem
// useEffect(()=>{
// console.log('子组件ListItem 加载')
// },[])
// useEffect(()=>{
// console.log('子组件render')
// })
// return (
// <div onClick={ addItem }> { props.children } </div>
// )
// }
// GOOD shouldComponentUpdate
const ListItem = React.memo((props)=> {
let addItem = props.addItem
useEffect(()=>{
console.log('子组件ListItem 加载')
},[])
useEffect(()=>{
console.log('子组件render')
})
return (
<div onClick={ addItem }> { props.children } </div>
)
})
let count = 0
function List(props) {
let [list, setList] = useState([])
let [name, setName] = useState('Kevin')
useEffect(()=>{
setList([
'6点起床',
'7点上班',
'8点早会'
])
}, [])
const addI = useCallback(()=>{
list.push('行程 '+ count)
setList([...list])
}, [list])
const modifyName = () => {
setName('K3VIN' + (++count))
}
return (
<>
{
list.map((item, index) => {
return <ListItem key={index} addItem = { addI }>
{item}
</ListItem>
})
}
现在的名字: {name} <button onClick={modifyName}> 点击修改名字 </button>
</>
)
}
export default List
使用memoAPI来缓存组件。
import React, { memo } from 'react';
const CacheComponent = memo(()=>{
return (
<div>
// ... component content
</div>
)
})
资料:https://github.com/facebook/react/issues/15156#issuecomment-474590693
练习集合: 仓库地址