浅谈对 React 合成事件的理解?
前言React 基于浏览器的事件机制自身实现了一套事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等,这套事件机制被称之为合成事件。
目的是为了实现全浏览器的一致性,抹平不同浏览器之间的差异性,比如原生 onclick 事件对应 React 中的 onClick 合成事件。
React 事件通过 JSX 方式绑定的事件, 比如 onClick={() => {}}
原生事件使用 addEventListener
123456789101112131415const ref = useRef()const onClick = useCallback(() => {}. []);useEffect(() => { // 绑定原生事件 ref.current.addEventListener('click', event => {});}, []);return ( <div ref={ref} ...
常见的 React hooks 有哪些
前言React Hook 是 React 16.8 推出的新特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。没有计划从 React 中移除 class。
为什么要有 Hook?官网 对于动机的解释。
在组件之间复用状态逻辑很难:
可能需要 render props 和高阶组件(HOC),但是会形成会形成嵌套地狱,而 hooks 支持从组件状态中提取状态逻辑,进行单独的测试和复用,很好的解决这个问题。
复杂组件变得难以理解:
类组件中,可能需要在不同的生命周期中执行一些逻辑,如事件监听/销毁等需要在不同的生命周期中定义, componentDidMount/componentWillUnMount 中执行,意味着会讲统一逻辑在不同生命周期中去拆分。但是在 hooks 中可以直接在 useEffect 中定义。
难以理解的 class:
this 指向问题,类组件中太多对 this 的使用,如 this.onCLick.bind(this) 等,容易忘记绑定事件处理器。class 不能很好的压缩导致热重载不稳定。
高阶组件 HOCHO ...
React 生命周期
前言生命周期指 React 组件从装载至卸载的全过程,这个过程内置多个函数供开发者在组件的不同阶段执行需要的逻辑。
其实目前一般很少会关注到 React 生命周期,虽然类组件和生命周期目前依然可以使用,但自从 React 16.8 推出 Hooks 之后,函数组件和 Hooks 成为了主流推荐的方式。
并且 React 16.3 版本已经明确了将在 17 版本中废弃componentWillMount、componentWillUpdate和componentWillReceiveProps这三个生命周期函数,并引入两个新的生命周期(static getDerivedStateFromProps、getSnapshotBeforeUpdate)来取代。
React 一次完整的状态更新,一共分为 2 个阶段、 4 个生命周期。
2 个阶段:
render 阶段:包括 Diff 算法,计算出状态变化
commit 渲染阶段:ReactDOM 渲染器,将状态变化渲染在视图中
4 个生命周期:
Mount(第一次挂载)
Update(更新)
Unmount(卸载)
Error(子项发 ...
ESM 和 CJS 的区别
前言
JavaScript 中的 ESM(ES Modules) 规范和 CJS(CommonJS)规范是用于模块化开发的两种不同的模组系统。
早期 Javascript 这门语言是没有模块化的概念的,直到 Nodejs 诞生,才把模块系统引入 js``。Nodejs 已经在逐步支持 ESM,目前很多主流浏览器也已经原生支持 ESM。
关于 CSJ 和 ESM关于 CJSCJS 是 CommonJS 的模块系统,最初是为了在服务端 Nodejs 开发设计的,但也被广泛用于前端开发。CSJ 使用 require 函数来导入模块,并使用 module.exports 对象来导出模块。
12345678910111213// math.js 定义模块function add(a, b) { return a + b;}module.exports = { add,};exports.add = add;// main.js 导入模块const { add } = require('./math.js');/ ...
curl 的用法指南
curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。支持通过 HTTP、HTTPS、FTP、SFTP 等协议,进行网络传输。常用于发送 HTTP 请求,获取网页内容,上传或下载文件,以及与 API 的交互。
语法
1curl [options...] <url>
基础指令123456789101112131415161718-A, --user-agent <name> 参数指定客户端的用户代理标头,将 User-Agent <name> 发送到服务器-b, --cookie <数据|文件> 向服务器发送 Cookie-c, --cookie <文件> 接收 Cookie 并保存文件-d, --data <数据> 向服务器发送 HTTP POST 数据-f, --fail HTTP 错误不输出信息-F, ...
彻底搞懂什么是一次性哈希算法
背景近期在学习 Go 语言,在 分布式存储 Geecache 练习教程中第一次听到一次性哈希,由于第一次接触后端,不是特别理解,所以记录下以备后续巩固学习。
分配请求在分布式存储中,往往会通过多台服务器构成集群来提供服务,因为单机的并发量和数据量是有限的,接下来我们称服务器为节点。
假设集群有十个节点,当 节点A 接收到 请求A 时,如果 节点A 没有缓存数据,那么它将会从数据源获取 数据A 并缓存到 节点A 。那么第二次当输入一致时将只有 1/10 的几率选择 节点A 去读取缓存,而有 9/10 的几率会选择其他节点,并再次访问数据源进而存储数据。就会造成在多个节点中,多次缓存同一份数据,导致效率低下,存储空间的浪费。
那么我们该如何将缓存均匀的分布到不同节点进行缓存,并保证但输入一致时,访问同一个节点?
哈希算法取模运算通过对输入进行哈希计算,每次计算都是相同的值,这样就可以将某些相同的请求全部打到同一个节点,从而满足分布式系统的负载均衡需求。
比如当前有三个节点 A、B、C,我们将输入的所有字符的 ASCII 码加起来生成一个 KEY,基于 hash(key) % 3 公式计算得 ...
Golang 学习(未完待续)
环境
MacOS 安装
1brew install go
修改 .zshrc 配置
1234export PATH=$PATH:$GOROOT/binexport GOPATH=$HOME/Developer/gopathsource ~/.zshrc
查看环境变量
12go versiongo env
语法基本结构和基本数据类型可见性规则
只有当某个(常量、变量、类型、函数、结构字段等)需要被外部包调用的时候才使用大写字母开头,并遵循 Pascal 命名法,称为导出(像面向对象语言中的 public);
否则就遵循骆驼命名法,即第一个单词的首字母小写,其余单词的首字母大写,对外不可见。
类型Go 语言中不存在类型继承
基本类型:int、float、bool、string
结构化/复合:struct、array、since、map、channel
结构化的类型没有真正的值,使用 nil 作为默认值
描述类型行为:interface
示例
12345678910单类型定义var IZ initvar a IZ = 5// 多类型定义type ( IZ int ...
通过 N 指令快速切换 Node 版本
安装 n 模块1sudo npm install -g n
安装 Node 版本1sudo n 20.12.2
查看所有版本并切换1n
切换选择 Node 版本
常用指令1234sudo n stable // 安装稳定版本sudo n x.x.x // 安装指定版本sudo n rm x.x.x // 删除指定版本sudo n use x.x.x demo.js // 用指定版本执行脚本
Docker 学习(未完待续)
常用 CLI
https://www.runoob.com/docker/docker-container-usage.html
docker login // 登陆官方 docker
cat ~/.docker/config.json
docker logout
docker login docker.yuansuan.cn // 登陆私有 dockerdocker logout docker.yuansuan.cn // 退出私有 docker
docker ps -a // 查看容器 -a 查看所有容器docker images // 查看所有镜像
docker start <容器 ID> // 启动容器docker stop <容器 ID> // 关闭容器docker restart <容器 ID> // 重启容器docker rm -f <容器 ID> // 删除容器docker image rm -f // 删除镜像
docker logs -f <容器 ID> // 查看容器内部的标准输出
docker ...
最常见的 pm2 指令
PM2 是 node 进程管理工具,可以利用它来简化很多 node 应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,而且使用非常简单。
基础指令
全局安装
1npm install -g pm2
启动
1pm2 start app.js
-i --instance: 创建进程实例,可用于负载均衡。
-n --name: 指定启动实例的应用名称。
-o --output <path>: 输出标准日志路径。
-e --error <path>: 输出错误日志路径。
--watch: 监听应用目录的变化,一旦发生变化,自动重启。如果要精确监听、不见听的目录,最好通过配置文件。
--ignore-watch: 排除监听的目录/文件,可以是特定的文件名,也可以是正则。比如–ignore-watch=”test node_modules “some scripts””
重新启动
1pm2 restart app.js
查看所有进程信息
123pm2 statuspm2 listpm2 ls
查看某个进程信息
1pm2 describe <NAME | ...