React中常见的面试题

news2024/11/19 14:25:50

本文是结合实践中和学习技术文章总结出来的笔记(个人使用),如有雷同纯属正常((✿◠‿◠))

喜欢的话点个赞,谢谢!

1. 约束性组件与非约束性组件

1.1. 非约束性组件

非约束性组件其实就是不能控制状态的组件,比如:

<input type="text" defaultValue="123" onChange={handleChange}>

在这里我们可以输入value值,也可以根据输入的值在change回调里面处理逻辑,但是我们无法控制value值

1.2. 约束性组件

约束性组件就是我们可以直接控制组件的value值或者显示结果的组件,比如:

<input type="text" value={this.state.value} onChange={handleChange}>

在这里我们可以直接控制value值的显示,可以在第三方逻辑中处理value值然后修改显示结果

 

2. 高阶组件 HOC

高阶组件本质是一个函数。它可以接收一个组件作为参数,然后返回处理完逻辑处理结果之后返回一个新的组件。

高阶组件通常用于处理一些比如路由守卫封装或者表单组件的逻辑复用封装,比如封装一个弹出窗:

显示页面:

import ModalFn from "../../Component/index.tsx"
import { Modal } from 'antd';
const ModalExtend = ModalFn(Modal)
function Test() {
    return <div>
        <ModalExtend />
    </div>
}

export default Test

封装逻辑:

import { Button } from 'antd';
import React from 'react';

export default function ModalFn(Modal) {
    return class ModalExtend extends React.PureComponent {
        state = {
            isModalOpen: false
        }

        //显示弹出窗
        handleShowModal = () => {
            this.setState({
                isModalOpen: true
            })
        }
        //确定按钮
        handleOk = () => {

        }
        //取消按钮
        handleCancel = () => {
            this.setState({
                isModalOpen: false
            })
        }
        render(): React.ReactNode {
            const ModalProps = {
                open: this.state.isModalOpen,
                onOk: this.handleOk,
                onCancel: this.handleCancel,
                title: "Basic Modal"
            }

            return (
                <>
                    <Button type="primary" onClick={this.handleShowModal}>
                        Open Modal
                    </Button>
                    <Modal {...ModalProps} />
                </>
            )
        }

    }
}

展示效果:

 

2e73050cd669bc124d2ca26ec6d406c7.png

不过我们通常不会这么做,我们做antd的二次封装只要传递参数即可,只不过一般的二次封装的思路都是学习自高阶组件

 

3. React路由

现在前端的项目一般都是SPA单页面应用,不再是以前多个页面多套HTML代码项目了,应用内的跳转不需要刷新页面就能完成页面跳转靠的就是路由系统

React路由系统分为BrowerRouter路由和HashRouter路由,分别表现为:

  • BrowerRouter路由: 就像平常网站www.baidu.com/test 这就是一个路由,在服务器渲染的时候需要后端做映射
  • HashRouter 路由: 比BrowerRouter多出了一个#符号,使用URL的哈希值实现,比如www.baidu.com/#/test,不需要后端做URL映射

可能会问到路由拦截(也就是路由守卫)的问题,这里不详细介绍,可以看看我之前发的React路由文章

 

4. React diff算法和虚拟DOM

diff算法是React实现组件差异化更新的核心逻辑之一,它与虚拟DOM是相辅相成的存在,正因为有了虚拟DOM才有diff的可能性

虚拟DOM本质上是JS到DOM之间的一个映射缓存,它在形态上表现为一个能够描述DOM树结构和属性信息的JS对象,如下图所示:

function Test(){
  return(
    <div className='aaa'>
        React
    </div>
  )
}

 

7a76a530e9bdda41254a04b0459b5832.png

diff算法: diff算法的本身是VirtualDOM 在render的时候差量更新时需要进行比对需要更新哪些节点的一个产物,diff是递归更新虚拟DOM树的,一旦开始不可以暂停打断

更详细的diff算法和解释可以看看我之前发的React diff算法与虚拟DOM

5. React 性能优化

React性能优化一般有两种情况,类组件性能优化和函数组件性能优化,更多详细内容可以看看我之前写的React性能优化专题

5.1. 类组件:

PurComponent : 类组件可以继承React.PurComponent 组件,PurComponent组件在shouldComponentUpdate里面对组件state、props更新渲染做了浅比较

Immutable.js : Immutable 是Facebook推出的用来给数据做持久性优化的库,配合PurComponent使用的话可以进行组件更新渲染的深层次比较,避免组件无意义的二次渲染

5.2. 函数组件

