react源码解析20.总结第一章的面试题解答

news2024/11/24 20:55:57

总结

至此我们介绍了react的理念,如果解决cpu和io的瓶颈,关键是实现异步可中断的更新

我们介绍了react源码架构(ui=fn(state)),从scheduler开始调度(根据过期事件判断优先级),经过render阶段的深度优先遍历形成effectList(中间会执行reconcile|diff),交给commit处理真实节点(中间穿插生命周期和部分hooks),而这些调度的过程都离不开Fiber的支撑,Fiber是工作单元,也是节点优先级、更新UpdateQueue、节点信息的载体,Fiber双缓存则提供了对比前后节点更新的基础。我们还介绍了jsx是React.createElement的语法糖。Lane模型则提供了更细粒度的优先级对比和计算,这一切都为concurrent mode提供了基础,在这之上变可以实现Suspense和batchedUpdate(16、17版本实现的逻辑不一样),18章context的valueStack和valueCursor在整个架构中运行机制,19章介绍了新版事件系统,包括事件生产、监听和触发,

面试题简答(详见视频源码角度讲解)

  1. jsx和Fiber有什么关系

    答:mount时通过jsx对象(调用createElement的结果)调用createFiberFromElement生成Fiber
    update时通过reconcileChildFibers或reconcileChildrenArray对比新jsx和老的Fiber(current Fiber)生成新的wip Fiber树

  2. react17之前jsx文件为什么要声明import React from ‘react’,之后为什么不需要了

    答:jsx经过编译之后编程React.createElement,不引入React就会报错,react17改变了编译方式,变成了jsx.createElement

function App() {
  return <h1>Hello World</h1>;
}
//转换后
import {jsx as _jsx} from 'react/jsx-runtime';

function App() {
  return _jsx('h1', { children: 'Hello world' });
}
  1. Fiber是什么,它为什么能提高性能

    答:Fiber是一个js对象,能承载节点信息、优先级、updateQueue,同时它还是一个工作单元。

    1. Fiber双缓存可以在构建好wip Fiber树之后切换成current Fiber,内存中直接一次性切换,提高了性能
    2. Fiber的存在使异步可中断的更新成为了可能,作为工作单元,可以在时间片内执行工作,没时间了交还执行权给浏览器,下次时间片继续执行之前暂停之后返回的Fiber
    3. Fiber可以在reconcile的时候进行相应的diff更新,让最后的更新应用在真实节点上

hooks

  1. 为什么hooks不能写在条件判断中

    答:hook会按顺序存储在链表中,如果写在条件判断中,就没法保持链表的顺序

状态/生命周期

  1. setState是同步的还是异步的

    答:legacy模式下:命中batchedUpdates时是异步 未命中batchedUpdates时是同步的

    concurrent模式下:都是异步的

  2. componentWillMount、componentWillMount、componentWillUpdate为什么标记UNSAFE

    答:新的Fiber架构能在scheduler的调度下实现暂停继续,排列优先级,Lane模型能使Fiber节点具有优先级,在高优先级的任务打断低优先级的任务时,低优先级的更新可能会被跳过,所有以上生命周期可能会被执行多次,和之前版本的行为不一致。

组件

  1. react元素$$typeof属性什么

    答:用来表示元素的类型,是一个symbol类型

  2. react怎么区分Class组件和Function组件

    答:Class组件prototype上有isReactComponent属性

  3. 函数组件和类组件的相同点和不同点

    答:相同点:都可以接收props返回react元素

    不同点:

    编程思想:类组件需要创建实例,面向对象,函数组件不需要创建实例,接收输入,返回输出,函数式编程

    内存占用:类组建需要创建并保存实例,占用一定的内存

    值捕获特性:函数组件具有值捕获的特性 下面的函数组件换成类组件打印的num一样吗

export default function App() {
  const [num, setNum] = useState(0);
  const click = () => {
    setTimeout(() => {
      console.log(num);
    }, 3000);
    setNum(num + 1);
  };

  return <div onClick={click}>click {num}</div>;
}

export default class App extends React.Component {
  state = {
    num: 0
  };

  click = () => {
    setTimeout(() => {
      console.log(this.state.num);
    }, 3000);
    this.setState({ num: this.state.num + 1 });
  };

  render() {
    return <div onClick={this.click}>click {this.state.num}</div>;
  }

}

可测试性:函数组件方便测试

状态:类组件有自己的状态,函数组件没有只能通过useState

