React16源码: Hooks源码实现

React-Hooks源码深度解读 使用 hooks 几个月了。基本上所有类组件我都使用函数式组件来写。现在 react 社区的很多组件,都也开始支持hooks。大概了解了点重要的源码,做到知其然也知其所以然,那么在实际工作中使用他可以减少不必要的 bug,提高效率。 阅读详情

Hooks

1 )概述

  • Hooks 在 React16.7版本出现的新功能
  • Hooks 改变了整体应用开发的模式,同时开发体验会和以前会变得不一样
  • Hooks 让函数组件具有类组件的能力
    • 在 function component 里面没有this无法保存 state
    • 通过 Hooks可以让 function component 代替 class component
    • Hooks 让函数组件变得更强大

2 )用例演示

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

export default () => {
  const [name, setName] = useState('Wang')

  useEffect(() => {
    console.log('component update')

    return () => {
      console.log('unbind')
    }
  }, [])

  return (
    <>
      <p>My Name is: {name}</p>
      <input type="text" value={name} onChange={e => setName(e.target.value)} />
    </>
  )
}
  • 这里声明了一个functional component ,在以前对比class component它缺少的是什么
    • 缺少就是this对象,它没有this对象,那么它就不能有 this.state
    • 它就具有包含自己本身的状态的这么一个功能
    • 它没有生命周期方法
  • 在这里面我们使用了hooks来给我们的组件去存储了 state
    • 使用 useState 传入了一个默认值是 Wang
    • 然后它返回一个数组,这是一个数组的解构
    • 这个数组第一项是state的对应的这个变量
    • 第二项是让我们去改变这个state的方法
    • 这就是我们通过useState返回给我们的唯一的两个东西
  • 然后我们就可以在我们渲染的过程当中去使用这个state了,同样可以去修改这个state
    • 比如说我们绑定了这个input的 onchange 事件
    • 就是去修改这个state,就是我们的name
    • 输入的内容之后它的state就自动更新
    • 在下一次渲染的时候能够拿到 state
  • 这就是hooks,它给 function component 提供了class component 所具有的能力
    • 它的意义不仅仅是为了替代 class compoment
    • 是想要去帮助我们去拆分一些在组件内部的逻辑
    • 把他们提取出来,能够给更多的组件进行一个复用
    • 以前在class compoment 里面是很难去拆分这部分逻辑的
  • 还有一个是跟 class component 的最大区别,就是生命周期方法
    • 在function component 里面,使用hooks可以通过一个叫做useEffect的这个API
    • 这个东西呢我们就可以传入一个方法,这个方法里面
    • 比如说,随便写一句 component updated
    • 在hooks里面,他没有着重的去区分 mounted 和 updated
    • 它的理念是 mounted和updated 都是 updated
    • 每一次有组件内容更新的时候都会去调用我们传入的这个 effect 回调函数
  • 如果需要事件绑定什么的,之前在unmount的时候,去解除事件绑定,那这时怎么办
    • 很简单,看到上面 return一个方法,这个方法就是解除我们的绑定,这边叫做 unbind
    • 在目前这种情况下,每一次有更新的时候都会先执行unbind,然后再重新bind
    • 这是比较符合react更新的一个逻辑的,就是在它有任何更新的时候
    • 都会把之前的状态全部消除,然后返回新的状态
  • 当然这对于一些事件监听的绑定不是特别友好, 解决方案如下
    • 把它改造成行为,类似于 componentDidMount 和 componentWillUnmount
    • 直接在这个 useEffect 传入第二个参数,然后传一个空数组
    • 比如说传入一个props来进行一个它是否有变化的一个区分
    • 如果传一个空数组,它就没有东西区分,就代表着只要执行一次
    • 这样,在输入改变state时,就没有了,只再刷新后,才会执行一次
  • 同样,在跳出的时候打印输出了 unbind
  • 这就是我们使用 hooks 模拟生命周期方法的一个用法

3 ) 源码分析

这个要在 React 16.7 版本上来找,在 React.js 中可看到

import {
  useCallback,
  // ... 很多 khoos
} from './ReactHooks';