React.memo:

React.memo 的使用方式相比immutable更加简单一些.它本质上是一个高阶组件,直接包裹住要声明的函数组件即可,内部也是浅比较,与PurComponent类似

useMemo:

React.memo的特性和用法,缺点很明显,无法感知组件内部的state,还有就是不能控制单一的某一段逻辑,所以官方建议使用useMemo加强深比较的能力,useMemo用法就是传递2个参数:第一个是需要渲染的内容,第二个参数是一个状态,根据这个状态是否变化来决定这段内容的更新与否

 

6. React 数据持久化

有一些面试官不会直接问状态管理容器redux、mobx之类的,会直接问你了解React数据持久化么?

一般的第三方数据持久化库都是用localStorage 或 AsyncStorage来进行存储数据的,我这里以redux-persist + @reduxjs/toolkit为例:

安装:

yarn add redux-persist
yarn add react-redux
yarn add @reduxjs/toolkit

配置src/store.ts

import { configureStore, combineReducers } from '@reduxjs/toolkit'
import HomeReducer from './models/home'

import { persistStore, persistReducer } from 'redux-persist'
// 选择持久化存储引擎,如 localStorage 或 AsyncStorage
import storage from 'redux-persist/lib/storage' // 默认使用localStorage作为存储引擎

// 组合各个模块的reducer
const reducer = combineReducers({
    Home: HomeReducer
})

// 配置持久化设置
const persistConfig = {
    key: 'root', // 存储的键名
    storage,// 持久化存储引擎
    // 可选的配置项,如白名单、黑名单等 选其一就好了
    // blacklist:['Home'], // 只有 Home 不会被缓存
    whitelist: ["Home"], // 只有 Home 会被缓存
}

const persistedReducer = persistReducer(persistConfig, reducer)

export const store = configureStore({
    reducer: persistedReducer, // 注册子模块
    middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware({
            serializableCheck: false // 关闭默认的序列化检查//关闭严格模式
        })
})

export const persistor = persistStore(store)

配置src/models/HomeReducer

import { createSlice } from '@reduxjs/toolkit'

// 定义状态类型  
interface Action {
    payload: number,
    type: string
}
interface State {
    count: number
}

export const HomeStore = createSlice({
    // 模块名称独一无二
    name: 'home',
    // 初始数据
    initialState: {
        count: 1
    },
    // 修改数据的同步方法
    reducers: {
        increment: (state: State, action: Action) => {
            state.count += action.payload
        },
        decrement: (state: State, action: Action) => {
            state.count -= action.payload
        },
    }
})

// 导出
export const { increment, decrement } = HomeStore.actions
export default HomeStore.reducer

配置好了以后:

 

1a044ae9977062de57711d2db2d0a34f.png

刷新没有变化

 

298b677810b22396e9ef30db37f8f77e.png

mac不太方便做GIF,过程也很简单,大家可以create一个demo自己尝试一下

 

7. React Hooks

Hooks基本上也是属于热门面试问答题,主要涉及到几个方面:常用的Hooks钩子、Hooks组件与类组件的区别、自定义Hooks、Hooks的逻辑复用

内容太多这里就不详细描述了.有兴趣的同学可以直接跳转查看详细内容React Hooks专题

 

8. React Fiber架构

React Fiber架构是16.x之后更新的,目的是为了重写原来的React 15以及之前版本的调和过程,这里做一个简短的描述,更多详细内容可以查阅React Fiber专题

8.1. React 15及更老版本 diff算法

React 15中的diff算法采用的是分层递归方式查找更新过程中有差异的一些DOM节点,主要是基于虚拟DOM节点树来递归查询,其主逻辑有以下几个部分组成:(此处简单介绍,详细内容可查阅React diff算法专题)

  1. 首先判断是否存在旧的虚拟DOM树节点,没有的话直接创建新虚拟DOM树
  2. 判断旧的虚拟DOM是否与新的虚拟DOM类型一致,不一致重新创建
  3. 判断旧的虚拟DOM是否为组件,如果为组件又要在内部逻辑判断是否为同组件更新等等
  4. 如果旧的虚拟DOM与新的虚拟DOM类型一致(高频diff类型),如果存在key值则用key值进行操作,比如移动位置新增一个节点等等,如果不存在key值,那么只能使用diff重新递归更新。当我们没有在批量生成节点的时候标记key值,React官方会给我们抛出一个warning,提示我们必须使用key,否则将影响应用性能

 

