状态派生与保存——useMemo() 和 useCallback()

状态派生与保存——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',
  },
];

定义函数组件,使用useHistoryuseLocation 这两个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>
  )
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值