返回顶部
首页 > 资讯 > 前端开发 > JavaScript >详解React Hooks是如何工作的
  • 839
分享到

详解React Hooks是如何工作的

2024-04-02 19:04:59 839人浏览 安东尼
摘要

目录1. React Hooks VS 纯函数2. 简单 myUseState3. 改进 myUseState4. 实现原理引发的 Hooks 规则1. React Hooks VS

1. React Hooks VS 纯函数

React Hook 说白了就是 React V18.6 新增的一些 api,API的本质就是提供某种功能的函数接口。因此,React Hooks 就是一些函数,但是 React Hooks 不是纯函数。

什么是纯函数呢?就是此函数在相同的输入值时,需产生相同的输出,并且此函数不能影响到外面的数据。
简单理解就是函数里面不能用到在外面定义的变量,因为如果用到了外面定义的变量,当外面的变量改变时会影响函数内部的计算,函数也会影响到外面的变量。

对于 React Hooks 提供的函数 API,恰恰就不是纯函数。
来看一个 useState 的使用语句 const [count, setCount] = useState(0),使用 useState 函数得到的结果并不是全都一样的,因为如果 useState(0) 每次得到的结果都是一样的,那 count 值就永远不会改变了,那 count 所在的页面就永远不会改变,和我们看到的结果就不一样了。由此可知,React Hooks 都不是纯函数,也就是说 Hooks 用到了函数外的变量。

那么是什么特性让 React Hooks 一定不能是纯函数呢?实际上是 React 框架和函数组件本身决定的。我们知道,React 页面渲染的原理就是通过每次 render 得到新的虚拟 DOM ,然后进行 DOM Diff 来渲染页面。而 React 的函数组件是通过执行整个函数得到一个虚拟 DOM。因此在每次页面渲染 render 时,在函数组件内部的所有语句都会重新执行一次。如果在函数组件内部使用的 React Hooks 是纯函数的话,就不会在每次渲染后得到不同的虚拟 DOM 了。

React 规定: 所有 React 组件都必须是纯函数,并禁止修改其自身 props 。

因此在 React V16.8 之前 React Hooks 还没出来的时候,函数组件因为是纯函数,只能返回一个固定的虚拟 DOM,不能包含状态,也不支持生命周期方法。因此,当时仅仅是支持函数组件,但函数组件相比于类组件限制太多,函数组件无法取代类组件,也没类组件好用。

React 希望组件是简单的而不是复杂的,React 认为组件的最佳写法应该是函数,而不是类。因此 React 就新增了 React Hooks,Hook 就是钩子的意思,是 React 提供给函数组件在需要外部功能和数据状态时将其 “钩” 进去,从而完善函数组件,使其能完全代替类组件。

React 的函数组件只能是纯函数,那么每次事件发生时重新 render 函数组件时得到不同的虚拟 DOM 的事就完全交给了 React Hooks,那么 React Hooks 是如何做到的呢?下面就手动实现一个 useState,useState 的具体细节肯定不是这样的,但原理和思路是一样的。

2. 简单 myUseState

React.useState 的第一次执行是将初始值赋予给一个 _state,之后的每次重新 render 时就是读取 _state 的值。[state, setState] 中的 setState 做的事就是改变 _state 的值,然后重新渲染页面。
根据这个原理实现 myUseState 函数如下:


import React from 'react';
import ReactDOM from 'react-dom';

let _state

function myUseState(initialValue){
  if(_state === undefined){
    _state = initialValue
  }
  const setState = (newValue)=>{
    _state = newValue
    render()
  }
  return [_state, setState]
}

function render(){
  ReactDOM.render(<App/>,document.getElementById('root'));
}

function App(){
  const [n, setN] = myUseState(0)
  return (
    <div>
      n: {n}
      <button onClick={() => setN(n+1)}>+1</button>
    </div>
  )
}

ReactDOM.render(<App/>,document.getElementById('root'));