现在定位到 ReactHooks.js

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {
  MutableSource,
  MutableSourceGetSnapshotFn,
  MutableSourceSubscribeFn,
  ReactContext,
} from 'shared/ReactTypes';
import type {OpaqueIDType} from 'react-reconciler/src/ReactFiberHostConfig';

import invariant from 'shared/invariant';

import ReactCurrentDispatcher from './ReactCurrentDispatcher';

type BasicStateAction<S> = (S => S) | S;
type Dispatch<A> = A => void;

function resolveDispatcher() {
  const dispatcher = ReactCurrentDispatcher.current;
  invariant(
    dispatcher !== null,
    'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
      ' one of the following reasons:\n' +
      '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
      '2. You might be breaking the Rules of Hooks\n' +
      '3. You might have more than one copy of React in the same app\n' +
      'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.',
  );
  return dispatcher;
}

export function useContext<T>(
  Context: ReactContext<T>,
  unstable_observedBits: number | boolean | void,
): T {
  const dispatcher = resolveDispatcher();
  if (__DEV__) {
    if (unstable_observedBits !== undefined) {
      console.error(
        'useContext() second argument is reserved for future ' +
          'use in React. Passing it is not supported. ' +
          'You passed: %s.%s',
        unstable_observedBits,
        typeof unstable_observedBits === 'number' && Array.isArray(arguments[2])
          ? '\n\nDid you call array.map(useContext)? ' +
              'Calling Hooks inside a loop is not supported. ' +
              'Learn more at https://reactjs.org/link/rules-of-hooks'
          : '',
      );
    }

    // TODO: add a more generic warning for invalid values.
    if ((Context: any)._context !== undefined) {
      const realContext = (Context: any)._context;
      // Don't deduplicate because this legitimately causes bugs
      // and nobody should be using this in existing code.
      if (realContext.Consumer === Context) {
        console.error(
          'Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be ' +
            'removed in a future major release. Did you mean to call useContext(Context) instead?',
        );
      } else if (realContext.Provider === Context) {
        console.error(
          'Calling useContext(Context.Provider) is not supported. ' +
            'Did you mean to call useContext(Context) instead?',
        );
      }
    }
  }
  return dispatcher.useContext(Context, unstable_observedBits);
}

export function useState<S>(
  initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
  const dispatcher = resolveDispatcher();
  return dispatcher.useState(initialState);
}

export function useReducer<S, I, A>(
  reducer: (S, A) => S,
  initialArg: I,
  init?: I => S,
): [S, Dispatch<A>] {
  const dispatcher = resolveDispatcher();
  return dispatcher.useReducer(reducer, initialArg, init);
}

export function useRef<T>(initialValue: T): {|current: T|} {
  const dispatcher = resolveDispatcher();
  return dispatcher.useRef(initialValue);
}

export function useEffect(
  create: () => (() => void) | void,
  deps: Array<mixed> | void | null,
): void {
  const dispatcher = resolveDispatcher();
  return dispatcher.useEffect(create, deps);
}

export function useLayoutEffect(
  create: () => (() => void) | void,
  deps: Array<mixed> | void | null,
): void {
  const dispatcher = resolveDispatcher();
  return dispatcher.useLayoutEffect(create, deps);
}

export function useCallback<T>(
  callback: T,
  deps: Array<mixed> | void | null,
): T {
  const dispatcher = resolveDispatcher();
  return dispatcher.useCallback(callback, deps);
}

export function useMemo<T>(
  create: () => T,
  deps: Array<mixed> | void | null,
): T {
  const dispatcher = resolveDispatcher();
  return dispatcher.useMemo(create, deps);
}

export function useImperativeHandle<T>(
  ref: {|current: T | null|} | ((inst: T | null) => mixed) | null | void,
  create: () => T,
  deps: Array<mixed> | void | null,
): void {
  const dispatcher = resolveDispatcher();
  return dispatcher.useImperativeHandle(ref, create, deps);
}

export function useDebugValue<T>(
  value: T,
  formatterFn: ?(value: T) => mixed,
): void {
  if (__DEV__) {
    const dispatcher = resolveDispatcher();
    return dispatcher.useDebugValue(value, formatterFn);
  }
}

