react-hooks知识梳理—3.useRef

1.回忆useEffect的问题

————————————————————————————————————————————————

想实现一个定时器的效果,每0.5s count加1

import React, { useState, useEffect } from 'react';
 
const Fetch = () => {
  const [count, setCount] = useState(0);
 
  useEffect(() => {
    setInterval(() => {
      setCount(count + 1 );
    }, 500);
  }, []);
 
  return (
    <div>
      count: {count}
    </div>
  )
};
 
function UseEffect() {
  return (
    <div className="App">
      <Fetch />
    </div>
  );
}
 
export default UseEffect;

但是执行一下,加了1就不动了

因为useEffect有一个特性是catpurrvalue,,就是没有任何依赖的情况下,会捕获初始传进来的值,后面不会在变化。所以看下面控制台里面每次打印都是0。

————————————————————————————————————————————————

useEffect添加一个依赖,这样依赖变化的时候,他就会跟着变化,有一个问题就是useEffect每次都会重新执行,即会产生一起新的回调,往往有时候不希望一些useEffect去执行,不执行的话就是不去添加依赖,但不添加依赖的话由于特性catpurrvalue,依赖的值可能是旧的,这样就会导致一个bug。这个时候useRef就登场了。

2.useRef功能一:作为变量

可以尝试用useRef解决上面的问题

import React, { useState, useEffect, useRef } from 'react';

const Fetch = () => {
  const [count, setCount] = useState(0);
  const countRef = useRef(null);

  useEffect(() => {
    countRef.current = count + 1;
  }, [count]);

  useEffect(() => {
    const timer = setInterval(() => {
      console.log(count, countRef.current);
      setCount(countRef.current);
    }, 500);
    return () => clearInterval(timer);
  }, []);

  return (
    <div>
      count: {count}
    </div>
  )
};

function UseRef() {
  return (
    <div className="App">
      <Fetch />
    </div>
  );
}

export default UseRef;

理解一下,useRef里面的crrent是在组件整个生命周期中,不会随着state的变化而变化,可以理解为组件内部的一个全局变量,其他地方都可以访问到他的最新值,除非手动的给他变化,即countRef.current = count这样。而state在useEffect里面,是有capturevalue的,不一定访问到他的最新值,除非添加依赖

3.useRef功能二:获取dom

import React, { useState, useEffect, useRef } from 'react';

const Fetch = () => {
  const [count, setCount] = useState(0);
  const btnRef = useRef(null);

  useEffect(() => {
    const handleOnClick = () => {
      setCount(count + 1);
    };
    btnRef.current.addEventListener('click', handleOnClick, false);
    return () => {
      btnRef.current.removeEventListener('click', handleOnClick, false);
    };
  }, [count]);

  return (
    <div>
      count: {count}
      <br/>
      <button ref={btnRef}>+1</button>
    </div>
  )
};

function UseRef() {
  return (
    <div className="App">
      <Fetch />
    </div>
  );
}

export default UseRef;

3.useRef其他功能

react实现了一些自己的事件,但他并没有覆盖全部的原生dom事件,比如说onClick事件是有的,但鼠标滚动的事件的一些事件是没有的,这样就需要自己使用dom去绑定,这个时候useRef就派上用场了。

当然可以通过绑定id的方式获取dom,但是这种方式存在一个问题,给人感觉你是直接在操作dom。而使用useRef方式并不是直接操作dom,操作dom被放在react内部了,并没有对你的程序代码造成破坏。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值