我们先初步了解下 hooks,使用 useState 和 useEffect。
/**
* 必须要react和react-dom 16.7以上
*/
import React, { useState, useEffect } from 'react'
export default () => {
const [name, setName] = useState('zhangsan')
return (
<>
<p>My Name is: {name}</p>
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</>
)
}

这是一个非常非常简单的 demo , 首先要使用 hooks ,必须要react和react-dom 16.7以上。我们这里声明了一个 function component , 在以前对比 class component , 他缺少的是什么,缺少的就是 this 对象。他没有 this 对象,就没有 this.state , 就不具有包含自己本身的状态的功能,第二个,他不能有生命周期方法,这是最明显的几个特点,在这里,我们使用了 hooks 来存储了state

const [name, setName] = useState('zhangsan')
这边使用 useState, 然后传入一个默认值,然后他返回的是一个数组,这是一个数组的解构,大家应该都清楚,这个数组的第一项是我们 state 对应的变量,第二项是我们去改变这个 stage 的方法。这就是通过 useState 返回给我们的唯一的一个东西。然后我们就可以在我们渲染当中去使用这个 state 和修改这个 stage。比如这个 onChange 就是去修改这个 state。
这就是 hooks 给 function component 提供了 class component 所具有的能力。他的意义不仅仅是为了替代 class component , 他的意义是为了帮助我们去拆分组件内部的一些逻辑。把他提取出来,能够给更多的组件进行复用。以前在 class component 里面是很难去拆分这部分逻辑的。
useEffect(() => {
console.log('component update') return () => {
console.log('unbind')
}
}, [])
我们要使用生命周期方法,在组件渲染的时候,我们要去做一些操作的时候,我们可以使用 Hooks 中的 useEffect 。这个东西可以传入一个方法,在 hooks 里面没有着重的区分 mounted 和 updated 。useEffect 每次有内容更新的时候都会调用。如果我们在这个方法里面做了事件绑定,在第 n 次更新的时候要解除这个事件,怎么办呢,就是在 return 这个方法里面解除绑定。在这里会先执行 unbind 。再执行 component update 。这比较符合更新的逻辑,每次更新的时候都会把之前的状态消除,然后返回新的状态。
这里传入一个空的数组,就代表执行一次就 ok 了。这就是使用 hooks 模拟生命周期方法的一个用法。 我们在 React.js 里面找到 useState 源码
function resolveDispatcher() {
const dispatcher = ReactCurrentOwner.currentDispatcher;
invariant(
dispatcher !== null,
'Hooks can only be called inside the body of a function component.',
);
return dispatcher;
} export function useState<S>(initialState: (() => S) | S) {
const dispatcher = resolveDispatcher();
return dispatcher.useState(initialState);
}

我们看到 useState 里面有个 dispatcher,这个 useState 的返回值是 dispatcher.useState 。这个 dispatcher 是调用了 resolveDispatcher(). 在方法 resolveDispatcher 里面看到这个 dispatcher 是通过  ReactCurrentOwner.currentDispatcher 获取的。这就是涉及后续渲染的时候才会去赋值这些东西。因为在 react 使用阶段是没有拿到任何节点。在 createElement 的时候传入的是对象,还没真正渲染,还没真正的创建这个实例。 ReactCurrentOwner 是个全局的类,

const ReactCurrentOwner = {
/**
* @internal
* @type {ReactComponent}
*/
current: (null: null | Fiber),
currentDispatcher: (null: null | Dispatcher),
};

这就是 ReactCurrentOwner 的源码,非常简单,就是一个全局的对象。里面有两个属性,一个是 current , 就是目前渲染的是哪个节点,这个实力。currentDispatcher 就是实力对应的 dispatcher。 useEffect 类似于 useState。

