12.手写迷你react(短小精悍就是我)

人人都能读懂的react源码解析(大厂高薪必备)

12.手写迷你react(短小精悍就是我)

视频课程&调试demos

​ 视频课程的目的是为了快速掌握react源码运行的过程和react中的scheduler、reconciler、renderer、fiber等,并且详细debug源码和分析,过程更清晰。

​ 视频课程:进入课程

​ demos:demo

课程结构:

  1. 开篇(听说你还在艰难的啃react源码)
  2. react心智模型(来来来,让大脑有react思维吧)
  3. Fiber(我是在内存中的dom)
  4. 从legacy或concurrent开始(从入口开始,然后让我们奔向未来)
  5. state更新流程(setState里到底发生了什么)
  6. render阶段(厉害了,我有创建Fiber的技能)
  7. commit阶段(听说renderer帮我们打好标记了,映射真实节点吧)
  8. diff算法(妈妈再也不担心我的diff面试了)
  9. hooks源码(想知道Function Component是怎样保存状态的嘛)
  10. scheduler&lane模型(来看看任务是暂停、继续和插队的)
  11. concurrent mode(并发模式是什么样的)
  12. 手写迷你react(短小精悍就是我)

迷你react和真正的源码有哪些区别呢

  • 在render阶段我们遍历了整颗Fiber树,在源码中如果节点什么都没改变会命中优化的逻辑,然后跳过这个节点的遍历
  • commit我们也遍历了整颗Fiber树,源码中只遍历带有effect的Fiber节点,也就是遍历effectList
  • 每次遍历的时候我们都是新建节点,源码中某些条件会复用节点
  • 没有用到优先级

第一步:渲染器和入口函数

const React = {
   
   
    createElement,
    render,
  }
  
  const container = document.getElementById("root")
  
  const updateValue = e => {
   
   
    rerender(e.target.value)
  }
  
  const rerender = value => {
   
   
    const element = (
      <div>
        <input onInput={
   
   updateValue} value={
   
   value} />
        <h2>Hello {
   
   value}</h2>
      </div>
    )
    React.render(element, container)
  }
  
  rerender("World")

第二步:创建dom节点函数

function createElement(type, props, ...children) {
   
   //创建element
    return {
   
   
      type,
      props: {
   
   
        ...props,
        children: children.map(child =>
          typeof child === "object"
            ? child
            : createTextElement(child)
        ),
      },
    }
  }
  
  function createTextElement(text) {
   
   //创建text类型
    return {
   
   
      type: "TEXT_ELEMENT",
      props: {
   
   
        nodeValue: text,
        children: [],
      },
    }
  }
  
  function createDom(fiber) {
   
   //创建dom
    const dom =
      fiber.type == "TEXT_ELEMENT"
        ? document.createTextNode("")
        : document.createElement(fiber.type)
  
    updateDom(dom, {
   
   }, fiber.props)
  
    return dom
  }

第三步:更新节点函数

const isEvent = key => key.startsWith("on")
  const isProperty = key =>
    key !== "children" && !isEvent(key)
  const isNew = (prev, next) => key =>
    prev[key] !== next[key]
  const isGone = (prev, next) => key => !(key in next)
  function updateDom(dom, prevProps, nextProps) {
   
   //更新节点属性

    //删除老的事件
    Object.keys(prevProps)
      .filter(isEvent)
      .filter(
        key =>
          !(key in nextProps) ||
          isNew(prevProps, nextProps)(key)
      )
      .forEach(name => {
   
   
        const eventType = name
          .toLowerCase()
          .substring(2)
        dom.removeEventListener
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值