export const emptyObject = {};

export function useTransition(): [(() => void) => void, boolean] {
  const dispatcher = resolveDispatcher();
  return dispatcher.useTransition();
}

export function useDeferredValue<T>(value: T): T {
  const dispatcher = resolveDispatcher();
  return dispatcher.useDeferredValue(value);
}

export function useOpaqueIdentifier(): OpaqueIDType | void {
  const dispatcher = resolveDispatcher();
  return dispatcher.useOpaqueIdentifier();
}

export function useMutableSource<Source, Snapshot>(
  source: MutableSource<Source>,
  getSnapshot: MutableSourceGetSnapshotFn<Source, Snapshot>,
  subscribe: MutableSourceSubscribeFn<Source, Snapshot>,
): Snapshot {
  const dispatcher = resolveDispatcher();
  return dispatcher.useMutableSource(source, getSnapshot, subscribe);
}
  • 定位到 useState

    export function useState<S>(
      initialState: (() => S) | S,
    ): [S, Dispatch<BasicStateAction<S>>] {
      const dispatcher = resolveDispatcher();
      return dispatcher.useState(initialState);
    }
    
    • 这边调用了一个 dispatcher.useState(initialState);
    • 这个dispatch等于 const dispatcher = resolveDispatcher();
  • 对应的再去找到这个 resolveDispatcher ,它是个function

    function resolveDispatcher() {
      const dispatcher = ReactCurrentOwner.currentDispatcher;
      invariant(
        dispatcher !== null,
        'Hooks can only be called inside the body of a function component.',
      );
      return dispatcher;
    }
    
    • 可看到是通过 ReactCurrentOwner.currentDispatcher 去获取的
    • 这个就要涉及到后续react-dom渲染的过程
    • 在我们使用阶段,是没有拿到任何真正节点的实例的。
    • 比如在我们创建了react element,我们传进去的是这个class component的类
    • 而不是它的一个new的一个实例,拿不到对应的东西
    • 只有在 react-dom 进行真正的渲染的过程当中,才会去为我们创建这个实例
    • 它这边提供了这个方法,在实际调用是要在我们的 react-dom进行渲染的时候
    • 它才会为我们这个 ReactCurrentOwner 去设置属性
  • ReactCurrentOwner 它是一个全局的类,定位一下

    /**
     * Copyright (c) Facebook, Inc. and its affiliates.
     *
     * This source code is licensed under the MIT license found in the
     * LICENSE file in the root directory of this source tree.
     *
     * @flow
     */
    
    import type {Fiber} from 'react-reconciler/src/ReactFiber';
    import typeof {Dispatcher} from 'react-reconciler/src/ReactFiberDispatcher';
    
    /**
     * Keeps track of the current owner.
     *
     * The current owner is the component who should own any components that are
     * currently being constructed.
     */
    const ReactCurrentOwner = {
      /**
       * @internal
       * @type {ReactComponent}
       */
      current: (null: null | Fiber),
      currentDispatcher: (null: null | Dispatcher),
    };
    
    export default ReactCurrentOwner;
    
  • 我们可以看到 ReactCurrentOwner ,它就是一个对象,里面有两个属性

  • 一个是 current , 就是这个current就对应正在目前正在渲染的哪一个节点的一个实例

  • currentDispatcher 是实例对应的 dispatcher

  • 它一开始初始化的时候,是两个 null

  • 然后到后期每一个组件进行渲染的时候,它才会进行一个渲染

  • 就跟我们在class component里面看到的,它的 setState 调用的是 this.updateSetState

  • 在这里的 dispatch 也是从不同平台上面,它传入进来的一个东西,不是我们在react中定义的

  • 所以在react中我们可以看到的源码就非常的简单,就是这么一些相关的东西

  • 同理,useEffect和其他内容也基本是类似的,只不过它最终调用的方法会不一样

  • 比如说useReducer,那么它调用的是 dispatcher.useReducer

  • 它们最终都是调用 dispatcher 上面的方法

