ReactJS useTransition Hook
在构建交互式用户界面时,性能是一个关键的考虑因素。改进React应用程序性能的一种方法是使用useTransition挂钩。该挂钩允许您将某些状态更新指定为不重要,通过将与动画相关的状态更改与组件中的其他状态更改分开。
在本文中,我们将探讨useTransition挂钩的基础知识以及如何使用它来提高React应用程序的性能。
useTransition挂钩 使我们能够指定哪些状态更改是关键或紧急的,哪些不是。
在React中,所有状态更改都被视为必要的。可能会有某些快速的UI更新,比如从下拉菜单中选择一个值,这些更新应该优先于其他更新,比如列表过滤,这可能会减慢它们的执行速度。useTransition挂钩允许我们指定哪些状态更改应该以较低的优先级运行,以提高应用程序的性能。
语法:
const [isPending, startTransition] = useTransition()
useTransition hook不接受任何参数,并返回两个值:
- isPending: 一个布尔值,指示过渡当前是否正在进行中。
- startTransition: 一个可以用于开始过渡的函数。
让我们看一些实际使用useTransition的示例。
创建React应用:
步骤1: 创建一个项目目录,转到终端,并使用以下命令创建一个名为usetransition-example的React应用:
npx create-react-app usetransition-example
步骤2: 创建 usetransition-example 应用后,通过键入以下命令切换到新文件夹 usetransition-example:
cd usetransition-example
项目结构:
我们会修改文件夹并保留我们在这个示例中需要的文件。现在,请确保您的文件结构如下所示:
示例1: 我们将使用 useTransition 钩子来更改文本的可见性以及更改文本本身。
index.html: 将以下代码包含在位于项目目录的 public 文件夹中的 index.html 文件中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1" />
<meta name="theme-color"
content="#000000" />
<meta name="description"
content="Web site created using create-react-app" />
<title>React useTransition hook</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
App.js:
- 在这个示例中,组件包含两个按钮,第一个按钮将在 true 和 false 之间切换 isVisible 状态变量,第二个按钮将改变文本。
- 当点击“切换可见性”按钮时,isVisible 状态变量将切换,同时调用 startTransition 函数来开始过渡,并使用 isPending 来给元素应用一个不透明度样式,该样式根据过渡的状态而变化,即是进行中或者不在进行中。
import { useState, useTransition } from 'react';
import './App.css';
const App = () => {
const [isVisible, setIsVisible] = useState(false);
const [text, setText] = useState("Hello Geek");
const [isPending, startTransition] = useTransition();
const handleClick = () => {
setIsVisible(!isVisible);
startTransition();
};
return (
<div className='container'>
<div className="btn-container">
<button className='btn' onClick={handleClick}>
Toggle Visibility</button>
<button className='btn' onClick={() =>
setText("Welcome to geeksforgeeks")}>
Change Text</button>
</div>
<div style={isPending ?
{ opacity: 0 } :
{ opacity: isVisible ? 1 : 0 }}>
<h1>{text}</h1>
</div>
</div>
);
}
export default App;
App.css: 将以下代码添加到App.css中以样式化应用程序。
.container {
margin: 1rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 2rem;
}
.btn-container {
display: flex;
flex-direction: row;
}
.btn {
padding: 20px;
margin: 10px;
cursor: pointer;
border-radius: 15px;
font-weight: bold;
}
h1 {
border: 4px solid darkGreen;
border-radius: 20px;
padding: 20px;
}
index.js: 将以下代码添加到index.js文件中。
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
运行应用程序的步骤: 使用以下命令运行应用程序:
npm start
输出: 默认情况下,React项目会在端口3000上运行。您可以在浏览器上通过 localhost:3000 访问它。
示例2:使用useTransition hook更新列表项。
startTransition将包含 setList 方法。这表示更新setList状态的优先级较低,而更新输入字段的优先级较高。这确保我们可以在代码运行缓慢时仍然与应用程序进行交互。
App.js:
import React, { useState, useTransition } from "react";
const defaultList = [1, 2, 3, 4, 5];
const App=()=> {
const [name, setName] = useState("");
const [list, setList] = useState(defaultList);
const [isPending, startTransition] = useTransition();
const sizeOfList = 10000;
const handleChange=(e)=> {
const { value } = e.target;
setName(value);
startTransition(() => {
const data = [];
for (let i = 0; i < sizeOfList; i++) {
data[i] = value;
}
setList(data);
});
}
return (
<>
<input type="text" value={name} onChange={handleChange} />
{isPending ? (
<div>Loading...</div>
) : (
list.map((list) => {
return <div>List Item: {list}</div>;
})
)}
</>
);
}
export default App;
运行应用程序的步骤: 使用以下命令运行应用程序:
npm start
输出:
我们输入的字段在我们输入时即时更新,而该列表在加载完成后渲染。