在React组件中使用setTimeouts

在React组件中使用setTimeouts

setTimeout方法在一定时间后执行一个函数。这对于创建基于时间的效果非常有用,例如在加载新数据之前显示加载旋转图标几秒钟,或者在几秒钟后隐藏成功消息。然而,在React中使用传统的setTimeout可能会具有挑战性。为了保持React应用的效率,我们需要使用useEffect钩子来跟踪和清除这些超时。
让我们了解如何在React组件中处理setTimeouts:

在React组件中使用setTimeouts:

我们可以像在JavaScript中处理一样,在React组件中使用setTimeout方法。在React组件中,setTimeout方法遵循与JavaScript相同的原则。然而,我们应该注意一些注意事项。

要设置超时,我们需要在我们的React组件中使用useEffect钩子。直接在组件内部设置超时可能是一种不恰当的方法,因为每次组件重新渲染时,React都会重新生成setTimeout方法,导致新的超时。我们的应用程序将因为这些超时而迅速变得臃肿并且不可靠。由于多个状态更改,需要进行其他重新渲染。因此,我们将使用useEffect钩子为React组件创建timeout。当组件重新渲染时,useEffect钩子执行副作用。它接受一组依赖项数组以及用于处理副作用的回调函数。这些依赖项是状态变量,当它们变化时,引起这些副作用。我们将把timeout包含在useEffect钩子中以进行管理。

让我们了解在React中实现setTimeout方法的各种方法。

创建React应用:

步骤1: 创建一个项目目录,打开终端,使用以下命令创建一个名为 spinner-gfg 的React应用:

npx create-react-app spinnner-gfg
JavaScript

步骤2: 在创建 spinner-gfg 应用程序之后,通过输入以下命令切换到新文件夹 spinner-gfg:

cd spinner-gfg
JavaScript

项目结构: 现在,我们将修改文件夹并保留此示例所需的文件。现在,请确保您的文件结构如下:

在React组件中使用setTimeouts

示例1: 我们将使用setTimeout方法,在渲染一些数据之前展示一个加载动画5秒钟。

方法:创建加载动画应用程序:

  • 我们将使用useEffect钩子和一个空的依赖数组,在组件挂载后创建一个定时器。
  • data 状态变量存储内容, setData 函数更新内容的值。
  • 当定时器结束后,数据将会显示, isLoading 状态将被设为false。

index.html: 将以下代码写入你的index.html文件,该文件位于项目目录的public文件夹中:

<!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>Timeouts in React</title> 
</head> 
  
<body> 
    <div id="root"></div> 
</body> 
  
</html>
JavaScript

App.js:

import { useState, useEffect } from 'react'; 
import './App.css'
  
const App = () => { 
    const [isLoading, setIsLoading] = useState(true); 
    const [data, setData] = useState(null); 
  
    useEffect(() => { 
  
        // Creating a timeout within the useEffect hook 
        setTimeout(() => { 
            setData("Welcome to gfg!"); 
            setIsLoading(false); 
        }, 5000); 
    }, []); 
  
    if (isLoading) { 
        return <div className='spinner'> 
            Loading.....</div>; 
    } 
  
    return ( 
        <div className='container'> 
            {data} 
        </div> 
    ); 
} 
export default App;
JavaScript

App.css 将以下代码添加到 App.css 中以为旋转加载应用程序添加样式。

.spinner, 
.container { 
    margin: 1rem; 
    display: flex; 
    flex-direction: column; 
    align-items: center; 
    justify-content: center; 
    font-size: 2rem; 
} 
  
.container { 
    border: 2px solid darkGreen; 
}
JavaScript

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> 
);
JavaScript

运行应用程序的步骤: 使用下面的命令运行应用程序:

npm start
JavaScript

输出: 默认情况下,React项目将在端口3000上运行。您可以在浏览器中通过localhost:3000访问它。

在React组件中使用setTimeouts

解释: useEffect钩子函数调用一个空数组依赖,这意味着它只会在组件挂载时运行一次,并确保定时器只设置一次。isLoading状态变量控制组件的渲染。如果isLoading为true,组件将渲染一个加载旋转器。如果isLoading为false,组件将显示数据。我们可以使用setTimeout方法在useEffect钩子函数中加载数据时显示加载旋转器。

让我们了解如何在重新渲染时创建超时。

清除setTimeout:

