useState疑问

最近在学习React,在useState部分被困扰了半天,分享一下问题!如下代码:

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

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`Count updated to ${count}`);
  }, [count]);

  const increment = () => {
    setCount(count + 1);
  };

  const reset = () => {
    setCount(0);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
}

export default Counter;

流程解析

  1. 初始状态

    • count 为 0
    • 页面显示 0
    • 输出 Count updated to 0
  2. 状态值不同的情况

    • 用户点击“Increment”按钮,调用 setCount(count + 1)
    • count 变为 1
    • 页面显示 1
    • 输出 Count updated to 1
  3. 状态值不同的情况

    • 用户点击“Reset”按钮,调用 setCount(0)
    • count 变为 0
    • 页面显示 0(记作 01)。
    • 输出 Count updated to 0
  4. 状态值相同的情况

    • 用户再次点击“Reset”按钮,调用 setCount(0)
    • count 仍然是 0
    • React 检查状态值是否相同(当前值为 0,新值也是 0)。
    • 由于值相同,React 不会触发实际的 DOM 更新。
    • 但是,React 会执行一次“比较渲染”,确保状态的一致性。
    • 输出 Count updated to 0(记作 02)。

最终显示的值

  • 最终状态值:最后一次调用 setCount(0) 后,状态值仍然是 0
  • 页面显示的值:页面显示的值是最后一次更新后的 0(记作 02)。

总结

  1. 内存地址:尽管 01 和 02 的内存地址不同,页面上显示的值仍然是 0
  2. 实际渲染 vs. 比较渲染:当状态值相同但 setCount 被调用时,React 会执行一次“比较渲染”,确保状态的一致性,但不会实际更新 DOM。
  3. 页面显示:页面显示的值是最后一次更新后的 0(记作 02)。

这个时候我的疑问出来了,明明01到02的变化是实实在在的替换,虽然是0 -->0的过程,但应该也算是重新渲染,为什么却叫做“比较渲染”。最后查了半天才发现是我钻牛角尖了。

从 01 到 02 的过程虽然涉及状态值的重新赋值,但由于值相同,React 不会触发实际的 DOM 更新。页面上的显示值仍然是 0,只是内存地址不同。这种情况下不算实际的重新渲染。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
手写 useState 的主要目的是为了理解其运行原理。在手写过程中,可以参考 React 官方文档中对于 useState 的介绍,以及引用中提到的原理。 手写 useState 的核心思想是使用闭包来保存状态,并提供更新状态的方法。具体步骤如下: 1. 首先,定义一个函数,例如 useState,该函数接收一个初始值作为参数。 2. 在函数内部,创建一个变量,用于保存状态的值,默认设置为初始值。 3. 接着,创建一个函数,用于更新状态的值。这个函数将会被返回,并且可以在组件中调用。 4. 在更新状态的函数中,使用闭包来保存状态的值,并通过参数获取新的状态值。 5. 最后,将状态的值和更新状态的函数作为一个数组返回。 通过以上步骤,就可以手写一个简单的 useState。例如,可以参考引用中的代码示例,其中使用了 useState 来管理一个计数器的状态。 需要注意的是,手写的 useState 仅仅是为了了解其运行原理,并不能完全替代 React 提供的 useState。在实际开发中,建议使用 React 提供的 hooks API 来管理组件的状态。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [手写useStateuseEffect](https://blog.csdn.net/qq_40413670/article/details/124518502)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小佟Q_Q!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值