数字马力 前端一面 时间50分钟
1.项目介绍,亮点
2.路由怎么实现的,react-router cacherouter是干嘛的,hash router和history router的区别
- 安装react-router-dom
- 创建路由组件
- 使用BrowserRouter或HashRouter包裹应用
- 在组件中使用Link进行导航
其中Browser或HashRouter包裹应用
import {BrowserRouter as Router, Route, Switch} from "react-router-dom";
function App(){
return (
<Router>
<Switch>
<Route path="/path" component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
)
}
使用Link
import {Link} from "react-router-dom";
function Navigation(){
return (
<nav>
<ul>
<li><Link to="/home">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
</nav>
)
}
3.useffect怎么实现副作用的,怎么在卸载前取消订阅
import React, {useState, useEffect} from "react";
function ExampleComponent(){
const [data, setData] = useState(null);
useEffect(()=>{
const fetchDate = async () => {
const result = await fetch("http://api.com");
const jsonData = await result.json();
setData(jsonData);
}
return ()={
//返回的清理函数在组件卸载时执行,用于取消订阅或执行其他清理操作。
};
}, []);
return (
<div>
{data && <p>{data}</p>}
</div>
)
}
4.script阻塞怎么解决,具体讲讲defer和async的区别
脚本阻塞是指浏览器在解析HTML文档时遇到scirpt标签时会停止渲染并下载执行脚本。
使用defer和async来控制脚本的加载和执行
defer告诉浏览器立即下载脚本,但是等文档解析完了再执行。使用defer会在DOMContentLoaded事件之前执行,但是在DOMContentLoaded事件之前执行,浏览器仍然可以并行下载其他资源
async要求浏览器下载完脚本立即执行。不会等文档解析完成。多个带有async属性的脚本会并行下载,下载完成后立即执行,不会按照出行顺序去执行。
区别:
- 执行时机
- defer在文档解析完成后执行
- async在下载完成后立即执行,不会等待文档解析完成
- 执行顺序
- defer安装文档出现顺序执行
- async不保证执行顺序,谁下载完谁先执行
- 对文档解析的影响
- defer不会阻塞文档解析,但会等待文档解析完成后执行
- async会立即下载并执行,不会等待文档解析完成
5.react为什么需要hooks
为了解决组件之间的复用状态逻辑,解决了复用性差、代码冗长、难以理解的生命周期的问题。
并带来以下优势:
- 函数式组件可以拥有状态和副作用
- 更简洁的代码
- 更容易理解和测试
Hooks列表:
- useState:添加局部状态
- useEffect:执行副作用
- useContext:访问上下文获取全局数据
- useReducer:管理复杂状态
- useCallback:缓存回调函数
- useMemo:缓存计算结果
- useRef:创建可变的ref对象
- useLayoutEffect:与useEffect类似,但是在浏览器执行绘制之前触发副作用操作
- useImperativeHandle:在函数式组件中自定义暴露给父组件,场合forwardRef结合使用
6.react class组件和函数组件的区别
- 语法
- class是es6类的,继承React.Component
- 函数组件是简单的JavaScript函数,接受props作为参数,返回React元素
- 状态管理
- class组件可以使用this.state来存储和管理组件状态,并且可以通过this.setState()方法来更新状态
- 函数组件无法直接拥有状态,但是可以通过Hooks如useState和useReducer的引入,拥有内部状态的管理能力
- 生命周期
- class拥有一些列的生命周期,比如componentDidMount、componentDidUpdate、componentWillUnmount等,用于在组件不同状态阶段执行特定的逻辑
- 函数组件可以通过useEffect来模拟类组件中的生命周期,从而在组件渲染、更新和销毁时执行特定的副作用逻辑
- 性能优化
- 由于Class存在一些实例化绑定方法的开销,在大型应用中可能会影响性能
- 函数组件相对于Class组件具有更好的性能,更简单、更轻量,没有实例化的开心,并且可以更好利用React的优化机制
- 代码复用
- 函数组件更容易复用,可以将逻辑抽象为自定义Hook,并在多个组件中共享使用
- Class组件中逻辑复用通常需要使用高阶组件HigherOrderComponents或者渲染属性来实现,更繁琐
7.react fiber是干嘛的
react fiber是react 16引入的一种重新实现的调度算法,用于实现更加高效的组件渲染和更新。目标是实现更好的时间分片和异步渲染,提高性能和用户体验。
主要作用包括:
- 异步渲染:Fiber架构是的React能够在多个渲染阶段中间停下来,执行其他任务,然后返回并继续渲染。这使得React应用在进行大量计算或渲染大型组件树能够更加流畅,避免出现卡顿或阻塞的情况。
- 时间分片:React Fiber将渲染过程分割成多个小任务单元,并且可以在每个任务单元之间进行优先级排序。遮掩就可以根据任务的优先级来动态调整任务执行顺序,来保证优先级的任务能够有效执行
- 增量渲染:Fiber架构支持增量渲染,即将渲染工作分解为多个步骤,比起二可以在多次渲染周期之间复用之前的工作,这样就可以避免不必要的重复计算和渲染,提高效率。
- 错误边缘:FIber架构改进了React的错误处理机制,使得React应用能够更好地捕捉和处理组件渲染过程出现的错误,避免整个应用崩溃。
8.react redux是怎么更新ui的,除了react-redux其他store有了解吗?
React Redux中,但应用状态发生变化,会通过store来更新UI。通过store.dispaptch(action)派发一个action,这个action会被传递给reducer,然后reducer根据action的类型来更新相应状态。
还有mobx、zustand、recoil
9.antd config.privider
ant design中config.provider是一个用于配置全局样式主题的属性。通过设置config.provider,可以定义Ant Design组件中的各种样式变量。从而自定义整个应用程序的主题风格。通常config.provide
10.实现水平垂直居中的方案
- flex
- grid
- place-items: center
- 使用绝对定位
- 父
- position: relative
- 子
- position: absolute
- top: 50%
- left: 50%
- transform: translate(-50%, -50%)
- 父
11.less如何实现第1-8个元素不同的颜色
.container{
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
@color: #fff, #fff, #fff, #ff1, #ff2, #ff2
.loop-colors(@index) when (@index > 0){
&:nth-child(@{index}){
background-color: extract(@colors, @index);
}
.loop-colors(@index - 1);
}
.loop-colors(8);
}
}
12.this了解多少,箭头函数的this为什么在定义时就已经确定
this在调用时确定的,不是在定义的时候确定的。
13.js事件循环
- 执行栈
- 异步任务
- 微任务队列
- 任务队列
14.h5多线程,多线程有什么限制
HTML5没有直接的多线程能力,但是通过web workers技术,可以在浏览器中创建多线程。
限制
- 不能访问DOM
- 通过消息传递通信
- 限制的API
- 独立的全局对象,不能与主线程共享数据
15.babel怎么实现向后兼容的
- 语法转换
- API转换
- Polyfill支持,在旧版本模拟新特性的方法
- 目标浏览器支持
- 插件支持
16.git多人开发时,临时存储方案
- stach
git stash
git stash apply
- 分支切换
- 临时分支
- commit暂存
17.ts泛型是什么?什么时候用到
是一种在定义函数、类、接口时刻从夫组件的工具。允许定义是不指定具体的类型,而是使用时再指定类型,从而使得这个可重复的组件能够使用与多种不同类型的数据。
1、函数泛型:
function identity<T>(arg: T): T{
return arg;
}
let result = identity<string>("Hello");
2、类泛型:可以定义类,其中有些属性或者方法的类型的泛型
class Box<T> {
private value: T;
constructor(value: T){
this.value = value;
}
getValue(): T {
return this.value;
}
}
let box = new Box<number>(10);
3、接口泛型:可以定义接口,其中某些成员是泛型
interface Pair<T, U> {
first: T;
second: U;
}
let pair: Pair<number, string> = {first: 1, second: "two"};
- 数组泛型
let array: Array<number> = [1, 2, 3];