Mini-React
项目拆解:
Jsx 和虚拟 DOM
组件和生命周期
Diff
异步的setState
hook支持
具体思路
将jsx经过babel转成React.createElement的形式
例如
1 | class Hem extends React.Component { |
经过babel转义后
1 | _createClass(Hem, [ |
Jira项目
代码自动格式化工具:prettier
配置过程:https://prettier.io/docs/en/precommit.html
yarn add --dev --exact prettier
新建.prettierrc.json,.prettierignore
文件
设置git commit预提交钩子
npx mrm@2 lint-staged
规范git commit工具:commitlint
配置过程:https://github.com/conventional-changelog/commitlint
yarn add --save-dev @commitlint/config-conventional @commitlint/cli
新建 commitlint.config.js文件,引入规则module.exports = {extends: [‘@commitlint/config-conventional’]}
如何利用css var做一个dark mode方案
背景
- 希望利用 css 变量实现 dark 和 light 模式的切换
- 原有的工程都是 less 形式定义的 css,并且还有 less 的函数,比如 fade 等,不想手动改 less 的函数,希望该插件能支持解析 less 函数
- 需要支持局部不切换模式,比如某个区域是固定的 light 模式
步骤
第一步:less 变量转换成 css 变量
这一步比较简单,less 已经提供了字段用于转换,只需要添加一个配置项就可以,就是globalVars
属性。
可以查看example 代码参考
1 | { |
LessGlobalCSSVars
大概长这个样子
1 | { |
React组件性能优化
React 性能优化思路
我觉得React 性能优化的理念的主要方向就是这两个:
- 减少重新 render 的次数。因为在 React 里最重(花时间最长)的一块就是 reconciliation(简单的可以理解为 diff),如果不 render,就不会 reconciliation。
- 减少计算的量。主要是减少重复计算,对于函数式组件来说,每次 render 都会重新从头开始执行函数调用。
在使用类组件的时候,使用的 React 优化 API 主要是:shouldComponentUpdate
和 PureComponent
,这两个 API 所提供的解决思路都是为了减少重新 render 的次数,主要是减少父组件更新而子组件也更新的情况。
但是在函数式组件里面没有声明周期也没有类,那如何来做性能优化呢?
先分个类,组件什么时候会重新执行?
- 组件自己的状态改变
- 父组件重新渲染,导致子组件重新渲染,但是父组件的 props 没有改变
- 父组件重新渲染,导致子组件重新渲染,但是父组件传递的 props 改变
针对第二点,在FC中,可以通过memo减少rerender
1 | function Component(props) { |
通过 React.memo
包裹的组件在 props 不变的情况下,这个被包裹的组件是不会重新渲染的(相当于PureComonent)
默认情况下其只会对 props 的复杂对象做浅层对比(浅层对比就是只会对比前后两次 props 对象引用是否相同,不会对比对象里面的内容是否相同),如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现。
TypeScript入门
TypeScript简介
- TypeScript是JavaScript的超集。
- 它对JS进行了扩展,向JS中引入了类型的概念,并添加了许多新的特性。
- TS代码需要通过编译器编译为JS,然后再交由JS解析器执行。
- TS完全兼容JS,换言之,任何的JS代码都可以直接当成JS使用。
- 相较于JS而言,TS拥有了静态类型,更加严格的语法,更强大的功能;TS可以在代码执行前就完成代码的检查,减小了运行时异常的出现的几率;TS代码可以编译为任意版本的JS代码,可有效解决不同JS运行环境的兼容问题;同样的功能,TS的代码量要大于JS,但由于TS的代码结构更加清晰,变量类型更加明确,在后期代码的维护中TS却远远胜于JS。
TypeScript 开发环境搭建
下载Node.js
安装Node.js
使用npm全局安装typescript
- 进入命令行
- 输入:npm i -g typescript
创建一个ts文件
使用tsc对ts文件进行编译
进入命令行
进入ts文件所在目录
执行命令:tsc xxx.ts
Hooks
Redux
Redux
设计思想
- (1)Web 应用是一个状态机,视图与状态是一一对应的。
- (2)所有的状态,保存在一个对象里面。
Action
Action 就是 View 发出的通知,表示 State 应该要发生变化了。
Action 是一个对象,其中的
type
属性是必须的,表示 Action 的名称,Action 描述当前发生的事情。改变 State 的唯一办法,就是使用 Action。
可以定义一个函数来生成 Action,这个函数就叫 Action Creator,示例如下
1 | const ADD_TODO = '添加 TODO'; |
浏览器架构和事件循环
chrome浏览器架构
Chrome 采用多进程架构,其顶层存在一个 Browser process 用以协调浏览器的其它进程。
- Browser Process:
负责包括地址栏,书签栏,前进后退按钮等部分的工作;
负责处理浏览器的一些不可见的底层操作,比如网络请求和文件访问;
- Renderer Process:
- 负责一个 tab 内关于网页呈现的所有事情
- Plugin Process:
- 负责控制一个网页用到的所有插件,如 flash
- GPU Process
- 负责处理 GPU 相关的任务
由于一个tab标签页都有一个独立的渲染进程,所以一个tab异常崩溃后,其他tab不会受到影响。
一个渲染进程包括
- JS引擎线程
- HTTP请求线程
- 定时触发线程
- 事件触发线程
- GUI线程
浏览器JS异步执行原理
执行JS代码的线程只有一个,是浏览器提供的JS引擎线程,浏览器中还有
函数式编程
什么是函数式编程?
函数式编程具有五个鲜明的特点。
1. 函数是”第一等公民”
指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。
举例来说,下面代码中的print变量就是一个函数,可以作为另一个函数的参数。
1 | var print = function(i){ console.log(i);}; |
2. 只用”表达式”,不用”语句”
“表达式”(expression)是一个单纯的运算过程,总是有返回值;”语句”(statement)是执行某种操作,没有返回值。函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。
原因是函数式编程的开发动机,一开始就是为了处理运算(computation),不考虑系统的读写(I/O)。”语句”属于对系统的读写操作,所以就被排斥在外。
当然,实际应用中,不做I/O是不可能的。因此,编程过程中,函数式编程只要求把I/O限制到最小,不要有不必要的读写行为,保持计算过程的单纯性。