状态派生与保存——useMemo() 和 useCallback()
useMemo():在一个函数组件同步执行一个函数逻辑,函数的返回值作为一个新的状态保存起来。
**使用场景:**在函数组件需要进行大量的计算,不希望每一次函数组件渲染的时候去执行这些计算的逻辑,就把这些计算的逻辑放useMemo中,然后把得到的计算结果缓存起来。
useMemo()基础介绍:
语法:
const value=useMemo(function,array);
参数解释:function为一个函数,array为一个数组,value为返回值,执行function过后的返回值,如果array的依赖项发生改变,返回一个重新执行完的function的值,否则取的就是上一次的缓存值。
1. 缓存值,避免重复执行上下文
const number=React.useMemo(()=>{
....//许多逻辑计算
return number;
},[props.number])//只有props.number改变的时候才会重新计算number的值
2. 减少不必要的dom循环
/* 用 useMemo包裹的list可以限定当且仅当list改变的时候才更新此list,这样就可以避免selectList重新循环 */
{useMemo(() => (
<div>{
selectList.map((i, v) => (
<span
className={style.listSpan}
key={v} >
{i.patentName}
</span>
))}
</div>
), [selectList])}
3. 减少子组件渲染
const goodListChild=useMemo(()=><GoodList list={props.list} />,[props.list])
useCallback()基础介绍:
和useMemo接受的参数是一样的,依赖项发生改变就执行,返回缓存的值。区别:useMemo返回的是函数运行后的结果,useCallback返回的是一个函数,这个回调函数是经过处理后的结果,
/* 用react.memo */
const DemoChildren = React.memo((props)=>{
/* 只有初始化的时候打印了 子组件更新 */
console.log('子组件更新')
useEffect(()=>{
props.getInfo('子组件')
},[])
return <div>子组件</div>
})
const DemoUseCallback=({ id })=>{
const [number, setNumber] = useState(1)
/* 此时usecallback的第一参数 (sonName)=>{ console.log(sonName) }
经过处理赋值给 getInfo */
const getInfo = useCallback((sonName)=>{
console.log(sonName)
},[id])
return <div>
{/* 点击按钮触发父组件更新 ,但是子组件没有更新 */}
<button onClick={ ()=>setNumber(number+1) } >增加</button>
<DemoChildren getInfo={getInfo} />
</div>
}
在table表格组件进行简单的使用,定义表格:
import { Table, Divider, Tag } from 'antd';
import React from 'react';
import { useHistory,useLocation } from 'react-router-dom';
import qs from'query-string'
//定义表格
const columns = [
{
title: 'Name',
dataIndex: 'name',
render: text => <a>{text}</a>,
},
{
title: 'Cash Assets',
className: 'column-money',
dataIndex: 'money',
},
{
title: 'Address',
dataIndex: 'address',
},
];
//定义表格数据内容
const data = [
{
key: '1',
name: 'John Brown',
money: '¥300,000.00',
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
money: '¥1,256,000.00',
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
money: '¥120,000.00',
address: 'Sidney No. 1 Lake Park',
},
];
定义函数组件,使用useHistory 和 useLocation 这两个API。
export default function Page4() {
//使用路由的这两个API,需要提前引入这两个路由API
const history = useHistory();
const location = useLocation();
//计算出来当前页码
const current = React.useMemo(()=>parseInt(qs.parse(location.search).current as string)||1,[location]);
//使用useCallback创建回调onChange
const onChange = React.useCallback(e => {
history.push(`/page4?current=${e.current}`)
},[history]
)
return (
<div>
<Table
columns={columns}
dataSource={data}
onChange={onChange}
bordered
title={() => 'Header'}
footer={() => 'Footer'}
pagination={
{
total:1000,
pageSize: 15,
current: current,
size: 'small',
}
}
/>
</div>
)
}