生命周期:类组件有完整生命周期,函数组件没有可以使用useEffect实现类似的生命周期

逻辑复用:类组件继承 Hoc(逻辑混乱 嵌套),组合优于继承,函数组件hook逻辑复用

跳过更新:shouldComponentUpdate PureComponent,React.memo

发展未来:函数组件将成为主流,屏蔽this、规范、复用,适合时间分片和渲染

开放性问题

  1. 说说你对react的理解/请说一下react的渲染过程
    答:是什么:react是构建用户界面的js库能干什么:可以用组件化的方式构建快速响应的web应用程序如何干:声明式(jsx) 组件化(方便拆分和复用 高内聚 低耦合) 一次学习随处编写做的怎么样: 优缺(社区繁荣 一次学习随处编写 api简介)缺点(没有系统解决方案 选型成本高 过于灵活)设计理念:跨平台(虚拟dom) 快速响应(异步可中断 增量更新)性能瓶颈:cpu io fiber时间片 concurrent mode渲染过程:scheduler render commit Fiber架构
  2. 聊聊react生命周期
    详见第11章
  3. 简述diff算法
    详见第9章
  4. react有哪些优化手段
    答:shouldComponentUpdate、不可变数据结构、列表key、pureComponent、react.memo、useEffect依赖项、useCallback、useMemo、bailoutOnAlreadyFinishedWork …
  5. react为什么引入jsx
    答:jsx声明式 虚拟dom跨平台解释概念:jsx是js语法的扩展 可以很好的描述ui jsx是React.createElement的语法糖想实现什么目的:声明式 代码结构简洁 可读性强 结构样式和事件可以实现高内聚 低耦合 、复用和组合 不需要引入新的概念和语法 只写js, 虚拟dom跨平有哪些可选方案:模版语法 vue ag引入了控制器 作用域 服务等概念jsx原理:babel抽象语法树 classic是老的转换 automatic新的转换
  6. 说说virtual Dom的理解
    答:是什么:React.createElement函数返回的就是虚拟dom,用js对象描述真实dom的js对象优点:处理了浏览器的兼容性 防范xss攻击 跨平台 差异化更新 减少更新的dom操作缺点:额外的内存 初次渲染不一定快
  7. 你对合成事件的理解
类型原生事件合成事件
命名方式全小写小驼峰
事件处理函数字符串函数对象
阻止默认行为返回falseevent.preventDefault()

理解:

  • React把事件委托到document上(v17是container节点上)
  • 先处理原生事件 冒泡到document上在处理react事件
  • React事件绑定发生在reconcile阶段 会在原生事件绑定前执行

相关参考视频讲解:进入学习

优势:

  • 进行了浏览器兼容。顶层事件代理,能保证冒泡一致性(混合使用会出现混乱)
  • 默认批量更新
  • 避免事件对象频繁创建和回收,react引入事件池,在事件池中获取和释放对象(react17中废弃)
    react17事件绑定在容器上了
  1. 我们写的事件是绑定在dom上么,如果不是绑定在哪里?
    答:v16绑定在document上,v17绑定在container上
  2. 为什么我们的事件手动绑定this(不是箭头函数的情况)
    答:合成事件监听函数在执行的时候会丢失上下文
  3. 为什么不能用 return false 来阻止事件的默认行为?
    答:说到底还是合成事件和原生事件触发时机不一样
  4. react怎么通过dom元素,找到与之对应的 fiber对象的?
    答:通过internalInstanceKey对应 react源码182

解释结果和现象

  1. 点击Father组件的div,Child会打印Child吗
function Child() {
  console.log('Child');
  return <div>Child</div>;
}


function Father(props) {
  const [num, setNum] = React.useState(0);
  return (
    <div onClick={() => {setNum(num + 1)}}>
      {num}
      {props.children}
    </div>
  );
}


function App() {
  return (
    <Father>
      <Child/>
    </Father>
  );
}

const rootEl = document.querySelector("#root");
ReactDOM.render(<App/>, rootEl);

答: 不会,源码中是否命中bailoutOnAlreadyFinishedWork

  1. 打印顺序是什么
function Child() {
useEffect(() => {
console.log('Child');
}, [])
return <h1>child</h1>;
}

function Father() {
useEffect(() => {
console.log('Father');
}, [])

return <Child/>;
}

function App() {
useEffect(() => {
console.log('App');
}, [])

return <Father/>;
}