React 源碼解析 - Hooks 系列 React 源碼解析 - Hooks 系列前言正文調用 React Hook 到底背後發生了什麼?初探 Hooks 源碼DispatcheruseState HookHook 的實現Hook 在 Mount 階段(useState)mountWorkInProgressHook() - 存儲 Hook 的數據結構 - 循環鏈表整個 Hook 鏈表保存在哪裡useState 怎麼處理 state 更新觸發組件更新(重新渲染)使組建達到 Update 階段Hook 在 Update 階段做了什麼?useStat 阅读详情

相关推荐

【React】React18核心源码解读

【React】React18核心源码解读

owo_ovo的博客 2467

React常用hooks源码解析

hooks源码解读

m0_57307213的博客 970

掌握React Hooks与自定义Hooks:The Rehooks徽标指南

本文还有配套的精品资源,点击获取 简介:React Hooks是React 16.8版本的新增特性,它为函数组件带来了状态和生命周期管理能力,极大地提升了代码的可复用性和可维护性。The Rehooks徽标可能指向一个提供额外自定义Hooks(如useDebounce、useThrottle等)的库或框架,这些Hooks有助于简化React应用中的特定任务。本指南将帮助开发...

weixin_30765637的博客 1187

React源码分析6-hooks源码

所以我们总结一下这个函数,它所做的事情如下:总结一下useState和useReducer的执行过程如下图:总结一下useEffect的大体流程如下:本章讲解了 react hooks 的源码,理解了 hooks 的设计思想和工作过程。其他 hook 平时用的比较少,就不在这里展开讲了,但通过上面几个 hook 的源码讲解,其他 hook 看源码你应该也能看得懂。

It_kc的博客 611

ROS基础(一)——命令行代码(以小乌龟程序为例)

ROS学习(一)——命令行代码(以小乌龟程序为例)1 基础命令行语句1.1 roscore1.2 rqt_graph(显示系统计算图)1.3 rosnode(显示所有节点相关信息)1.4 rostopic(和话题相关)2 服务类型指令rosservice同时存在两只海龟3 指令记录 1 基础命令行语句 从大二四旋翼无人机编队后就没再接触过ROS了,最近由于科研任务需要重新捡起来,打算系统学一下!学习过程参考古月居老师的视频,有兴趣的同学可以去[BliBli]学习。 学习平台:Ubuntu 18.04 硬件

北理自动化小白 6269

卫星监测“America”级#两#栖#攻#击#舰#(LHA-6)出港

卫星监测“America”级#两#栖#攻#击#舰#(LHA-6)出港 前脚刚走,后脚又来,山姆大叔又来刷存在感,2020年7月28日,USS Ronald Reagan流窜在我国东海海区被卫星拍了下来: 2020年8月1日,最新卫星图像显示USS Ronald Reagan已经返回母港日本横须贺:距离其出港(2020年6月8日)已经过去了快两个月 然而事情并没有到此结束,“America”级#两#栖#攻#击#舰#(LHA-6)选择在 “八.一” 这个特殊的日子前后出港颇具挑衅的味道。 根据2020年

qq_46071146的博客 1566

react hook 源码完全解读

从React Hooks发布以来,整个社区都以积极的态度去拥抱它、学习它。期间也涌现了很多关于React Hooks 源码解析的文章。本文就以笔者自己的角度来写一篇属于自己的文章吧。希望可以深入浅出、图文并茂的帮助大家对React Hooks的实现原理进行学习与理解。本文将以文字、代码、图画的形式来呈现内容。主要对常用Hooks中的进行学习,尽可能的揭开Hooks的面纱。看到这里我们在回头看看最初的一些疑问:1.React 如何管理区分Hooks?

梅花寺 379

Halcon异常检测训练避坑指南:如何避免GPU内存溢出和样本不足问题

本文针对Halcon深度学习异常检测训练中常见的GPU内存溢出和样本不足两大难题,提供了从原理分析到实战解决方案的深度指南。通过调整批次大小、图像尺寸、使用梯度累积等技巧有效管理显存,并利用针对性数据增强与人工合成策略破解小样本困境,帮助开发者构建稳定高效的训练流程。

river的博客 217

