前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >react源码解析14.手写hooks

react源码解析14.手写hooks

原创
作者头像
zz1998
发布于 2021-12-04 01:26:12
发布于 2021-12-04 01:26:12
27200
代码可运行
举报
运行总次数:0
代码可运行

react源码解析14.手写hooks

视频讲解(高效学习):进入学习

最关键的是要理解hook队列和update队列的指针指向和updateQueue的更新计算,详细见视频讲解

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import React from "react";
import ReactDOM from "react-dom";

let workInProgressHook;//当前工作中的hook
let isMount = true;//是否时mount时

const fiber = {//fiber节点
  memoizedState: null,//hook链表
  stateNode: App//dom
};

const Dispatcher = (() => {//Dispatcher对象
  function mountWorkInProgressHook() {//mount时调用
    const hook = {//构建hook
      queue: {//更新队列
        pending: null//未执行的update队列
      },
      memoizedState: null,//当前state
      next: null//下一个hook
    };
    if (!fiber.memoizedState) {
      fiber.memoizedState = hook;//第一个hook的话直接赋值给fiber.memoizedState
    } else {
      workInProgressHook.next = hook;//不是第一个的话就加在上一个hook的后面,形成链表
    }
    workInProgressHook = hook;//记录当前工作的hook
    return workInProgressHook;
  }
  function updateWorkInProgressHook() {//update时调用
    let curHook = workInProgressHook;
    workInProgressHook = workInProgressHook.next;//下一个hook
    return curHook;
  }
  function useState(initialState) {
    let hook;
    if (isMount) {
      hook = mountWorkInProgressHook();
      hook.memoizedState = initialState;//初始状态
    } else {
      hook = updateWorkInProgressHook();
    }

    let baseState = hook.memoizedState;//初始状态
    if (hook.queue.pending) {
      let firstUpdate = hook.queue.pending.next;//第一个update

      do {
        const action = firstUpdate.action;
        baseState = action(baseState);
        firstUpdate = firstUpdate.next;//循环update链表
      } while (firstUpdate !== hook.queue.pending);//通过update的action计算state

      hook.queue.pending = null;//重置update链表
    }
    hook.memoizedState = baseState;//赋值新的state

    return [baseState, dispatchAction.bind(null, hook.queue)];//useState的返回
  }

  return {
    useState
  };
})();

function dispatchAction(queue, action) {//触发更新
  const update = {//构建update
    action,
    next: null
  };
  if (queue.pending === null) {
    update.next = update;//update的环状链表
  } else {
    update.next = queue.pending.next;//新的update的next指向前一个update
    queue.pending.next = update;//前一个update的next指向新的update
  }
  queue.pending = update;//更新queue.pending

  isMount = false;//标志mount结束
  workInProgressHook = fiber.memoizedState;//更新workInProgressHook
  schedule();//调度更新
}

function App() {
  let [count, setCount] = Dispatcher.useState(1);
  let [age, setAge] = Dispatcher.useState(10);
  return (
    <>
      <p>Clicked {count} times</p>
      <button onClick={() => setCount(() => count + 1)}> Add count</button>
      <p>Age is {age}</p>
      <button onClick={() => setAge(() => age + 1)}> Add age</button>
    </>
  );
}

function schedule() {
  ReactDOM.render(<App />, document.querySelector("#root"));
}