React源码 Hooks的更多相关文章

  1. React躬行记(16)——React源码分析

    React可大致分为三部分:Core.Reconciler和Renderer,在阅读源码之前,首先需要搭建测试环境,为了方便起见,本文直接采用了网友搭建好的环境,React版本是16.8.6,与最新版 ...

  2. React源码剖析系列 - 生命周期的管理艺术

    目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理.本系列文章希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期(C ...

  3. React源码解析:ReactElement

    ReactElement算是React源码中比较简单的部分了,直接看源码: var ReactElement = function(type, key, ref, self, source, owne ...

  4. react 源码之setState

    今天看了react源码,仅以记录. 1:monorepo (react 的代码管理方式) 与multirepo 相对. monorepo是单代码仓库, 是把所有相关项目都集中在一个代码仓库中,每个mo ...

  5. React 源码剖析系列 - 不可思议的 react diff

      简单点的重复利用已有的dom和其他REACT性能快的原理. key的作用和虚拟节点 目前,前端领域中 React 势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理. 本系列文章希望通过剖析 ...

  6. React 源码剖析系列 - 生命周期的管理艺术

    目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理. 本系列文章 希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期 ...

  7. 读react源码准备

    git源码地址:https://github.com/facebook/react react 里面就是 react源码 react里面的react文件夹就是react源码,react源码非常的少,总 ...

  8. react源码之render

    1.最近学习react源码,刚刚入门,看了render的原理,到了fiberRoot的创建 如图:

  9. React源码之组件的实现与首次渲染

    react: v15.0.0 本文讲 组件如何编译 以及 ReactDOM.render 的渲染过程. babel 的编译 babel 将 React JSX 编译成 JavaScript. 在 ba ...

随机推荐

  1. RedHat linux服务器安装elasticsearch且设置公网访问

    0. 首先需要安装jdk,因为elasticsearch是Java写的,默认需要Java环境,且安装elasticsearch 7.x需要使用jdk 1.8或更高版本 1. 执行以下命令,创建elas ...

  2. 使用helm管理复杂kubernetes应用

    1. 查看仓库: $ helm repo list NAME URL stable https://aliacs-app-catalog.oss-cn-hangzhou.aliyuncs.com/ch ...

  3. makefile小计

    1. makefile格式如下,想要生成code.o,就要指定它依赖哪些东西.比如这里是依赖code.cpp这个文件 然后如何生成,换行+tab(与python类似,通过tab区分下面的是生成的命令) ...

  4. iis可以运行但是界面不能在桌面显示是怎么回事

    iis可以运行但是界面不能在桌面显示是怎么回事 引用:https://zhidao.baidu.com/question/1948053642075906588.html 在开始->运行 执行i ...

  5. 基于ZYNQ的uart传输任意长度的数据

    1.参考 UG585 网络笔记 参考:ZYNQ进阶之路14–PS端uart串口接收不定长数据 2.理论知识 参见上一次实验:基于ZYNQ 的UART中断实验之串口写数据到DDR3中 3.实验目的 基于 ...

  6. 转载:Linux命令行快捷键

    常用 Ctrl + 左右键:在单词之间跳转 Ctrl + A:跳到本行的行首 Ctrl + E:跳到页尾 Ctrl + U:删除当前光标前面的所有文字(还有剪切功能) Ctrl + K:删除当前光标后 ...

  7. CentOS7-部署测试Apollo

    linux部署apollo环境要求:jdk1.8.mysql5.7 centos7安装jdk1.8跟mysql5.7可以参考我这两篇文章 https://www.cnblogs.com/reasonz ...

  8. 【转帖】 PM RD QA OP

    From 百度知道 一.PM: Product Manager,产品经理,又称品牌经理(Brand Manager).举凡产品从创意到上市,所有相关的研发.调研.生产.编预算.广告.促销活动等等,都由 ...

  9. mysql启动报错 "unknown variable 'defaults-file=/etc/my.cnf"

    使用指定的my.cnf,而不用默认的/etc/my.cnf文件,可以在启动时,在mysqld_safe后加上参数--default-file=/usr/local/server/mysql2/etc/ ...

  10. 不一样的LCA——luoguP1852跳跳棋

    洛谷端题目链接 loj端题目链接 题目大意: 在一条数轴上进行跳跳棋游戏.棋子只能摆在整点上.每个点不能摆超过一个棋子.用跳跳棋完成:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动 ...