尽量别再用上

41 阅读4分钟

react合成事件,就是把所有事件在react17以前是委托到document, 17以后委托到根节点,原生event事件对象上有一个composedPath方法, 能够获取到触发事件节点的path,是一个数组(顺序从子到父),可以用来模拟捕获和冒泡 并且合成事件调用前设置为批处理状态,事件处理器执行完调用完以后去flushDirtyComponent 批量更新 好处:为了解决不同浏览器事件的一致性

生命周期3个阶段:挂载、更新、卸载 以前生命周期 挂载: constructor ---> componentWillMount ---> render ---> componentDidMount 更新(属性props和状态state变化): shouldComponentUpdate的返回bool值决定是否触发render componentWillReceiveProps ---> shouldComponentUpdate ---> componentWillUpdate ---> render ---> componentDidUpdate 卸载:componentWillUnmount (清理定时器,事件监听等)

新的生命周期 挂载:constructor ---> getDivergedStateFromProps ---> render ---> componentDidMount 更新:getDerivedStateFromProps ---> shouldComponentUpdate ---> render ---> getSnapshotBeforeUpdate ---> componentDidUpdate 卸载:componentWillUnmount

废弃: componentWillMount 18被废弃了因为 在并发模式下,React 可以在fiber渲染过程中f中断和恢复 componentWillUpdate componentWillReceiveProps

新增: getSnapShotBeforeUpdate getDivergedStateFromProps (static 静态方法 可以拿到新的props 和旧的props 返回值null 决定不更新) 在组件挂载和更新时调用,用于根据 props 更新 state。

函数组件和类组件的区别

  1. 类组件是基于ES6的类语法实现的,函数组件是通过js的函数语法实现的
  2. 类组件生命周期更完整,函数组件可以通过hooks实现生命周期三个阶段
  3. 类组件可以使用ErrorBoundary (19以前)函数组件无法实现
  4. 逻辑复用来说函数组件可以自定义hooks
  5. 性能优化方面来说函数组件可以使用memo和useMemo,类组件可以使用pureComponent和shouldComponentUpdate 进行更精细的控制

jsx 转换js? === React.createElement (babel做的)

用react hooks 实现一个redux? useContext createContext useReducer

react18新特性? createRoot 并发模式 fiber node setState 自动批处理 Suspense 新增api == flushSync

Suspense

  1. react16中suspense 主要用于包裹懒加载的组件,并在组件懒加载期间显示一个加载动画

setState 同步?异步? 1.在react16中,setState是在事件处理函数、生命周期中是异步的,会将setState调用合并为一次更新 在setTimeout、定时器、原生事件处理函数addEventListener

2.在react18中,都是异步,可以使用flushSync强制同步 // flushSync 函数内部的多个 setState 仍然为批量更新,这样可以精准控制哪些不需要的批量更新

3.setState 第二个回调函数可以拿到最新的值 useState 传回调函数 参数就是当前状态的值,并且把返回值当作新值 可以说react能够管理的地方都是批量的

// new实现 function newMock(foo, ...arg) { const obj = { proto: foo.prototype, }; // 通过new 构造函数,创建的实例隐式原型__proto__ 指向 构造函数的prototype , // 通过调用实例对象调用的属性或方法,先检查自身是否存在,不存在则继续向上查找,一直Object.prototype.proto = null // 实例.proto == 构造函数.prototype = { proto: Object.prototype } // 实例.constructor = 构造函数 Function.constructor = Function return foo.apply(obj, arg); } 'aaa'.constructor === String;

// 对象类型先调toPrimitive、valueOf、toString依次调用获取返回值 Number(['123']); // 123 Number(['']); // 0 !![]; // true !!{}; // true 'test' + ['123', 'adb']; // test123,adb 'a' + {}; // a[object Object] {}.toString() 'a' + []; // a [].valueOf()返回 ""

// 编码解码 encodeURIComponent decodeURI

// 0.1 + 0.2 底层是转二进制 浮点类型的小数位会出现精度丢失 解决:big.js库, bigInt.MAX_SAFE_INTEGER 2的53次方-1

// typeof null === "object" 数据类型值底层是64/32位二进制存储的,null是64个0,开头是000被认为是对象

// Object.prototype.toString.call() [object Array/Number/Math/Symbol]

// slice(开始位置,截止位置[不包含截至]) 支持复制&有返回值 splice(start, deleteCount, item, itemN...)

/* ES6 新特性 let 和 const:块级作用域,let 可变,const 不可变。 模板字符串:用反引号(`)支持变量嵌入和多行字符串。 箭头函数:简洁语法,不绑定 this。 解构赋值:快速从数组或对象中提取值。 默认参数:函数参数支持默认值。 展开运算符(...):数组/对象的展开与合并。 for...of:遍历可迭代对象。 Promise:处理异步操作,避免回调地狱。 模块化:import 和 export 实现模块化。 类(class):更简洁的面向对象语法。 Set 和 Map:集合和键值对数据结构。 Symbol:唯一值的数据类型。 async/await:基于 Promise 的异步代码简化写法。 ?.

常用 ES6 新方法总结: 数组方法: find():找第一个满足条件的元素。 findIndex():找第一个满足条件的索引。 includes():判断是否包含某值。 Array.from():类数组转数组。 Array.of():创建数组。 字符串方法: startsWith():判断是否以某字符开头。 endsWith():判断是否以某字符结尾。 includes():判断是否包含某字符。 repeat():重复字符串。 对象方法: Object.assign():合并对象。 Object.keys():获取键数组。 Object.values():获取值数组。 Object.entries():获取键值对数组。 数字方法: Number.isNaN():判断是否是 NaN。 Number.isFinite():判断是否是有限数。 Math.trunc():去掉小数部分。