schedule();

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
react源码解析14.手写hooks
手写hooks最关键的是要理解hook队列和update队列的指针指向和updateQueue的更新计算
长腿程序员165858
2022/11/16
2370
react源码解析14.手写hooks
最关键的是要理解hook队列和update队列的指针指向和updateQueue的更新计算,详细见视频讲解
全栈潇晨
2021/06/17
4540
来来来,手摸手写一个hook
来来来,手摸手写一个hook hello,这里是潇晨,今天就带着大家一起来手写一个迷你版的hooks,方便大家理解hook在源码中的运行机制,配有图解,保姆级的教程,只求同学一个小小的 第一步:引入React和ReactDOM 因为我们要将jsx转变为virtual-dom,这一步分工作就交给babel吧,而jsx被babel进行词法解析之后会形成React.createElement()的调用,而React.createElement()执行之后的返回结果就是jsx对象或者叫virtual-dom。 又因
全栈潇晨
2021/12/09
5380
React源码分析(三):useState,useReducer
大家都知道hooks是在函数组件的产物。之前class组件为什么没有出现hooks这种东西呢?
goClient1992
2022/09/27
9190
React 架构的演变 - Hooks 的实现
“这是这个系列的最后一篇文章了,终于收尾了? 。 React Hooks 可以说完全颠覆了之前 Class Component 的写法,进一步增强了状态复用的能力,让 Function Compone
桃翁
2020/11/11
5780
React 架构的演变 - Hooks 的实现
从React源码来学hooks是不是更香呢
要理解 hooks 的执行过程,首先想要大家对 hooks 相关的数据结构有所了解,便于后面大家顺畅地阅读代码。
goClient1992
2022/10/04
7150
【React】946- 一文吃透 React Hooks 原理
之前的两篇文章,分别介绍了react-hooks如何使用,以及自定义hooks设计模式及其实战,本篇文章主要从react-hooks起源,原理,源码角度,开始剖析react-hooks运行机制和内部原理,相信这篇文章过后,对于面试的时候那些hooks问题,也就迎刃而解了。实际react-hooks也并没有那么难以理解,听起来很cool,实际就是函数组件解决没有state,生命周期,逻辑不能复用的一种技术方案。
pingan8787
2021/05/14
2.8K0
【React】946- 一文吃透 React Hooks 原理
从React源码来学hooks是不是更香呢_2023-02-28
要理解 hooks 的执行过程,首先想要大家对 hooks 相关的数据结构有所了解,便于后面大家顺畅地阅读代码。
goClient1992
2023/02/28
7520
带你深入了解 useState
为什么 react 16 之前的函数组件没有状态? 众所周知,函数组件在 react 16 之前是没有状态的,组件状态只能通过 props 进行传递。 写两个简单的组件,一个类组件和一个函数组件: const App = () =><span>123</span>; class App1 extends React.Component {  constructor(props) {    super(props);    this.state = {      a: 1,    }  }  
用户1097444
2022/06/29
1.8K0
带你深入了解 useState
React Hooks 源码解析(3):useState
React 源码版本: v16.11.0 源码注释笔记:airingursb/react 在写本文之前,事先阅读了网上了一些文章,关于 Hooks 的源码解析要么过于浅显、要么就不细致,所以本文着重讲解源码,由浅入深,争取一行代码也不放过。那本系列讲解第一个 Hooks 便是 useState,我们将从 useState 的用法开始,再阐述规则、讲解原理,再简单实现,最后源码解析。另外,在本篇开头,再补充一个 Hooks 的概述,前两篇限于篇幅问题一直没有写一块。 注:距离上篇文章已经过去了两个月,这两
QQ音乐前端团队
2019/12/03
1.9K1
React Hooks 源码解析(3):useState
烧脑预警,这波心智负担有点重,深度探讨 useState 的实现原理
在前面的一篇文章中,我们介绍了 Fiber 的详细属性所代表的含义。在函数式组件中,其中与 hook 相关的属性为 memoizedState
用户6901603
2024/01/10
3380
烧脑预警,这波心智负担有点重,深度探讨 useState 的实现原理
全网最简单的React Hooks源码解析!
从React Hooks发布以来,整个社区都以积极的态度去拥抱它、学习它。期间也涌现了很多关于React Hooks 源码解析的文章。本文就以笔者自己的角度来写一篇属于自己的文章吧。希望可以深入浅出、图文并茂的帮助大家对React Hooks的实现原理进行学习与理解。本文将以文字、代码、图画的形式来呈现内容。主要对常用Hooks中的 useState、useReducer、useEffect 进行学习,尽可能的揭开Hooks的面纱。
Nealyang
2022/04/11
2.1K0
全网最简单的React Hooks源码解析!
react源码解析13.hooks源码
​ 在hook源码中hook存在于Dispatcher中,Dispatcher就是一个对象,不同hook 调用的函数不一样,全局变量ReactCurrentDispatcher.current会根据是mount还是update赋值为HooksDispatcherOnMount或HooksDispatcherOnUpdate
全栈潇晨
2021/06/16
6910
ReactHooks源码解析之useState及为什么useState要按顺序执行
从本篇开始,我们讲 React-Hooks 最常用的几个函数,先通过例子来看下React.useState():
进击的小进进
2020/05/17
3.8K0
深入react源码看setState究竟做了什么?
在深究 React 的 setState 原理的时候,我们先要考虑一个问题:setState 是异步的吗?
flyzz177
2023/01/05
5120
相关推荐
react源码解析14.手写hooks
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文