React 15下的diff算法由于采用的是递归的形式,一旦开始不可以暂停/结束,只能等待任务完成,那么我们在更新一个比较庞大的任务的时候,往往会带来页面卡死/卡顿等问题,为了解决这个问题React官方在16版本推出Fiber架构

8.2. React Fiber

Fiber架构推出的原因上面我们上面已经讲过了,主要是为了解决diff算法递归到底不回头的问题,我们先来看看Fiber的特点

Fiber架构的核心: 可中断、可恢复、优先级

在 React 16 之前,React 的渲染和更新阶段依赖的是如下图所示的两层架构:

8df0b6cdf3ba567f7e9815a072db207e.jpeg

而在 React 16 中,为了实现“可中断”和“优先级”,两层架构变成了如下图所示的三层架构:

a15000df2029d54ccb75813f33001e0c.jpeg

对比React15多出了一个Scheduler(优先级调度器),调度器的作用是,每次触发更新的时候调度更新的优先级

比如有一个更新任务B抵达调度器,调度器将其塞入Reconciler层,此时又有一个更新任务A抵达,调度器发现A的优先级高于B,那么就会中断B的更新,优先更新A,等A执行完了之后,再将中断的B重新加入Reconciler层,继续它的渲染流程,这就是可恢复

 

Fiber结构的本质

虽然大部分人都将Fiber的结构称为Fiber树,但是实际上Fiber的数据结构已经从树变成了链表的形式,此处引用某大佬的一张图来直观展示:

badf97e8a764180ee0645b8948627237.png

 

(未完待更新)

 

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

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

相关文章

一个思维狂赚20万+?揭秘电商平台隐藏的流量认知!

你想要的流量&#xff0c;资源&#xff0c;人脉&#xff0c;都已经有人为你准备&#xff0c;你只需要找到拥有这些资源的人。对于流量和信息&#xff0c;也是一样&#xff0c;你想找的客户和产品&#xff0c;都已经有人为你准备在淘宝、拼多多等电商平台&#xff0c;你只需要找…

【踏雪无痕的痕六】——数学中有意思的问题

一、背景介绍 提出一个问题往往比解决一个问题更有意义&#xff0c;因为提出一个问题相当于提出了一个思考问题的维度&#xff1b;而解决一个问题是沿着这个维度将已有的知识串起来的过程 三、过程 1.数人数你会吗&#xff1f; 小名再第10位&#xff0c;小李再第15位&#…

VRTK4.0学习——(二)

手柄绑定以及显示 1.导入CameraRigs.UnityXRPluginFramework 和 CameraRigs.TrackedAlias 预设&#xff0c;将CameraRigs.UnityXRPluginFramework拖入CameraRigs.TrackedAlias的Elements中即可&#xff0c;运行软件后即可看到手柄了 注&#xff1a;如果无法看到手柄&#xff…

AI降痕工具使用指南:如何有效降低AIGC疑似度

随着人工智能技术的突飞猛进&#xff0c;AI生成内容&#xff08;AIGC&#xff09;已被广泛用于学术论文撰写中&#xff0c;提高效率同时也带来了原创性的挑战。面对日益严格的学术审查&#xff0c;一个突出的问题是&#xff1a;使用AI代写的论文能否通过内容检测&#xff1f;因…

《精品生活》万方普刊投稿发表简介

《精品生活》杂志是由国家新闻出版总署批准&#xff0c;南方出版传媒股份有限公司主管&#xff0c;广东大沿海出版工贸有限公司主办&#xff0c;广东精品生活杂志社出版的综合性文化期刊。主要栏目&#xff1a;教学研究、艺术教育、文化广角、民族文化、理论前沿、综合论坛。 刊…

生命周期钩子小案例

文章目录 一、在created中发送数据二、在mounted中获取焦点 一、在created中发送数据 <body><div id"app"><ul><li v-for"(item, index) in list" :key"item.id" class"news"><div class"left"…

从功能性磁共振成像(fMRI)数据重建音频

听觉是人类最重要的感官之一&#xff0c;它负责接收外部的听觉刺激&#xff0c;并将这些信息传递给大脑进行处理和理解。研究人员正致力于从神经科学和计算机科学两个领域探索人脑的听觉感知机制。一个关键目标是从人脑中解码神经信息&#xff0c;并重建原始的刺激。常见的大脑…

用友BIP收入云:助力旅游行业实现高效收入自动化,驱动收入增长

在数字化浪潮的推动下&#xff0c;旅游行业正经历着前所未有的变革。从传统的线下服务模式到线上线下融合&#xff0c;再到如今的智能化、自动化管理&#xff0c;每一步都标志着旅游行业向更高效、更精准、更便捷的方向发展。其中&#xff0c;收入管理作为旅游企业运营的核心环…

