2025前端面试题-React高阶篇

1,011 阅读16分钟

以下为React面试高阶篇考察点总结,具体知识点不会太详细,主要梳理面试核心考察点,为面试做准备。

一、React-Router

2.React-Router的核心作用

  • SPA导航:在单页面应用中管理不同视图的切换,无需重新加载页面
  • URL与组件映射:将URL路径映射到对应的React组件,保持UI和URL同步
  • 历史记录管理:支持浏览器历史记录的导航(前进/后退)

2.核心组件与API

1.路由器类型

BrowserRouter
  • 使用HTML5 History API(pushState,replaceState)保持UI与URL同步
import { BrowserRouter } from 'react-router-dom';
<BrowserRouter>
  <App />
</BrowserRouter>
HashRouter
<HashRouter>
  <App />
</HashRouter>

2.路由定义

Route:定义路径与组件的映射关系
  • 使用URL的hash部分(如/#home),适用于不支持History API的旧浏览器
    • v5版本:
<Route path="/users" component={Users} />
- v6版本
<Route path="/users" element={<Users />} />
Routes(v6替代v5的Switch)
  • 仅渲染第一个匹配的Route,提升性能
<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
</Routes>

2.导航组件

  • Link:生成无刷新导航链接
<Link to="/about">关于</Link>
  • Navigate(V6替代V5的Redirect):重定向到指定路径
<Route path="/old" element={<Navigate to="/new" />} />

3.版本差异(v5 VS v6)

特性v5v6
路由匹配顺序匹配所有 Route优先精确匹配,使用 Routes
嵌套路由在子组件中定义嵌套 Route直接在父 Route 内嵌套
重定向Redirect 组件Navigate 组件 + replace 属性
编程式导航useHistoryuseNavigate
路由参数useParams 获取useParams + 动态路由语法优化

常见问题与解决方案

1.如何实现嵌套路由

  • v5
<Route path="/users" component={Users}>
  <Route path="/users/:id" component={UserDetail} />
</Route>
// Users 组件内部渲染子路由:
{this.props.children}
  • v6
<Route path="/users" element={<Users />}>
  <Route path=":id" element={<UserDetail />} />
</Route>
// Users 组件使用 `<Outlet />` 渲染子路由:
import { Outlet } from 'react-router-dom';
function Users() {
  return (
    <div>
      <h1>用户列表</h1>
      <Outlet />
    </div>
  );
}

2.如何动态处理路由参数?

// 定义动态路径
<Route path="/users/:userId" element={<UserProfile />} />

// 在组件中获取参数
import { useParams } from 'react-router-dom';
function UserProfile() {
  const { userId } = useParams();
  return <div>用户ID: {userId}</div>;
}

3.编程式导航的实现

  • v5
import { useHistory } from 'react-router-dom';
function Login() {
  const history = useHistory();
  const handleLogin = () => {
    history.push('/dashboard');
  };
  return <button onClick={handleLogin}>登录</button>;
}
  • v6
import { useNavigate } from 'react-router-dom';
function Login() {
  const navigate = useNavigate();
  const handleLogin = () => {
    navigate('/dashboard', { state: { from: '/login' } });
  };
  return <button onClick={handleLogin}>登录</button>;
}

4.路由守卫

function PrivateRoute({ children }){
    const isAuthenticated = useAuth(); // 自定义认证逻辑
    return isAuthenticate ? chilren : <Navigate to="/login" />;
    
}
// 使用方式
<Route
    path="/dashbord"
    element={ 
        <PrivateRoute>
            <Dashboard />
        </PrivateRoute>
    }

5.处理404页面

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
  <Route path="*" element={<NotFound />} />
</Routes>

5.高级技巧与最佳实践

1.代码分割与懒加载

  • 结合React.lazySuspense实现按需加载
const Users = React.lazy(() => import('./Users'));
<Route path="/users" element={
  <Suspense fallback={<Loading />}>
    <Users />
  </Suspense>
} />

2.传递状态至路由组件

  • 使用state属性传递
navigate('/profile', { state: { userData: data } });
// 在目标组件中获取
const location = useLocation();
const userData = location.state?.userData;

3.使用useRoutes配置式路由(V6)

  • 集中管理路由配置
const routes = useRoutes([
  { path: '/', element: <Home /> },
  { path: 'users', element: <Users />, children: [
    { path: ':id', element: <UserDetail /> }
  ]}
]);
return routes;

6.高频面试题

1.BrowserRouter和HashRouter有什么区别?
  • BrowserRouter使用HTML5 History API,URL格式为example.com/path
  • HashRouter使用URL Hash(example/#/path),兼容旧浏览器但不够美观
2.React-Router V6有哪些重大改进
  1. 引入Routes代替Switch,提升匹配逻辑
  2. 嵌套路由配置更简洁,支持相对路径
  3. 移除Redirect,改用Navigate
  4. element属性直接传递JSX元素,支持更灵活的组件组合
3.如何实现路由鉴权
  • 使用高阶组件或自定义路由组件包裹需要保护的路径,检查用户权限后决定渲染目标组件还是重定向到登录页
4.为什么需要exact属性(V5)
  • 确保路径完全匹配。例如,path="/" 没有exact时会匹配所有以/开头的URL。v6中默认精确匹配,无需此属性。

二、性能优化

1.优化核心思路

  1. 减少不必要的渲染:避免组件因无关状态/props变化而重新渲染
  2. 降低计算开销:缓存高成本计算和函数引用
  3. 优化DOM操作:减少实际DOM的无效变更
  4. 合理加载资源:按需加载关键代码与数据

2.关键优化策略与实现

1.组件渲染控制

  • React.memo:缓存函数组件渲染结果
const MemoComponent = React.memo(Component, (prevProps, nextProps) => {
  return prevProps.id === nextProps.id; // 自定义比较函数
});
  • PureComponent:类组件自动浅比较props/state
class OptimizedComponent extends React.PureComponent {
  // 自动实现 shouldComponentUpdate 浅比较
}
  • shouldComponentUpdate:手动控制类组件更新
shouldComponentUpdate(nextProps, nextState) {
  return this.props.data.id !== nextProps.data.id; // 精准控制更新条件
}

2.高效数据管理

  • useMemo:缓存复杂计算结果
const processedData = useMemo(() => transformData(rawData), [rawData]);
  • useCallback:稳定函数引用
const handleClick = useCallback(() => {
  submitData(id);
}, [id]); // id 变化时生成新函数
  • 状态结构优化:扁平化数据,避免深层嵌套
// ❌ 避免深层嵌套
const [data, setData] = useState({ user: { profile: { name: '' } } });

// ✅ 拆分为独立状态
const [userName, setUserName] = useState('');

3.列表渲染优化

  • key属性优化:使用唯一稳定标识
{items.map(item => (
  <ListItem key={item.id} data={item} /> // 避免使用索引作为 key
))}
  • 虚拟列表技术:使用react-window实现
import { FixedSizeList as List } from 'react-window';

<List height={600} itemSize={35} itemCount={1000}>
  {({ index, style }) => <div style={style}>Row {index}</div>}
</List>

4.资源加载优化

  • 代码分割:动态加载非关键组件
const LazyComponent = React.lazy(() => import('./HeavyComponent'));

<Suspense fallback={<Spinner />}>
  <LazyComponent />
</Suspense>
  • 图片懒加载:使用Intersection Observer
const LazyImage = ({ src }) => {
    const imageRef = useRef();
    useEffect(() => {
        const observer = new IntersectionObserver((entries) => {
            if (entries[0].isIntersecting){
                imgRef.current.src = src;
                observer.unobserve(imgRef.current);
            }
        });
        observer.observe(imgRef.current);
        return () => observer.disconnect();
    }, []);
    return <img ref={imgRef} alt="Lazy loaded" />;
}

3.性能分析工具

1. React DevTools Profiler

  • 记录组件渲染耗时
  • 查看渲染原因

2. Chorme Perfomance面板

  • 分析JavaScript执行耗时
  • 识别长任务(Long Tasks)

3. Lighthouse审计

  • 综合评估性性能指标(FCP,TTI,TBT)
  • 获取优化建议

4.高级优化技术

1.并发模式优化(React18+)

  • 自动批处理:合并多个状态更新
// React 18 前:setCount + setValue 触发两次渲染
// React 18:自动合并为一次渲染
const handleClick = () => {
  setCount(c => c + 1);
  setValue(v => v + 1);
};
  • useTransition:区分紧急/非紧急更新
const [isPending, startTransition] = useTransition();

const handleSearch = (query) => {
  startTransition(() => {
    setSearchQuery(query); // 标记为非紧急更新
  });
};

2.服务端渲染优化

  • 流式SSR:分块传输HTML
// Next.js示例
export async function getServerSideProps() {
    return {
        props: { data: await fetchData() },
    };
}
  • 静态生成:预渲染静态页面
export async function getStaticProps() {
    return { props: { /***/ }, recalidate: 60 }; // ISR 增量静态再生
}

5.常见性能陷阱与方案

问题解决方案
不必要的 Context 更新拆分多个 Context,使用 useMemo 缓存 Provider 值
过度使用 useMemo仅对高开销计算使用,避免对小计算进行不必要的缓存
内存泄漏及时清理定时器、事件监听器、订阅等副作用
大状态对象更新使用 Immer 实现不可变更新,避免深拷贝性能问题

6.性能优化黄金法则

  1. 优先解决关键瓶颈:使用Profiler定位主要性能
  2. 避免过早优化:在出现可测量的性能问题后再实施优化
  3. 保持组件简单:单一职责组件更易优化
  4. 渐进增强:优先优化首屏关键路径,再处理次要内容

三、高级特性

1.错误边界

1.定义与作用

  • 错误边界是React中的一种特殊类组件,用于捕获其子组件树中发生的JavaScript错误,防止这些错误导致整个应用崩溃。通过错误边界,开发者可以优雅地处理错误,并展示降级UI以提升用户体验

2.实现方式

错误边界必须使用类组件实现,并定义以下两个生命周期方法之一(或两者):

  1. static getDerivedStateFromError(error)
  • 作用:捕获子组件抛出的错误,返回一个状态对象来更新组件状态
  • 触发时机:渲染阶段(Render Phase)
  • 返回值:必须返回一个对象用于更新state,以控制是否显示降级UI

2.componentDidCatch(error, errorInfo)

  • 作用:记录错误信息(如发送至监控平台)
  • 触发时机:提交阶段(Commit Phase)
  • 参数
    • error:抛出的错误对象
    • errorInfo:包含组件栈信息的对象(componentStack)
class ErrorBoundary extends React.Component {
    state = { hasError: false };
    static getDerivedStateFromError(error) {
        return { hasError: true }; // 更新状态以显示降级UI
    }
    
    componentDidCatch(error, errorInfo) {
        logErrorToService(error, errorInfo); // 上报错误
    }
    
    render() {
        if (this.state.hasError) {
            return <h1>Oops! Something went wrong.</h1>;
        }
        return this.props.children; // 正常渲染子组件
    }
}

3.使用场景

1.包裹高风险组件
<ErrorBoundary>
  <UnstableComponent />
</ErrorBoundary>
2.全局兜底错误处理
// 在根组件外层包裹错误边界
<ErrorBoundary>
  <App />
</ErrorBoundary>

4.错误边界的限制

可捕获的错误类型无法捕获的错误类型
子组件渲染期间的错误事件处理器中的错误(需手动 try/catch
生命周期方法中的错误异步代码(如 setTimeoutfetch
构造函数中的错误服务端渲染(SSR)的错误
子组件错误边界未处理的错误错误边界自身抛出的错误

5.最佳实践

1.避免滥用
  • 仅在关键组件或模块使用,而非整个组件
2.组合使用
  • 多层错误边界实现局部错误隔离
<ErrorBoundary>
  <Header />
  <ErrorBoundary>
    <MainContent />
  </ErrorBoundary>
  <Footer />
</ErrorBoundary>
3.try/catch互补
  • 错误边界处理渲染错误
  • try/catch处理事件处理器、异步代码错误
function MyComponent() {
  const handleClick = () => {
    try {
      // 可能抛出错误的操作
    } catch (error) {
      logError(error);
    }
  };
  return <button onClick={handleClick}>Click</button>;
}

6.高频面试题

1.函数式组件能否作为错误边界?
  • 不能。错误边界必须通过类组件的生命周期方法实现,函数式组件需包裹在类组件的错误边界中
2.错误边界可以捕获哪些阶段的错误?
  • 仅捕获渲染阶段(如render、constructor、生命周期方法)的错误,无法捕捉提交阶段(如DOM操作)或异步代码中的错误
3.如何测试错误边界?
  1. 测试中模拟子组件抛出错误
  2. 验证错误边界是否显示降级UI
  3. 检查错误是否正确上报
// 使用 Jest 和 React Testing Library
test('ErrorBoundary shows fallback UI on error', () => {
  const ErrorComponent = () => {
    throw new Error('Test error');
  };
  const { getByText } = render(
    <ErrorBoundary>
      <ErrorComponent />
    </ErrorBoundary>
  );
  expect(getByText('Oops! Something went wrong.')).toBeInTheDocument();
});
4.错误边界如何处理自身错误?
  • 错误边界自身的错误会冒泡到上一层的错误边界。若没有父级边界,则导致整个应用崩溃

2.高阶组件

1.定义

高阶组件(Higher-Order Component)是React中用于复用组件逻辑的一种高级技巧。它是一个函数,接受一个组件作为参数,并返回一个新的增强组件。HOC本身不是组件,而是一个组件工厂函数

2.HOC的核心作用

  1. 逻辑复用:抽离多个组件的公共逻辑(如数据获取,权限控制)
  2. 增强组件能力:为组件注入额外的props或扩展生命周期行为
  3. 代码解耦:将业务逻辑与UI组件分离,提升可维护性

3.HOC的实现

1.属性代理(Props Proxy)
  • 特点:HOC包裹目标组件,通过props传递数据或方法
function withLogging(wrappedComponent) {
    return class extends React.Component {
        componentDidMount() {
            console.log('Component is mounted:', WrappedComponent.name);
        }
        render() {
            // 透传所有的props到被包裹的组件
            return <WrappedComponent {...this.props} />;
        }
    }
}
// 使用
const EnhancedComponent = withLogging(MyComponent);
2.反向继承(Inheritance Inversion)
  • 特点:通过继承目标组件,控制其渲染流程(较少使用)
function withEnhancement(WrappedComponent) {
    return class extends WrappedComponent {
        render() {
            // 可修改原组件的渲染结果
            const elements = supoer.render();
            return React.cloneElement(elements, { newPorps: 'value' });
        }
    }
}
// 使用
const EnhancedComponent = withEnhancement(MyComponent);

4.HOC应用场景

场景示例 HOC功能
权限控制withAuth检查用户权限,未登录则跳转
数据请求withFetchData统一处理 API 请求与状态管理
UI 功能增强withHover/withClickOutside添加悬停或点击外部关闭功能
状态管理Redux connect连接组件与 Redux Store

5.注意事项

1.不要修改原始组件
  • 使用组合而非继承,避免直接修改原始组件的原型
2.透传无关props
  • 确保HOC传递所有与自身无关的props到被包裹组件
render() {
  const { extraProp, ...restProps } = this.props;
  return <WrappedComponent {...restProps} />;
}
3.处理静态方法
  • 使用hoist-non-react-statics复制静态方法到新组件
npm install hoist-non-react-statics
import hoistNonReactStatic from 'hoist-non-react-statics';

function withEnhancement(WrappedComponent) {
  class EnhancedComponent extends React.Component { /* ... */ }
  hoistNonReactStatic(EnhancedComponent, WrappedComponent);
  return EnhancedComponent;
}
4.Ref传递问题
  • 使用React.forwardRef转发Ref到被包裹组件
function withRefForwarding(WrappedComponent) {
    class EnhancedComponent extends React.Componnet {
        render() {
            const { forwardedRef, ...resetProps } = this.props;
            return <WrappedComponent ref={forwardedRef} {...resetProps} />;
        }
    }
    return React.forwardRef((props, ref) => (
        <EnhancedComponent forwardedRef={ref} {...props} />;
    ))
}

6.HOC和Hooks对比

维度HOCHooks
适用组件类型类组件/函数组件仅函数组件
逻辑复用方式包裹组件,形成组件树层级在组件内部直接调用 Hook 函数
代码组织可能引入多层嵌套,可读性下降扁平化逻辑,易于追踪数据流
性能影响可能因层级嵌套导致不必要的渲染依赖数组精准控制更新
学习曲线需理解高阶函数和组件组合需掌握闭包和依赖数组规则

7.高频面试题

1.HOC的优缺点
  • 优点

    1. 跨组件复用逻辑,减少代码冗余
    2. 适用于类组件,兼顾旧项目
  • 缺点

    1. 组件层级嵌套过深,调试困难
    2. 需处理静态方法和Ref传递
    3. 可能引发props命名冲突
2.如何避免HOC的props命名冲突?
  • 使用命名空间或特点前缀
<WrappedComponent hocData={data} {...restProps} />
  • 在HOC中过滤专属props
render() {
  const { hocProp, ...passThroughProps } = this.props;
  return <WrappedComponent {...passThroughProps} />;
}
3.HOC在React生态的典型应用有哪些?
  • Reduxconnect(mapStateToProps, mapDispatchToProps)(Component)
  • React RouterwithRouter(Component)
  • Material-UIwhithStyle(styles)(Component)
4.HOC是否会导致性能问题?如何优化?
  • 问题:每次父组件渲染时创建新的HOC实例,导致子组件重新挂载
  • 优化:在组件外部定义HOC,而非在render方法中动态创建
// ❌ 错误:在 render 中创建 HOC
function Parent() {
  const HocComponent = withLogging(Child);
  return <HocComponent />;
}

// ✅ 正确:在外部定义 HOC
const EnhancedChild = withLogging(Child);
function Parent() {
  return <EnhancedChild />;
}

3.服务端渲染方案

1.核心优势

  1. SEO友好:爬虫直接解析服务端返回的HTML,提升搜索引擎排名
  2. 首屏性能优化:减少客户端渲染的白屏时间,提升用户体验
  3. 兼容性保障:确保低端设备或禁用JavaScript的环境下基础内容可访问

2.主流SSR方案对比

方案特点适用场景
Next.js开箱即用、约定式路由、支持 SSG/SSR/ISR全栈应用、SEO 要求高的项目
Gatsby基于 GraphQL 的静态站点生成(SSG)、插件生态丰富内容型网站(博客、文档)
自定义 SSR灵活控制渲染流程、深度定制化复杂企业级应用、特殊架构需求
React Server Components混合渲染(服务端/客户端组件结合)、减少客户端 JS 体积动态内容与静态内容混合的场景

3.Next.js实现SSR深度解析

1.页面级SSR

使用getServerSideProps在每次请求时生成页面

export async function getServerSideProps(context) {
    const data = await fetchData(context.data.id);
    return { props: { data } }; // 传递给页面组件
}

function Page({ data }) {
    return <div>{data}</div>;
}
2.增量静态再生(ISR)

结合静态生成与按需更新

export async function getStaticProps() {
  const data = await fetchData();
  return { 
    props: { data },
    revalidate: 60 // 最多每60秒重新生成一次
  };
}
3.客户端水合(Hydration)

自动处理服务端与客户端渲染链接

// 服务端生成HTML
import { renderToString } from 'react-dom/server';
const html = renderToString(<App />);

// 客户端激活
import { hydrateRoot } from 'react-dom/client';
hydrateRoot(document.getElementById('root'), <App />);

4.自定义SSR实现步骤

1.项目结构配置
# 分离客户端和服务端入口
- src/
  - client/
    - index.js # 客户端入口
  - server/
    - index.js # 服务端入口
2.Webpack多环境配置
// webpack.client.config.js
module.export = {
    entry: './src/client/index.js',
    output: {
        filename: 'client-bundle.js',
        path: path.resolve(__dirname, 'dist'),
    }
};
// webpack.server.config.js
module.exports = {
    entry: './src/server/index.js',
    target: 'node',
    output: {
        filename: 'server-boudle.js',
        path: path.resolve(__dirname, 'dist'),
    }
};
3.服务端渲染核心逻辑
import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from '../shared/App';

const app = express();
app.get('*', (req, res) => {
  const html = renderToString(<App />);
  res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>SSR App</title>
      </head>
      <body>
        <div id="root">${html}</div>
        <script src="/client-bundle.js"></script>
      </body>
    </html>
  `);
});
4.数据预取和状态同步
// 服务端数据获取
const fetchData = async () => {
  const res = await fetch('https://api.example.com/data');
  return res.json();
};

// 客户端同步状态
window.__INITIAL_STATE__ = serverData;

// 客户端入口
const initialState = window.__INITIAL_STATE__;
const store = configureStore(initialState);
hydrateRoot(document.getElementById('root'), <App store={store} />);

5.性能优化策略

1.缓存机制
// 使用 LRU 缓存渲染结果
const microCache = new LRU({
  max: 100,
  maxAge: 1000 * 60 // 1分钟缓存
});

app.get('*', (req, res) => {
  const cachedHtml = microCache.get(req.url);
  if (cachedHtml) return res.send(cachedHtml);
  
  const html = renderToString(<App />);
  microCache.set(req.url, html);
  res.send(html);
});
2.流式渲染
import { renderToPipeableStream } from 'react-dom/server';

app.use((req, res) => {
  const stream = renderToPipeableStream(<App />, {
    onShellReady() {
      res.setHeader('Content-type', 'text/html');
      stream.pipe(res);
    }
  });
});
3.代码分割
// 使用 @loadable/component
import loadable from '@loadable/component';
const LazyComponent = loadable(() => import('./HeavyComponent'));

// 服务端处理
import { ChunkExtractor } from '@loadable/server';
const extractor = new ChunkExtractor({ statsFile: 'dist/loadable-stats.json' });
const jsx = extractor.collectChunks(<App />);
const html = renderToString(jsx);
const scriptTags = extractor.getScriptTags(); // 插入客户端脚本

6.常见问题与解决方案

问题解决方案
客户端-服务端状态不一致使用 Redux 或 Context API 同步初始化状态
window 未定义错误通过条件判断限制客户端专用代码执行:if (typeof window !== 'undefined')
样式闪烁(FOUC)​使用 isomorphic-style-loader 提取服务端样式到 <style> 标签
内存泄漏监控服务器内存使用,使用 --max-old-space-size 调整 Node.js 内存限制

4.React18+新特性

1.并发渲染

React 18的核心更新是引入并发渲染能力,允许React在渲染过程中中断并优先处理更高优先级的任务(比如用户输入),从而提升响应速度。

关键机制
  • 时间切片:将渲染任务拆分成小块,避免长时间阻塞主线程
  • 优先级调度:用户交互(如点击)优先于数据更新(如API响应)
相关API
  • startTransition:标记非紧急更新,可被高优先级任务打断
import { startTransition } from 'react';

const handleSearch = (query) => {
  startTransition(() => {
    setSearchQuery(query); // 非紧急更新
  });
};
  • useTransition:跟踪过渡状态,显示加载指示
const [isPending, startTransition] = useTransition();

return (
  <button onClick={() => startTransition(handleClick)}>
    {isPending ? '加载中...' : '提交'}
  </button>
);

2.自动批处理

React 18默认将多次状态更新合并为单次渲染,减少不必要的重复渲染

更新场景对比
场景React 17 及之前React 18
事件处理器中的更新批量处理批量处理
setTimeout/Promise 中的更新不批量处理批量处理
强制同步更新
import { flushSync } from 'react-dom';

flushSync(() => {
  setCount(c => c + 1); // 立即同步渲染
});

3.流式服务端渲染

通过分块传输HTML选择性水合,显著提升服务端渲染性能

核心改进
  • 流式传输:服务器逐步发送HTML到客户端,缩短首屏时间
  • 并行水合:客户端在接收HTML时逐步激活交互功能,无需等待全部内容加载
import { renderToPipeableStream } from 'react-dom/server';

app.get('/', (req, res) => {
  const stream = renderToPipeableStream(<App />, {
    onShellReady() {
      res.setHeader('Content-type', 'text/html');
      stream.pipe(res);
    },
    bootstrapScripts: ['/main.js'] // 客户端脚本
  });
});

4.新根API与严格模式增强

1.新根API createRoot

替换原有的ReactDOM.render,启用并发功能

// React 17
ReactDOM.render(<App />, document.getElementById('root'));

// React 18
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
2.严格模式
  • 模拟卸载-挂载:开发环境下组件挂载后立即卸载再重新挂载,检测副作用清理问题
  • 重复渲染检测:故意双调用组件函数和Hook,暴露潜在副作用

5.新Hook与API

1.useId
  • 生成唯一ID,解决服务端与客户端ID不一致的问题
const id = useId(); // 生成如 :r1: 的稳定 ID
return <label htmlFor={id}>用户名</label>;
2.useDeferredValue
  • 延迟更新非关键UI,保持高优先级交互流程
const deferredQuery = useDeferredValue(query);
return <SearchResults query={deferredQuery} />;
3.useSyncExternalStore
  • 简化外部状态库(如Redux)集成,避免并发渲染下的撕裂问题
const state = useSyncExternalStore(store.subscribe, store.getState);

6.改进的Suspense功能

  • 支持在SSR中与流式渲染结合,优化体验
<Suspense fallback={<Spinner />}>
  <Comments /> {/* 异步加载的组件 */}
</Suspense>

以上是React面试题的高阶篇内容,如有错误欢迎评论区指正。