这次我真的好好学习react篇

74 阅读3分钟
  1. createRef
function createRef() {
  const refObj = { 
    current: null, 
    $$typeof: Symbol.for('react.ref'),
  }
  // 不允许新增属性
  Object.seal(refObj);
  return refObj
  
}
  1. createContext
function createContext(defaultValue) {
  const context = {
    _currentValue: defaultValue,//这个表示当前的值
    Provider: (props) => {
      //把属性中接收过来的value属性保存在context的_currentValue属性上
      context._currentValue = props.value;
      return props.children;//真正就是它的子元素
    },
    Consumer: (props) => {// Consumer也是一个函数组件,
      //它渲染的是子组件函数返回的结果 。函数的参数是context的当前值
      return props.children(context._currentValue)
    }
  }
  return context;
}
  1. PureComponent
class PureComponent extends Component {
  shouldComponentUpdate(nextProps, nextState) {
    //如果属性不相等,或者状态不相等,就返回true进行更新
    return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState)
  }
}

  浅比较:
    1. 地址值是否相等
    2. 判断类型是不是Object null
    3. key length
    4. hasOwnproperty(key) obj[key] !== obj2 [key]
  1. react hooks 实现简易react-redux
 context createContext provide  shouldComponentUpdate Consumer
  1. useEffect和useLayoutEffect区别?
useLayoutEffect 与DOM更新同步执行 在浏览器绘制前执行 (执行大量计算操作会导致,页面无法渲染,阻塞),
使用同步读取或更新DOM,或者在DOM更新后立即执行

useEffect 在浏览器绘制完以后异步执行
  1. 高阶组件(HOC)是接受一个组件并返回一个新组件的函数

  2. useState useCallback useMemo

在组件首次渲染的时候fiber节点上创建一个单向链表,并且首次渲染每个hooks各自会创建一个节点(节点是对应hooks的属性),添加到这个单向链表中

useState 的节点存放: { memoized: val, queue: [] } // value 更新队列 还有next下一个节点指针

useCallback 的节点存放: { memoized: val, dependencies: [] }
  1. fiber

image.png image.png

zhe
  1. 合成事件
// 17以前的顺序 document

Document capture click
Parent element capture click // 原生
Child element capture click
React child click // 合成
React parent click // 合成
Child element bubble click
Parent element bubble click
Document bubble click

// 17以后的顺序 root
Root capture click
Parent element capture click
React parent capture click
Child element capture click
React child capture click
React child bubble click
Child element bubble click
React parent bubble click
Parent element bubble click
Root bubble click

好处: shadow Dom、减少事件传播路径

 react17 开始把委托到document上的事件改到root上
1.React会在根DOM节点上添加一个统一的事件监听器,并是在绑定的DOM元素添加,而是在内部维护一个映射表
  

  1. 生命周期
 react16.3 开始引入新的生命周期api,旧的废弃了,17完全移除的,15以前是有那几个will的
    挂载 
      constructor -- componentWillMount render -- componentDidMount
      constructor -- getDerivedStateFromProps -- render -- componentDidMount
    更新 
      16.3之前
      componentWillReceiveProps -- shouldComponentUpdate -- componentWillUpdate -- render -- componentDidUpdate
      16.3之后
      static getDerivedStateFromProps -- shouldComponentUpdate -- render -- getSnapshotBeforeUpdate -- componentDidUpdate
    卸载 compontWillUnmount 一直无变化

    废弃原因:
    1.异步渲染模式下 react可能会暂停、恢复渲染过程导致 componentWillMount 会被频繁调用
    2.异步渲染模式下 暂停 恢复可能会出现 props state 数据不一致或副作用混乱
    3.某些sb开发可能会 componentWillReceiveProps componentWillUpdate写一些影响性能代码,造成多余的渲染,

    新增原因:
    1.getDerivedStateFromProps(props 只读的 单向数据流,state) 根据当前props 返回新的state状态
      static 纯函数,无副作用:避免在这个方法中意外地修改组件实例的状态
      props 只读可以性能优化 React 可以通过比较新旧 props 的引用来判断是否需要重新渲染组件

    2.getSnapshotBeforeUpdate(prevProps, prevState) 分别更新前的props和state
      在render之后,DOM更新之前触发,返回值作为第三个参数传给 componentDidUpdate

  1. 什么是无状态组件
有状态组件:class、函数组件调用 setState useState useReducer 维护内部状态
无状态组件:函数组件只接收props做渲染 (不产生副作用)
 
  1. react如何减少不必要的渲染?
1. memo和purecomponent组件通过浅层比较
class PureComponent extends Component {
  shouldComponentUpdate(nextProps, nextState) {
    //如果属性不相等,或者状态不相等,就返回true进行更新
    return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState)
  }
}
浅比较:
1. 地址值是否相等
2. 判断类型是不是Object null
3. key length
4. hasOwnproperty(key) obj[key] !== obj2 [key]