3. 改进 myUseState

上述实现的 myUseState 存在 bug,当在函数组件内用到两次 myUseState 时就会出现问题了,二者共用一个 _state 会出现混乱。
因此需要将上述实现进行改进,改进的思路就是将 _state 定义为一个数据或者是对象,由于我们在函数使用时只传了一个数值,无法确定键值,因此只能使用数据。改进如下:


import React from 'react';
import ReactDOM from 'react-dom';

let _state = []
let index = 0

function myUseState(initialValue){
  const currentIndex = index
  if(_state[currentIndex] === undefined){
    _state[currentIndex] = initialValue
  }
  const setState = (newValue)=>{
    _state[currentIndex] = newValue
    render()
  }
  index++
  return [_state[currentIndex], setState]
}

function render(){
  index = 0
  ReactDOM.render(<App/>,document.getElementById('root'));
}

function App(){
  const [n, setN] = myUseState(0)
  const [m, setM] = myUseState(0)
  return (
    <div>
      n: {n}
      <button onClick={() => setN(n+1)}>+1</button>
      <br/>
      m: {m}
      <button onClick={() => setM(m+1)}>+1</button>
    </div>
  )
}

ReactDOM.render(<App/>,document.getElementById('root'));

4. 实现原理引发的 Hooks 规则

上述实现的 myUseState 肯定不是 React.useState 的具体实现代码,但实现原理是一致的。myUseState 函数封装了函数组件内的数据状态,并对该状态进行管理,以暴露出相关的操作接口的方式提供给函数组件使用。
这样一来,函数组件就和其数据状态分离了,函数组件只负责返回虚拟 DOM 本身就可以了,对于数据状态的管理完全交给其 “钩” 住的 React.useState Hook 就可以了。

从上述的实现思路可以发现,React Hooks 的实现其实是基于 全局变量 和 闭包 原理实现的特殊函数。

但是,正是因为这样的实现方式,限制了 React Hooks 的使用必须是 只在顶层调用Hook,意思就是说 不要在循环,条件或嵌套函数中调用 Hook,如果在 if 条件句中使用了 Hook, 导致组件每次渲染生成时 React.useState 语句的执行次数不对,就会打乱 index 的计数,从而导致数据维护的错误。

上述的实现原理依赖于 index 的正确计数,因此 React 依赖于调用 Hooks 的顺序,

以上就是详解React Hooks是如何工作的的详细内容,更多关于详解React Hooks的资料请关注编程网其它相关文章!

--结束END--

本文标题: 详解React Hooks是如何工作的