在useEffect钩子函数中,我们可以在组件的状态改变时创建超时。然而,每次状态改变时都会生成新的超时,这可能会导致性能问题。必须清除不再需要的超时以防止潜在的内存泄漏。setTimeout方法创建一个定时器,并排队一个回调函数,在指定的时间过去后执行。如果定时器到期并且执行回调函数,超时完成。然而,如果使用相同的变量设置新的超时,上一个超时将被取消,新的超时将被启动。如果超时不在不再需要时被取消,即使设置超时的组件已经卸载,回调函数仍然可能被执行。这可能会导致资源浪费和潜在的错误,特别是如果回调函数具有不再相关的副作用。

为了避免这种情况,我们可以在创建新的超时之前清除上一个超时,使用clearTimeout方法。这对于预防我们的应用中的内存泄漏很重要,因为在组件卸载时,如果不清除setTimeout的回调函数仍然可能执行。

clearTimeout方法:

  • clearTimeout取消setTimeout方法生成的超时。
  • setTimeout方法返回一个timeoutId,该timeoutId传递给clearTimeout。
  • timeoutId标识setTimeout函数生成的特定定时器。

语法:

clearTimeout(timeoutID)
JavaScript

这是一个示例,展示了在重新渲染时如何在React中清除setTimeouts并创建定时器:

示例2: 显示在指定时间后消失的警告消息。

步骤:创建警告消息组件: 我们将显示一个警告消息5秒钟,然后使用setTimeout方法隐藏它。

  • 我们将使用 useEffect 钩子在 showWarning 状态为true时设置计时器,并在组件卸载或showWarning状态改变时取消计时器。
  • useEffect钩子在组件渲染时调用,意味着每次组件挂载且showWarning状态为true时都会设置一个计时器。
  • 为了在组件卸载或showWarning状态改变时取消计时器,我们需要一种存储 计时器ID 并从useEffect钩子的清理函数中访问它的方法。这就是 useRef 钩子的用武之地。
  • useRef钩子允许我们创建一个可变的 ref ,在重新渲染时保持不变,可以用于存储计时器ID。当组件挂载时,计时器ID存储在timerId ref的 current 属性中。
  • 当组件卸载或showWarning状态改变时,useEffect钩子的清理函数被调用,并使用存储在timerId ref 中的计时器ID取消计时器。

App.js:

import { useState, useEffect, useRef } from 'react'; 
import './App.css'
  
const App = () => { 
    const [showWarning, setShowWarning] = useState(false); 
    const timerId = useRef(null); 
  
    useEffect(() => { 
        if (showWarning) { 
  
            //Creating a timeout 
            timerId.current = setTimeout(() => { 
                setShowWarning(false); 
            }, 5000); 
        } 
  
        return () => { 
            //Clearing a timeout 
            clearTimeout(timerId.current); 
        }; 
    }, [showWarning]); 
  
    function handleClick() { 
        setShowWarning(true); 
    } 
  
    return ( 
        <div className='warn'> 
            {showWarning && <div className='warningMsg'> 
                This is a Warning ⚠️!</div>} 
            <button className='btn' onClick={handleClick}> 
                Show Warning</button> 
        </div> 
    ); 
} 
export default App;
JavaScript

App.css:App.css 中添加以下代码以给消息应用程序添加样式。

.warn { 
    margin: 1rem; 
    display: flex; 
    flex-direction: column; 
    align-items: center; 
    justify-content: center; 
    font-size: 1rem; 
} 
  
.warningMsg { 
    border: 2px solid orangered; 
    background-color: rgb(210, 153, 124); 
} 
  
.btn { 
    border: 2px solid darkGreen; 
    border-radius: 10px; 
    margin: 1rem; 
    cursor: pointer; 
}
JavaScript

运行应用程序的步骤:

使用以下命令运行应用程序:

npm start
JavaScript

输出:

在React组件中使用setTimeouts

解释:

组件挂载时,使用一个空的showWarning数组调用useEffect钩子,这意味着效果只会运行一次。if (showWarning)条件为false,所以计时器不会被设置。当用户点击Show Warning按钮时,会调用handleClick函数,该函数将showWarning状态设置为true。这会导致组件重新渲染并再次调用useEffect钩子。这次,if (showWarning)条件为true,所以使用setTimeout设置计时器,在5秒后隐藏警告消息。

如果用户在5秒内再次点击Show Warning按钮,则showWarning状态将再次被设置为true,导致组件重新渲染并再次调用useEffect钩子。这将取消上一个计时器,并设置一个新计时器,在5秒后隐藏警告消息。

如果用户在5秒内离开页面,则组件将被卸载,并调用useEffect钩子的清理函数。清理函数使用保存在timerId引用中的计时器ID来调用clearTimeout,取消计时器并防止回调函数被执行。

这样我们就可以在5秒后自动隐藏警告消息,而不会产生不必要的副作用。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册