答:Child ,Father ,App ,render阶段mount时深度优先遍历,commit阶段useEffect执行时机

  1. useLayout/componentDidMount和useEffect的区别是什么
class App extends React.Component {
  componentDidMount() {
    console.log('mount');
  }
}

useEffect(() => {
  console.log('useEffect');
}, [])

答:他们在commit阶段不同时机执行,useEffect在commit阶段结尾异步调用,useLayout/componentDidMount同步调用

react源码201

  1. 如何解释demo_4、demo_8、demo_9出现的现象
    答:demo_4:useEffect和useLayoutEffect的区别
    demo_8:任务的优先级有关,见源码分析视频
    demo_9:批量更新有关,见源码分析视频

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/154461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

测试开发 | Jenkins job 机制该如何使用?

Jenkins 像老板一样管理各种 job 。job 是 Jenkins 的一个执行计划&#xff0c;是一系列操作的集合&#xff0c;Jenkins 里的最常用的功能就是 job 的构建&#xff0c;即任务的构建。通过构建 job 即可让工人为你工作。 image806387 84.3 KB 创建 job及配置步聚 可以通过如下步…

C#,图像二值化(20)——全局阈值的耶恩算法(Yen Thresholding)及源代码

1 全局阈值的耶恩算法&#xff08;Yen Throsholding&#xff09;常见阈值算法1.1黄算法HuangThresholdImageFilter使用Shannon的熵函数实现Huang的模糊阈值[1]。模糊性度量表示原始图像与其二进制版本之间的差异。对于给定的阈值级别&#xff0c;像素的模糊隶属度函数由像素灰度…

Java中常用API总结(7)—— BigDecimal类

BigDecimal类一、前言二、概述1.API帮助文档2.使用方法三、常见方法1.格式2.实例3.报错4.解决方法四、结语一、前言 在使用float或者double类型的数据在进行数学运算的时候&#xff0c;很有可能会产生 精度丢失问题 我们都知道计算机底层在进行运算的时候&#xff0c;使用的都…

Echarts image 使用

通过image://...xx.png 在扇形图中可能会失败&#xff0c;可以将需要载入的img转换成base64直接载入可以通过背景色来载入图片 backgroundColor: {image: xxx/xxx.jpg },实例&#xff08;扇形图&#xff09;&#xff1a;var option {tooltip: {trigger: "item",show…

如何用用C++实现通达信接口调用?有哪些技巧

c作为三大计算机语言之一&#xff0c;在编程时很受投资者的偏爱&#xff0c;特别是在通达信接口软件开发时C更是担任着重要的开发角色&#xff0c;今天小编就来和大家说一下如何用C实现通达信接口调用&#xff1f; 用C查询股份数据代码&#xff08;部分&#xff09; std::cou…

C4D和Maya哪个学起来更容易

Maxon Cinema 4D和 Autodesk Maya 是最著名的两种 3D 软件&#xff0c;艺术家和工作室经常在许多领域使用它们。它们都有不同的功能&#xff0c;在本文中&#xff0c;让我们对它们进行比较。我们将尝试向您概述它们之间的主要区别&#xff0c;以及这两者的功能。哪一个更容易使…

2: [SpringData集成Elasticsearch] --- 配置打印命令日志

文章目录一&#xff1a;引入SpringDataElasticsearch依赖二&#xff1a;创建RestHighLevelClient配置类三&#xff1a;配置YML&#xff1a; logging.level --- 日志等级三&#xff1a;请求接口&#xff0c;查看日志3.1&#xff1a;请求代码3.2&#xff1a;Postman请求地址3.3&a…

LayoutInflater学习(一)之布局解析