【React源码16】深入学习React 源码实现—— Hooks闭包陷阱问题

React Hooks中的闭包陷阱是指异步回调函数捕获的是旧的state或props值,而非最新值。这种现象在useEffect、setTimeout、setInterval等场景中尤为常见。

silverclayz的技术分享 1854

NotImplementedError: Cannot copy out of meta tensor; no data! Please use torch.nn.Module.to_empty()

Please use torch.nn.Module.to_empty() instead of torch.nn.Module.to()输出(llama) (base) [root@localhost home]# nvidia-smi Unable to determine the device handle for GPU0000:09:00.0: Unknown Error。这是典型的“孤儿进程”,但它还是。(僵尸进程),占用 GPU 资源。如果进程仍然不消失,并且。,这意味着它的父进程是。

m0_61636632的博客 2098

RocketMQ源码分析之消息轨迹

文章目录前言一、消息轨迹二、消息轨迹源码分析1、producer端2、consumer端三、消息轨迹中存储的信息1.TraceContext2.TraceBean3.TraceType四、总结 前言   本篇文章将会从以下方面介绍消息轨迹:什么是消息轨迹?如何启用消息轨迹?示例demo、消息轨迹的源码分析和消息轨迹中存储的信息。最后会用一张图来总结消息轨迹的工作原理。 一、消息轨迹 1.什么是消息轨迹? 消息轨迹是用来跟踪记录消息发送、消息消费的轨迹。 2.如何启用消息轨迹? broker端 需要在b

不爱学习的小妞博客 1076

React Hooks源码浅析

前段时间研究了一波React的渲染流程,内部机制的源码,阅读到一半的时候React终于推出了16.8.x的版本,主要带来的更新就是Hooks的新功能。相信已经有很多的使用教程或者源码阅读文章。那么我也来一个属于自己的阅读有感的文章,做一个记录吧。 其实React文档中也有说明了Hooks的提出主要是为了解决什么问题的。 React团队认为组件之间复用状态逻辑很难。 就以前React为了将一个组...

大灰狼的小绵羊哥哥的博客 2214

封装POD与PinMap文件总结学习-20250516

芯片封装外形图(POD)和PinMap是芯片设计和制造中的关键文档。POD详细描述了芯片的物理尺寸、引脚布局和封装类型,而PinMap则提供了芯片封装上各个引脚的位置、名称和功能的详细信息。这些文档在芯片设计、制造和应用过程中起到“地图”的作用,帮助设计人员理解芯片的物理和电气特性。在PCB设计中,POD用于确定socket的footprint和pogo的选型,而PinMap则用于器件的合理布局和布线。这些信息对于确保芯片的正确安装和功能至关重要。

歌颂苦难的行为是无耻的; 2379

React Hooks 原理与最佳实践

1. 前言React Hooks 是 React 16.8 引入的新特性,允许我们在不使用 Class 的前提下使用 state 和其他特性。React Hooks 要解决的问题是状态共...

前端下午茶 1万+

TensorRT - 使用自定义层扩展 TensorRT

TensorRT 支持通过自定义插件扩展功能。开发者可以基于 IPluginV3 接口实现插件类,并通过 IPluginCreatorV3One 创建器类注册到 TensorRT 插件注册表。插件实现需要包含核心、构建和运行时三种能力,并通过静态或动态方式注册。最后可使用 addPluginV3() 将插件实例添加到 TensorRT 网络中。这种方法允许在标准层不满足需求时,使用自定义层扩展模型功能。

1149

Linux 下 OpenClaw 安装全记录:从零到一的保姆级图文教程

本文主要介绍了Linux 下 OpenClaw 安装全记录:从零到一的保姆级图文教程,希望能对学习使用OpenClaw 的同学们有所帮助。 文章目录 1. 背景 2. 实战教程 2.1 步骤一 安装Node.js 2.2 步骤二:安装git 2.3 步骤三:安装并配置OpenClaw 2.4 步骤四:配置OpenClaw 2.5 步骤五:配置模型 2.6 步骤六:对话 3. 后续使用步骤 4. 报错解决方案 5. OpenClaw的卸载

