前端面试

React

useEffect 中如何使用 async/await

  1. async函数抽离到外部
    1
    2
    3
    4
    5
    6
    7
    8
    9
    async function fetchMyAPI() {
    let response = await fetch("api/data");
    response = await res.json();
    ådataSet(response);
    }

    useEffect(() => {
    fetchMyAPI();
    }, []);
  2. async立即执行函数
    1
    2
    3
    4
    5
    useEffect(() => { 
    (async function anyNameFunction() {
    await loadContent();
    })();
    }, []);
  3. ahooks - useAsyncEffect
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    function useAsyncEffect(
    effect: () => AsyncGenerator<void, void, void> | Promise<void>,
    deps?: DependencyList,
    ) {
    useEffect(() => {
    const e = effect();
    let cancelled = false;
    async function execute() {
    if (isAsyncGenerator(e)) {
    while (true) {
    const result = await e.next();
    if (result.done || cancelled) {
    break;
    }
    }
    } else {
    await e;
    }
    }
    execute();
    return () => {
    cancelled = true;
    };
    }, deps);
    }

React hooks如何实现类似Redux的状态管理

useContext+useReducer

React key的作用

React useCallback使用场景

  1. 作为props传递的函数,集合memo一起使用;
  2. 作为更新触发的依赖项 主要目的是为了避免高昂的计算和不必要的重复渲染

React闭包陷阱

React reconcile

https://zh-hans.legacy.reactjs.org/docs/reconciliation.html#motivation

特殊的React Hooks

useTransition

useOptimistic

useSyncExternalStore

useImperativeHandle

当多次重复点击按钮时,以下三个 Heading 是如何渲染的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import React, { memo, useMemo, useState } from "react";

const Heading = memo(({ style, title }) => {
console.log("Rendered:", title);
return <h1 style={style}>{title}</h1>;
});

export default function App() {
const [count, setCount] = useState(0);

const normalStyle = {
backgroundColor: "teal",
color: "white",
};

const memoizedStyle = useMemo(() => {
return {
backgroundColor: "red",
color: "white",
};
}, []);

return (
<>
<button
onClick={() => {
setCount(count + 1);
}}
>
Increment {count}
</button>
<Heading style={memoizedStyle} title="Memoized" />
<Heading style={normalStyle} title="Normal" />
<Heading title="React.memo Normal" />
</>
);
}

setState代码输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { useState } from "react";

export default function App() {
const [todo, setTodo] = useState({ id: 1, status: "TODO" });
return (
<div className="App">
<button
onClick={() => {
todo.status = !todo.status;
setTodo(todo);
}}
>
Toggle Status
</button>
<h1>{todo.status}</h1>
</div>
);
}

useCallback和useMemo性能优化

优化React项目性能

  1. 避免不必要的渲染,shouldComponentUpdate、React.memo、React.useMemo、React.useCallback。
  2. 代码分割,React.lazy 动态加载组件
  3. 使用 react-query,对请求响应进行缓存、重发等,避免多次请求,减少网络 IO 消耗及优化渲染次数
  4. 使用 useDebounce,对值及事件处理函数进行防抖,避免状态频繁变动,优化渲染次数
  5. 使用 useImmer

React 19

JavaScript

防抖和节流

实现Promise

正向代理和反向代理

正向代理

正向代理是代理客户端,服务器无法感知客户端,客户端的请求都发往代理服务器,代理服务器替客户端发送请求给服务器,并把服务器响应的数据返回给客户端

应用:翻墙,接口转发实现跨域

反向代理

反向代理是代理服务器,客户端无法感知服务器

应用:负载均衡