LayoutInflater的创建与实例化 LayoutInflater是位于 "android.view" 包下的一个抽象类,同样它也是一个系统级服务 package android.view; SystemService(Context.LAYOUT_INFLATER_SERVICE) public abstract class LayoutInflater { LayoutInflater是用来解析 xml…

桌面录屏软件,分享3个十分便捷的录屏软件

​图片和视频都是人们传播信息的方式&#xff0c;不过相比于图片&#xff0c;视频能够更加直观生动的表达信息。在日常生活中&#xff0c;除了屏幕上记录一些应用程序的内容外&#xff0c;有时我们还需要记录电脑桌面。有更好的桌面录屏软件吗&#xff1f;当然&#xff0c;小编…

Git操作不规范,战友提刀来相见!

年终奖都没了&#xff0c;还要扣我绩效&#xff0c;门都没有&#xff0c;哈哈。 这波骚Git操作我也是第一次用&#xff0c;担心闪了腰&#xff0c;所以不仅做了备份&#xff0c;也做了笔记&#xff0c;分享给大家。 文末留言抽奖&#xff0c;聊聊你的年终奖。 问题描述 小A和…

C++多线程(并发、进程、线程的基本概念和综述)

并发、进程、线程的基本概念和综述 并发 并发表示两个或者更多任务(独立的活动)同时发生(进行)。例如&#xff0c;一面唱歌一面弹琴&#xff0c;一面走路一面说话&#xff0c;画画的时候听小说等。回归到计算机领域&#xff0c;所谓并发&#xff0c;就是一个程序同时执行多个…

html 3D立体多形态旋转音乐相册 | 2022都结束了,还不快给女神制作一个特殊的纪念相册

&#x1f4cb; 前言 &#x1f5b1; 博客主页&#xff1a;在下马农的碎碎念✍ 本文由在下马农原创&#xff0c;首发于CSDN&#x1f4c6; 首发时间&#xff1a;2023/01/07&#x1f4c5; 最近更新时间&#xff1a;2023/01/07&#x1f935; 此马非凡马&#xff0c;房星本是星。向前…

零基础掌握IP地址知识,小白必学知识点!

前言 大家好&#xff0c;在生活中我们使用具有上网功能的电子设备都有IP地址&#xff0c;就跟每个人都有自己的名字一样。IP地址分为IPV4 IPV6&#xff0c;我们所说的的IP地址指的是IPV4的地址。 正文 IPV4( Internet Protocol Version 4 )互联协议版本4&#xff0c;有版本V4之…

【HTML+CSS+JavaScript】动感爱心—— I love you~

有段时间没有分享了,no time。 还是抽出一会儿分享一下。有时间会解析的(具体…I don’t know)。 1. 效果展示 真实效果挺好看的,喜欢的朋友,可以给你的女朋友或者喜欢的TA看看呀! 可以根据实际情况修改文案,比如诗歌,或者你爱的人的名字哦~ 2. 源代码分享 2.1 动感…

在Ubuntu上安装docker(Ubuntu版本18.04)

在Ubuntu上安装docker详细步骤1、卸载之前的docker版本2、安装docker仓库3、在系统中添加Docker的官方密钥4、添加docker源5、再次更新源列表6、查看可以安装的docker版本并安装docker7、使用命令查看是否安装成功以及安装的docker版本8、启动 docker服务并设置开机自动启动doc…

FPGA基础之modelsim常见问题

目录 问题一&#xff1a;modelsim破解失败 1&#xff09;现象 2&#xff09;原因 ​ 3&#xff09; 解决 问题一&#xff1a;modelsim破解失败 1&#xff09;现象 modelsim激活失败&#xff0c;原先正常使用过的&#xff0c;重新卸载安装破解&#xff0c;设置环境变量…

Serverless 奇点已来,下一个十年将驶向何方?

本文整理自 QCon 上海站 2022 丁宇&#xff08;叔同&#xff09;的演讲内容。 以前构建应用&#xff0c;需要买 ECS 实例&#xff0c;搭建开源软件体系然后维护它&#xff0c;流量大了扩容&#xff0c;流量小了缩容&#xff0c;整个过程非常复杂繁琐。 用了 Serverless 服务以…

【如何添加本地jar包到maven依赖】

如何添加本地jar包到maven依赖 1、本地jar包和对应依赖如下图&#xff08;刚开始这俩依赖是报红的&#xff09; 2、执行mvn命令如下&#xff1a; mvn install:install-file -DfileD:\ht_mesis-platform\mesis-business\dandian4-1.0.0.jar -Dpackagingjar -DgroupIddandian4…

Java实战:Hutool类库中的DateUtil用法总结

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️荣誉&#xff1a; CSDN博客专家、数据库优质创作者&#x1f3c6;&…

微信小程序 | 一比一复刻抖音短视频

&#x1f4cc;个人主页&#xff1a;个人主页 ​&#x1f9c0; 推荐专栏&#xff1a;小程序开发成神之路 --【这是一个为想要入门和进阶小程序开发专门开启的精品专栏&#xff01;从个人到商业的全套开发教程&#xff0c;实打实的干货分享&#xff0c;确定不来看看&#xff1f; …