weixin_43178406的博客 10万+

react-hooks原理

一 前言 本篇文章主要从react-hooks起源,原理,源码角度,开始剖析react-hooks运行机制和内部原理,相信这篇文章过后,对于面试的时候那些hooks问题,也就迎刃而解了。实际react-hooks也并没有那么难以理解,听起来很cool,实际就是函数组件解决没有state,生命周期,逻辑不能复用的一种技术方案。 Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。 老规矩,????️????️????️我们

https://www.xiaohongshu.com/user/profile/5f3543150000000001002b2e 8450

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

React Hooks 源码解析:useEffect

Fiber 里面的内容很多,如果展开的话足够写几篇文章了,因此这里也尽量简单快捷的走一遍流程,忽略本文不相关的细节,只梳理部分逻辑的实现,重点关注我们调用 useEffect 之后的逻辑。useEffect 的入口和上一节中 useState 的一样,都在 ReactFiberHooks.js 这个文件中,并且同 useState 一样,在首次加载时 useEffect 实际执行的是 mountEffect,之后每次渲染执行的是 updateEffect,此处不再赘述。所以 3.4 中我们留下的问题——

m0_68271787的博客 1652

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

React 的源码与原理解读(十一):hooks 的原理

这个章节和前面的部分相对独立,我们将来讲一下我们在 React 16.8 更新的新特性 **Hooks**,我们都知道 Hooks 的提出主要就是为了解决函数组件的状态问题而存在的,之前我们的 class 组件有状态,但是 function 组件没有,所以为了解决这个问题,hooks 诞生了。那么为了让我们的 hooks 挂在在整个 React 的生命周期中, React 是怎么样处理他们的呢,我们来看看这部分的内容:

weixin_46463785的博客 2708

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

浅析React Hooks原理

React Hooks 简介 React Hooks 是 React 16.8 以及之后版本的产物,React Hooks 就是一堆钩子函数,不同的钩子函数提供了不同的功能,React 通过这些钩子函数对函数型组件进行增强。Hooks 允许你在不编写 class 的情况下使用状态(state)和其他 React 特性。 你还可以构建自己的 Hooks, 跨组件共享可重用的有状态逻辑。 践行代数效应 React 核心成员 Sebastian Markbåge (Hooks 的发明者)曾说:我们在 React

weixin_50964668的博客 3023

React Hooks 源码学习

React Hooks 添加于 React 16.8,用于 React 中函数组件的一类特殊函数,它们允许你在不编写类组件而是使用简单的函数组件(Function Component,以下称FC)的情况下依然享受到状态、上下文、副作用等 React 特性。自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook。// 下面自定义了一个获取窗口长宽值的hooks}...

发果叁 594

React Hooks 精讲:写给 Vue 开发者的 React hooks 使用指南

本篇文章将以 Vue 视角切入,带你从入门到核心源码,掌握 Hooks 的使用和原理。

Curry_On的博客 1452

【React源码04】深入学习React 源码实现—— React Hooks 的底层实现原理(useState,useEffect,useRef)

React Hooks 通过链表结构管理组件状态,每个函数组件对应一个 Hook 链表。核心文件包括 ReactFiberHooks.js 和 ReactUpdateQueue.js。Hook 对象包含 memoizedState(当前状态)、queue(更新队列)和 next(指向下一个 Hook)。useState 实现分为初始化(mountState)和更新(updateState)两个阶段:初始化时创建 Hook 节点和更新队列,更新时处理待执行队列计算新状态。

silverclayz的技术分享 1161

React Hooks 版实现 Redux

React-hook版 状态管理 使用React Hooks和Context API模拟实现 Redux 在React世界中,考虑状态管理时想到第一个想法就是使用Redux库。 Redux提供了一个可预测的状态容器来集中应用程序的全局存储。借助connect,mapStateToProps,mapDispatchToProps和bindActionsCreator。Redux可以轻松创建和管理...

前端小愤青 1987
上一篇: React16源码: Suspense与lazy源码实现
下一篇: React16源码: React.Children源码实现
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

Wang's Blog

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

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

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

打赏作者

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

抵扣说明:

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

余额充值