本文链接: https://lsjlt.com/news/126041.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详解React Hooks是如何工作的
    目录1. React Hooks VS 纯函数2. 简单 myUseState3. 改进 myUseState4. 实现原理引发的 Hooks 规则1. React Hooks VS...
    99+
    2024-04-02
  • React中Hooks是如何工作的
    React中Hooks是如何工作的?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1. React Hooks VS 纯函数React Hook 说白了就是 Re...
    99+
    2023-06-15
  • 详解如何构建自己的react hooks
    目录1. 常用的一个 hooks1.1 useState: 状态钩子1.2 useEffect: 副作用钩子1.3 useMemo 和 useCallback2. 实现几个自定义的 ...
    99+
    2024-04-02
  • React hooks的优缺点详解
    目录前言 优点:缺点:一、响应式的useEffect 二、状态不同步 怎么避免react hooks的常见问题 前言 Hook 是 React 16.8 的新增特性。它是完全可选的...
    99+
    2024-04-02
  • 详解React Fiber的工作原理
    目录啥是React Fiber? 为什么会有React Fiber? React Fiber到底怎么工作的? React Fiber的实现原理 React Fiber对我们日常开发有...
    99+
    2024-04-02
  • 基于React Hooks的小型状态管理详解
    目录实现基于 React Hooks 的状态共享使用感受本文主要介绍一种基于 React Hooks 的状态共享方案,介绍其实现,并总结一下使用感受,目的是在状态管理方面提供多一种选...
    99+
    2024-04-02
  • 如何理解React受控组件Hooks方式
    这篇文章主要介绍“如何理解React受控组件Hooks方式”,在日常操作中,相信很多人在如何理解React受控组件Hooks方式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2024-04-02
  • 浅谈React中的浅比较是如何工作的
    React 中浅比较的概念无处不在,它在不同的流程中起着关键的作用,也可以在React组件的多个生命周期中找到。比如,React Hooks中的依赖数组,通过React.memo进行...
    99+
    2024-04-02
  • hooks写React组件的5个注意细节详解
    目录正文01.不需要render的场景下使用useState02.使用了router.push而非link03.通过useEffect来处理actions04.单一职责组件05.单一...
    99+
    2023-03-13
    hooks写React组件 React hooks
  • 使用 React Hooks 重构类组件的示例详解
    目录1. 管理和更新组件状态2. 状态更新后的操作3. 获取数据4. 卸载组件时清理副作用5.  防止组件重新渲染6. Context API7. 跨重新渲染保留值8. 如...
    99+
    2024-04-02
  • 详解react hooks组件间的传值方式(使用ts)
    目录父传子子传父跨级组件(父传后代)父传子 通过props传值,使用useState来控制state的状态值 父组件 Father.tsx里: 子组件 Child.tsx里: ...
    99+
    2024-04-02
  • React调度系统Scheduler工作原理详解
    目录简介什么是Scheduler?Scheduler的工作原理使用Scheduler的场景代码示例1. 延迟执行任务2. 调整任务的优先级3. 批量更新状态总结简介 React是目...
    99+
    2023-03-13
    React Scheduler调度系统 React Scheduler
  • 如何实现基于React Hooks的状态共享
    这篇文章主要介绍了如何实现基于React Hooks的状态共享,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。实现基于 React Hooks 的状态共享React 组件间的状...
    99+
    2023-06-22
  • 详解React中key的作用
    目录问题: 点击按钮的时候,span的颜色会变成红色吗?分析上述问题:第二种情况:key的取值为索引值第三种情况:key的取值确定且唯一:如果想要达到预期效果,我们要设置唯一且确定的...
    99+
    2024-04-02
  • Flex是如何工作的
    小编给大家分享一下Flex是如何工作的,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Flex是如何工作的该部分文档的内容是为用户提供关于AdobeFlex工作机制...
    99+
    2023-06-17
  • cdn是如何工作的
    CDN(内容分发网络)是一种通过在全球分布式网络中放置服务器来加速内容传输的技术。它的工作原理如下:1. 缓存内容:CDN将原始内容...
    99+
    2023-08-25
    cdn
  • React中的浅比较是怎么工作的
    这篇文章主要介绍了React中的浅比较是怎么工作的的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇React中的浅比较是怎么工作的文章都会有所收获,下面我们一起来看看吧。想要理解浅比较的概念,最直接的方法就是研究...
    99+
    2023-06-30
  • git hooks的作用及创建使用示例详解
    目录1. 什么是git hooks ?有什么用啊?1.1 是个啥1.2 有啥用?我以前没用过它不也一样好好的吗?我干嘛要用它?2. 怎么创建一个 git hooks ?2.1 首先看...
    99+
    2024-04-02
  • 详解React 如何防止 XSS 攻击论$$typeof 的作用
    目录JSXXSS 攻击防止 XSS 攻击的方法React 对于文本节点的处理dangerouslySetInnerHTML 处理富文本节点$$typeof 的作用JSX 先来简单复习...
    99+
    2024-04-02
  • Vue3 Teleport是如何工作的
    这篇文章主要讲解了“Vue3 Teleport是如何工作的”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Vue3 Teleport是如何工作的”吧!Tele...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作