跳转到内容

React 部分常用API记录

本文档用于记录React内置的部分特定场景下的常用API,包括使用场景以及使用例子。

React PortalReact提供的一种将子节点渲染到父组件DOM层次结构之外的DOM节点中的方法,同时保持其在React组件树中的位置。

使用场景:

  1. 模态框(Modals):模态框通常需要覆盖整个页面,并且不受父容器样式(如overflow: hidden或z-index)的影响。使用Portal可以将模态框渲染到body的直接子元素,避免被父组件剪裁。

  2. 工具提示(Tooltips):当工具提示需要突破父容器的溢出隐藏或定位上下文时,可以使用Portal将其渲染到更高层级的DOM节点上。

  3. 弹出菜单(Popup Menus):类似工具提示,弹出菜单可能需要避免被父容器的样式所影响,确保正确显示。

  4. 通知(Notifications):全局的通知消息通常需要显示在页面的顶部,不受其他组件布局的影响。

  5. 悬停卡(Hover Cards):当鼠标悬停在某个元素上时显示的信息卡,有时需要突破父元素的布局限制。

  6. 对话框(Dialogs):与模态框类似,对话框通常需要覆盖整个页面,并且应该位于其他内容之上。

  7. 加载遮罩(Loading Overlays):全屏的加载指示器,需要覆盖整个页面或某个区域,并且位于所有内容之上。

使用例子(弹出框):

const Modal = ({ children, isOpen, onClose }) => {
const [modalRoot] = useState(() => document.getElementById('modal-root'));
const [el] = useState(() => document.createElement('div'));
useEffect(() => {
if (isOpen) {
modalRoot.appendChild(el);
document.body.style.overflow = 'hidden'; // 防止背景滚动
return () => {
modalRoot.removeChild(el);
document.body.style.overflow = 'unset';
};
}
}, [isOpen, el, modalRoot]);
if (!isOpen) return null;
return ReactDOM.createPortal(
<div className="modal-backdrop" onClick={onClose}>
<div className="modal" onClick={e => e.stopPropagation()}>
{children}
</div>
</div>, el);
};

文档:createPortal – React 中文文档

React.lazy用于懒加载组件,传入一个load函数,返回一个懒加载组件:

import { lazy } from 'react';
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

使用Suspense组件可以在懒加载的过程中插入一些中间态UI,用法如下:

<Suspense fallback={<Loading />}>
<MarkdownPreview />
</Suspense>

其中fallback属性传入的就是中间态的UI(如Loading组件)。

useTransitionReact 18引入的一个并发特性(Concurrent Feature),它允许你将一个状态更新标记为非阻塞的、可中断的过渡更新(Transition),从而让高优先级的更新(如用户输入、点击)能够打断它,保持用户界面的流畅和响应。

在没有useTransition之前,所有的状态更新都是“紧急”的。当一个耗时的状态更新(如根据用户输入过滤一个超长列表)发生时,它会阻塞线程,导致用户输入无法立即得到响应,输入框会感觉“卡顿”。

经典场景:一个搜索输入框 + 一个搜索结果列表:

用户在输入框中快速输入 “hello”。每次按键都会触发一个状态更新setInputValue,并随之触发一个昂贵的计算来过滤列表setSearchResults。由于setSearchResults计算量很大,它会阻塞UI线程。导致用户输入的下一个字符无法立即渲染,输入框看起来停止了响应,直到过滤计算完成。

使用useTransition后,你可以将过滤列表的更新标记为一个“过渡更新”。这样,setInputValue(紧急更新)会立即执行,让输入框内容变化;而setSearchResults(过渡更新)可以被中断或延迟,不会阻塞输入框的渲染。用户体验会变得非常流畅。

代码示例如下:

// 假设有两个状态:输入值 和 搜索结果
const [inputValue, setInputValue] = useState('');
const [searchResults, setSearchResults] = useState([]);
const [isPending, startTransition] = useTransition();
const handleInputChange = (e) => {
const value = e.target.value;
// 1. 紧急更新:立即更新输入框的值
setInputValue(value);
// 2. 过渡更新:将昂贵的列表更新包裹起来
startTransition(() => {
// 在这个回调函数内部的所有状态更新都会被标记为过渡更新
const filteredResults = hugeList.filter(item =>
item.name.includes(value)
);
setSearchResults(filteredResults);
});
};

文档:useTransition – React 中文文档