useCallback包裹函数,但是使用到的外部变量一直是最开始的值

这篇文章不错 https://www.cnblogs.com/ascoders/p/10591832.html
一开始用useCallback包裹了这个函数,这个函数的handleAction中有用到一个paramsMemo的数据,这个数据是声明在外面的。这样有个问题是handleAction中拿到的paramsMemo一直是最开始的数据。
所以疑问是 useCallback中会拿不到外面变量的更新么?

我的理解:

useCallback也应该有依赖,不然其里面用到的变量会一直是最开始那个,因为每次render都有自己独立的props,state,effects,事件处理!
除了useRef,利用 useRef 就可以绕过 Capture Value 的特性。可以认为 ref 在所有 Render 过程中保持着唯一引用,因此所有对 ref 的赋值或取值,拿到的都只有一个最终状态,而不会在每个 Render 间存在隔离。
依赖不丢、逻辑内聚,从而容易维护。
所以我一开始使用了useCallback,但是没有给其传依赖,但是里面又用到了,所以就导致这样的问题。

rightControlButton
const rightControlButton =
         useCallback(
        (row: DataManagement.DataManagementListItem) => {
            switch (row.lineStatus) {
                case null:
                case 1:
                    return (
                        < Button type="link" onClick={() => handlerAction(row, 'offline')} title="下线">
                            <BdpIcon type="iconxiaxian" color="#3954FF"></BdpIcon>
                        </Button>
                    )
                case 0:
                    return (
                        <Button type="link" onClick={() => handlerAction(row, 'online')} title="启用">
                            <BdpIcon type="iconshangxian" color="#3954FF"></BdpIcon>
                        </Button>
                    );
                case 2:
                default:
                    // 流程中和其他的状态展示上线的图标,但是要置灰!
                    return (
                        <Button type="link" disabled>
                            <BdpIcon type="iconshangxian" color="#DDD"></BdpIcon>
                        </Button>
                    )
            }
        }
      [])
paramsMemo
const paramsMemo = useMemo(() => {
        const { keyword, pageNum = 1, pageSize = 10, topic, lineStatus, type = 1 } = params;
        let params1: DataManagement.tepeListByManager = {
            keywords: keyword ? keyword : '',
            topic: topic === 'all' ? '' : topic,
            lineStatus: lineStatus === 'all' ? '' : lineStatus,
            pageNum: pageNum,
            pageSize: pageSize,
            type: currentUser.type ? currentUser.type : 1
        }
        return params1
    }, [params])
最后 将useCallback注释掉就好了,或者在useCallback的依赖中加上paramsMemo,不过这样一来二去显得很繁琐了,目前没有找到最好的使用useMemo,useCallback的套路。
const rightControlButton =
        //  useCallback(
        (row: DataManagement.DataManagementListItem) => {
            switch (row.lineStatus) {
                case null:
                case 1:
                    return (
                        < Button type="link" onClick={() => handlerAction(row, 'offline')} title="下线">
                            <BdpIcon type="iconxiaxian" color="#3954FF"></BdpIcon>
                        </Button>
                    )
                case 0:
                    return (
                        <Button type="link" onClick={() => handlerAction(row, 'online')} title="启用">
                            <BdpIcon type="iconshangxian" color="#3954FF"></BdpIcon>
                        </Button>
                    );
                case 2:
                default:
                    // 流程中和其他的状态展示上线的图标,但是要置灰!
                    return (
                        <Button type="link" disabled>
                            <BdpIcon type="iconshangxian" color="#DDD"></BdpIcon>
                        </Button>
                    )
            }
        }
    //  [])
测试
import React,{useMemo,useCallback,useState} from 'react';
const Test=()=>{
    const [state,setState]=useState(10);
    function handle(){
        alert(state)
    }
    let getNum=useCallback(()=>{

        return (
            <>
            {/* 由于没有依赖,而每次渲染都有自己的props和state,所以这个state是一直不会变的,
            handle执行的时候按照作用域,应该是打印全局作用域的state,
            但是这个时候的整个作用域的state就是初始的那个state */}
            <h1>{state}</h1> 
            <button onClick={()=>{handle()}}>试试</button>
            </>
        )
    },[])
    return(
        <>
            <h1>{state}</h1>
            <button onClick={()=>{setState(state+1)}}>添加</button>
            {getNum()}
        </>
    )
}
export default Test;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值