机器学习:更多关于元学习

目录 Meta Learning vs Self-supervised Learning 自监督学习——找初始化的参数MAML 自动学出合适的参数 MAML&#xff1a;不断的学初始化参数MAML的初始化参数来自BERT MAML&#xff1a;找出来的初始化参数能在训练任务上表现的很好BERT&#xff1a;自监督目标是不同的下游任…

msvcp140.dll是什么dll文件?msvcp140.dll文件的丢失要怎么去修复?

msvcp140.dll是什么dll文件&#xff1f;一般会问出这种问题的人&#xff0c;都是遇到了msvcp140.dll丢失的情况了&#xff0c;这时候你的一些程序是打不开的&#xff0c;你需要修复好msvcp140.dll文件才可以正常的打开程序&#xff0c;今天我们就来了解一下msvcp140.dll这文件&…

KT1025A的双模蓝牙芯片,参考标准蓝牙天线,蓝牙距离短,会卡

一、问题简介 使用KT1025A的双模蓝牙芯片&#xff0c;为什么我参考BT201或者BT301&#xff0c;或者BT321F设计的蓝牙天线&#xff0c;蓝牙距离短&#xff0c;会卡等等&#xff0c;这个可能是什么原因&#xff0c;如何改善呢&#xff1f; 问题详细分析 首先看看客户的板子PCB…

opencv快速安装以及各种查看版本命令

安装opencv并查看其版本&#xff0c;直接通过一个可执行文件实现。 #!/bin/bashwget https://codeload.github.com/opencv/opencv/zip/3.4 -O opencv-3.4.zip && unzip opencv-3.4.zip && cd opencv-3.4 && \mkdir build && cd build &&a…

C++--DAY3

思维导图 设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数。 #include <iostream>using namespace std; class …

【文档智能】符合人类阅读顺序的文档模型-LayoutReader原理及权重开源

引言 阅读顺序检测旨在捕获人类读者能够自然理解的单词序列。现有的OCR引擎通常按照从上到下、从左到右的方式排列识别到的文本行&#xff0c;但这并不适用于某些文档类型&#xff0c;如多栏模板、表格等。LayoutReader模型使用seq2seq模型捕获文本和布局信息&#xff0c;用于…

品牌营销的“必杀技”,一文带你看懂如何实现精准营销

你在遇到疑惑寻求解决方法时是否会优先想到“百度一下”&#xff1f;我们脑中的优先选择其实就是品牌将自身特点结合其目标用户信息采取精准营销从而完成的广告信息的成功投放。而精准营销&#xff0c;作为一种现代化的广告营销方式&#xff0c;已成为品牌营销的新趋势&#xf…

varchar 字段扩展问题

背景 近期接到一个产品需求&#xff0c;由于上游业务字段扩大了字段&#xff0c;下游的字段也得跟着调整扩大&#xff0c;这就涉及几十张大表&#xff0c;十几亿行数据的变更。 如果按照传统方式 onlie-ddl 借用第三方工具也得三四天分批跑&#xff0c;看了看MySQL官网&#…

0605_C++3

练习1&#xff1a; 设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数 #include <iostream>using namespace std; …

重学java 65.IO流 缓冲流

I am not afraid tomorrow for I have seen yesterday and love today —— 24.6.5 一、字节缓冲流 1.字节缓冲流的意义 之前所写的FileOutputstream、FileInputstream、FileReader、Filewriter这都叫做基本流,其中FileInputstream和FieOutputstream的读写方法都是本地方法(方…

解锁ArrayBlockingQueue奥秘:深入源码的精彩之旅

1.简介 ArrayBlockingQueue 是 BlockingQueue 接口的一个实现类&#xff0c;它基于数组实现了一个有界阻塞队列。创建 ArrayBlockingQueue 实例时需要指定队列的容量&#xff0c;队列的大小是固定的&#xff0c;无法动态增长。 主要特点包括&#xff1a; 有界性&#xff1a;A…

AI大模型+产品经理:打造智能产品的黄金组合

前言 当我们谈论AI大模型与产品经理的结合&#xff0c;不仅仅是技术与创意的碰撞&#xff0c;更是对未来智能生活的期待。想象一下&#xff0c;当产品的灵魂被注入智能的血液&#xff0c;它们将成为我们生活中不可或缺的伙伴。 我们不仅仅是要探索AI大模型的深层技术&#xf…