前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >useRef与createRef的区别2

useRef与createRef的区别2

原创
作者头像
挥刀北上
修改2021-02-26 10:20:18
5510
修改2021-02-26 10:20:18
举报
文章被收录于专栏:Node.js开发

首先看两段代码:

代码语言:javascript
复制
import ReactDOM from 'react-dom';
import './index.css';
import React,{useState,useEffect,useRef,createRef} from 'react';
const App = () => {
    const [count, setCount] = useState(0);
    const lastCount = createRef(count);
    useEffect(() => {
        lastCount.current = count;
    })
    function handleAlertClick() {
        setTimeout(() => {
            alert(lastCount.current)
        }, 3000);
    }
    return <div>
        <p>你点击了{count}次</p>
        <button onClick={() => setCount(count + 1)}>click me</button>
        <button onClick={handleAlertClick}> show Alert</button>
    </div>
}
ReactDOM.render(
    <App />,
    document.getElementById('root')
);

再看第二段:

代码语言:javascript
复制
import ReactDOM from 'react-dom';
import './index.css';
import React,{useState,useEffect,useRef,createRef} from 'react';
const App = () => {
    const [count, setCount] = useState(0);
    const lastCount = useRef(count);
    useEffect(() => {
        lastCount.current = count;
    })
    function handleAlertClick() {
        setTimeout(() => {
            alert(lastCount.current)
        }, 3000);
    }
    return <div>
        <p>你点击了{count}次</p>
        <button onClick={() => setCount(count + 1)}>click me</button>
        <button onClick={handleAlertClick}> show Alert</button>
    </div>
}
ReactDOM.render(
    <App />,
    document.getElementById('root')
);

页面渲染如下:

那么当多次点击第一个按钮,中途点击一下第二个按钮,然后再点击第一个按钮,弹窗弹出的数字是什么样的,解释一下流程。

两段代码的执行结果是不一样的:

首先使用了useRef的代码,我的理解是这个函数创建的lastCount对象,其指向的地址存储在函数的作用外面,也就是说函数之后再怎么执行lastCount的值不会发生变化,lastCount始终指向某一个内存地址。

再看代码,如果lastCount始终指向某个固定的内存地址,那么修改其上面的属性,不论修改多少次,当用异步方式读取时都会读取到最后一次修改的结果。

而是用createRef就不同了,调用createRef每次得到的对象都是最新的,每次得到的lastCount都是独立的,并且其存储的位置就是在函数的内部,而不是像useRef创建的lastCount存储到函数作用域外面,这样当用异步方式也就是settimeout方式读取createRef创建的lastCount时,每次读取都是读取的当前作用域的lastCount,所以每次都是不同的值,而不是最后修改的值。

类比如下代码:

代码语言:javascript
复制
 for (var i = 0; i < 10; i++) {
    //定义lastCount
    setTimeout(() => {
        console.log((i.current)
    }, 3000)
}

代码语言:javascript
复制
 for (let i = 0; i < 10; i++) {
    //定义lastCount
    setTimeout(() => {
        console.log((i.current)
    }, 3000)
}

第一段的i存储在全局,第二个i存在每个循环的单独作用域中,以上便是我对useRef和createRef的区别的理解,希望对你有所帮助。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档