• React Hooks使用经验以及技巧


    最近一段时间都在使用React Hooks,简单记录下使用技巧,比较常用的hook有:useState、useEffect、useRef、useMemo、useCallback…

    hook通用规则:

    1. 只在 React 函数中调用 Hook。
    2. 不要在循环、条件或嵌套函数中调用 Hook。

    一.useState

    // name 和 setName 名称自己定义
    const [name,setName] = useState('')
    
    // 更改 name 为 ‘aquan’
    const onClick = () = >{
    	setName('aquan')
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    useState是用来存储状态的hook,其中 name 表示变量名称,setName表示改变state的函数,useState接受一个参数,这个参数为 state 的初始化值。

    用法是比较简单的,但是需要注意的点有
    1. 在 setName 后立马打印 name 是获取不到最新的值的,因为 useState 是异步的,如果想要获取新的值之后做什么操作,可以参考下面的 useEffect
    2. 调用多次 setName 只会以最后一次为准,例如:

    const onClick = () = >{
    	setName('aquan')
    	setName('quan')
    	// 最后 name 的值为 quan
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果你的值基于上一次更新,setName 可以接受一个函数,参数会有上一次更新的值

    const onClick = () = >{
    	setName('aquan')
    	setName((val)=>val+'-demo')
    	// 最后 name 的值为 aquan-demo
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.每次调用 setName 会导致组件重新更新一次,为了优化体验,有时候尽量把多个setState改成一个,避免多次渲染

    const onClick = () = >{
    	setName('aquan')
    	setAge(18)
    	// 会导致组件刷新两次,在setName完成后刷新一次,在setAge完成后又刷新一次
    	// 可以改为
    	setData({name:'aquan',age:18})
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    二.useEffect

    useEffect可以让你在一些情况下,执行自己的想添加的操作,例如:监听state变化时,组件加载完成时,组件销毁时。
    useEffect接受两个参数,第一个参数为函数,可以传入用户想要执行的操作,第二个参数为监听项,但第二个参数变化时,会执行用户传入的函数
    1.监听state变化时(useEffect第二个参数有值,当然因为是数组也可以传多个state监听)

    useEffect(()=>{
    	// state初始化的时候也会进来一次
    	console.log(name)
    },[name])
    
    • 1
    • 2
    • 3
    • 4

    这个一般用于,在某个值变化的时候执行自己的操作,例如:有一个搜索功能,有好几个下拉框,在用户选择下拉框的时候,你希望能请求一下数据查询

    const [query,setQuery] = useState({})
    
    const handleChangeSelect = () => {
    	setQuery({level:1})
    	// 如果你有多个参数,建议改为
    	setQuery((val)=>{...val,level:1})
    	// 或
    	setQuery({...query,level:1})
    	// 避免更改覆盖了之前query的除开level其他值
    }
    
    const getData = (params) => {
    	// 根据参数请求接口重新查询数据
    }
    
    useEffect(()=>{
    	getData(query)
    },[query])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.组件加载完成时(第二个参数为空数组)

    useEffect(()=>{
      // 组件加载完成时,一般用于组件刚进来获取数据,调用接口
      getData()
    },[])
    
    • 1
    • 2
    • 3
    • 4

    3.组件被销毁时(return了一个函数)

    useEffect(()=>{
      return  () => {
      // 组件被销毁时调用 一般用于清除定时器或者销毁前的一些操作
       console.log('组件销毁')
      }
    },[])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三.useRef

    useRef一般用于获取dom元素

    const testRef = useRef()
    
    // dom元素
    <div ref={testRef} id='test'>测试文本</div>
    
    // 此时testRef 等于,可以直接拿到dom元素
    testRef.current  =  document.getElementById('test')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    有时候也可以用作变量存储,或者存定时器,用名称.current去赋值和获取

    const timerRef = useRef()
    
    useEffect(()=>{
    // 组件加载完成,设置定时器
      timerRef.current = setInterval(()=>{
      	console.log('时间正在流逝')
      },[1000])
    	return ()=>{
    	//组件销毁时清除定时器
    	  clearInterval(timer.current);
    	}
    },[])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注意: 使用useRef当做变量存储的话,变量如果发生更新,组件不会重新渲染,所以一般还是用useState存储状态,除非个别情况下用第三方插件可能导致useState拿不到新更新的值。

    四.useMemo

    useMemo涉及到性能优化这块了,可以让一些变量避免重复声明,同样接受两个参数,第一个是回调函数,第二个是数组

    const demo = () => {
      const [count, setCount] = useState(0);
      const [status, setStatus] = useState(0);
    
      // 每次组件更新都会重新声明一次,点击改变状态也会导致重新声明
      const isBigNum =  count > 1
      // 使用useMemo可以让变量只在加载完成时更新,以及监听对象更新时重新声明
      const isBigNum = useMemo(()=> count > 1,[count])
    
      const handleOnClick = ()=>{
      	  setCount(val=>val+1)
      }
      
      const handleOnChangeStatus = ()=>{
      	  setStatus(!status)
      }
    
      return (<div>
    	<div onClick={handleOnClick}> 点我+1 </div>
    	<div onClick={handleOnChangeStatus}> 点我改变状态 </div>
        </div>);
    };
    
    export default demo;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    前端使用 Konva 实现可视化设计器(2)
    【MySQL】初步认识
    Python每日一练 01
    记录:2022-9-19 螺旋矩阵 球会落何处 分页分区
    [每周一更]-(第61期):Rust入门策略(持续更新)
    java有关的HttpsUtils工具类 https请求工具类
    洗地机哪款最好用?口碑最好的家用洗地机推荐
    Docker-查看镜像仓库中镜像的版本信息
    Word自动生成目录的方法
    软件测试工程师的核心竞争力是什么?
  • 原文地址:https://blog.csdn.net/weixin_44457418/article/details/132986604