最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React Hooks與setInterval的踩坑問(wèn)題小結(jié)

 更新時(shí)間:2022年04月27日 14:35:19   作者:田先森  
本文主要介紹了React Hooks與setInterval的踩坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、需求

我們希望有一個(gè)每一秒自動(dòng)+1的定時(shí)器

function Counter() {
  let [count, setCount] = useState(0);
  useEffect(() => {
    let id = setInterval(() => {
      setCount(count + 1);
    }, 1000);
    return () => clearInterval(id);
  }, [count]);
  return <h1>{count}</h1>;
}

這種寫法你會(huì)發(fā)現(xiàn)頁(yè)面效果確實(shí)能出來(lái),但是性能很差。每當(dāng) count 更改了, useEffect 就會(huì)渲染一次,定時(shí)器也會(huì)不停的被新增與移除。過(guò)程如下:

//第一次
function Counter() {
//... 
useEffect(() => {
    let id = setInterval(() => {
      setCount(0 + 1);
    }, 1000);
    return () => clearInterval(id);
  }, [0]);
//...
}
//第二次
function Counter() {
//... 
useEffect(() => {
    let id = setInterval(() => {
      setCount(1 + 1);
    }, 1000);
    return () => clearInterval(id);
  }, [1]);
//...
//第N次
}

現(xiàn)在我們的需求是在實(shí)現(xiàn)功能的基礎(chǔ)上,還要使得定時(shí)器只監(jiān)聽(tīng)一次,保障它的性能很高。

二、解決方案

1、函數(shù)式更新

useState 中的set方法可接收函數(shù),該函數(shù)將接收先前的 state ,并返回一個(gè)更新后的值。這樣定時(shí)器每次拿到的是最新的值。

function Counter() {
let [count, setCount] = useState(0);
useEffect(() => {
    let id = setInterval(() => {
      setCount(v => {
        return v + 1;
      });
    }, 1000);
    return () => clearInterval(id);
  }, []);
return <h1>{count}</h1>;
}

2、使用useRef

useRef 返回一個(gè)可變的 ref 對(duì)象,返回的 ref 對(duì)象在組件的整個(gè)生命周期內(nèi)保持不變。

將定時(shí)器函數(shù)提取出來(lái),每次定時(shí)器觸發(fā)時(shí),都能取到最新到 count .

function Counter() {
  let [count, setCount] = useState(0);
  const myRef = useRef(null);
  myRef.current = () => {
    setCount(count + 1);
  };
  useEffect(() => {
    let id = setInterval(() => {
      myRef.current();
    }, 1000);
    return () => clearInterval(id);
  }, []);
  return <h1>{count}</h1>;
}

思考:為什么不直接像下面這個(gè)例子,將setInterval寫成 setInterval(myRef.current, 1000)這樣呢?為什么要通過(guò)一個(gè)函數(shù)返回?

//這個(gè)例子是錯(cuò)誤的
function Counter() {
  let [count, setCount] = useState(0);
  const myRef = useRef(null);
  myRef.current = () => {
    setCount(count + 1);
  };
  useEffect(() => {
    let id = setInterval(myRef.current, 1000);
    return () => clearInterval(id);
  }, []);
 return <h1>{count}</h1>;
}

定時(shí)器的第一個(gè)參數(shù)為 interval 變量,如果直接將myRef.current直接賦值給 interval 變量,那么之后的myRef.current的值改變之后,在這里依舊取到的是改變之前的值,因?yàn)?strong>ref的改變不會(huì)引起組件的重新渲染。

3、用useReducer

將 count 變量存入 reducer 中,使用 useReducer 更新 count

function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return state + 1;
    default:
      throw new Error();
  }
}
?
function Counter() {
  const [state, dispatch] = useReducer(reducer, 0);
  useEffect(() => {
    setInterval(() => {
      dispatch({ type: "increment" });
    }, 1000);
  }, []);
  return <h1>{state}</h1>;
}

4、自定義的hooks

自定義hook:useInterval

import React, { useState, useEffect, useRef } from 'react';
 
function useInterval(callback, delay) {
  const savedCallback = useRef();
 
  // 保存新回調(diào)
  useEffect(() => {
    savedCallback.current = callback;
  });
 
  // 建立 interval
  useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
}

使用useInterval

function Counter() {
  let [count, setCount] = useState(0);
 
  useInterval(() => {
    // 你自己的代碼
    setCount(count + 1);
  }, 1000);
 
  return <h1>{count}</h1>;
}

useInterval這個(gè)api的設(shè)計(jì)是非常巧妙的。

  • 首先useIntervalsetInterval接收的參數(shù)是一樣的,這就降低了我們的學(xué)習(xí)成本

  • 其次,useInterval的delay參數(shù)是可以動(dòng)態(tài)調(diào)整的,而setInterval的delay參數(shù)是沒(méi)有辦法動(dòng)態(tài)調(diào)整的

    • 當(dāng) useInterval Hook 接收到不同 delay,它會(huì)重設(shè) interval。
    • 聲明一個(gè)帶有動(dòng)態(tài)調(diào)整 delay 的 interval,來(lái)替代寫 添加和清除* interval 的代碼 —— useInterval Hook 幫我們做到了**。
    • 如果想要暫時(shí)暫停 interval ,那么可以像下面這個(gè)例子一樣
  const [delay, setDelay] = useState(1000);
  const [isRunning, setIsRunning] = useState(true);
 
  useInterval(() => {
    setCount(count + 1);
  }, isRunning ? delay : null);
  • useInterval的delay也可以受控于另外一個(gè)useInterval
function Counter() {
  const [delay, setDelay] = useState(1000);
  const [count, setCount] = useState(0);
 
  // 增加計(jì)數(shù)器
  useInterval(() => {
    setCount(count + 1);
  }, delay);
 
  // 每秒加速
  useInterval(() => {
    if (delay > 10) {
      setDelay(delay / 2);
    }
  }, 1000);
 
  function handleReset() {
    setDelay(1000);
  }
 
  return (
    <>
      <h1>Counter: {count}</h1>
      <h4>Delay: {delay}</h4>
      <button onClick={handleReset}>
        Reset delay
      </button>
    </>
  );
}

到此這篇關(guān)于React Hooks與setInterval的踩坑問(wèn)題小結(jié)的文章就介紹到這了,更多相關(guān)React Hooks與setInterval內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React中使用dnd-kit實(shí)現(xiàn)拖曳排序功能

    React中使用dnd-kit實(shí)現(xiàn)拖曳排序功能

    在這篇文章中,我將帶著大家一起探究React中使用dnd-kit實(shí)現(xiàn)拖曳排序功能,由于前陣子需要在開(kāi)發(fā) Picals 的時(shí)候,需要實(shí)現(xiàn)一些拖動(dòng)排序的功能,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2024-06-06
  • 詳解React中錯(cuò)誤邊界的原理實(shí)現(xiàn)與應(yīng)用

    詳解React中錯(cuò)誤邊界的原理實(shí)現(xiàn)與應(yīng)用

    在React中,錯(cuò)誤邊界是一種特殊的組件,用于捕獲其子組件樹中發(fā)生的JavaScript錯(cuò)誤,并防止這些錯(cuò)誤冒泡至更高層,導(dǎo)致整個(gè)應(yīng)用崩潰,下面我們就來(lái)看看它的具體應(yīng)用吧
    2024-03-03
  • ReactNative點(diǎn)擊事件.bind(this)操作分析

    ReactNative點(diǎn)擊事件.bind(this)操作分析

    這篇文章主要為大家介紹了ReactNative點(diǎn)擊事件.bind(this)操作分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • React Ref Callback使用場(chǎng)景最佳實(shí)踐詳解

    React Ref Callback使用場(chǎng)景最佳實(shí)踐詳解

    這篇文章主要為大家介紹了React Ref Callback使用場(chǎng)景最佳實(shí)踐詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 關(guān)于react中useCallback的用法

    關(guān)于react中useCallback的用法

    這篇文章主要介紹了關(guān)于react中useCallback的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • react路由守衛(wèi)的實(shí)現(xiàn)(路由攔截)

    react路由守衛(wèi)的實(shí)現(xiàn)(路由攔截)

    react不同于vue,通過(guò)在路由里設(shè)置meta元字符實(shí)現(xiàn)路由攔截。本文就詳細(xì)的介紹一下,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 詳解React項(xiàng)目中碰到的IE問(wèn)題

    詳解React項(xiàng)目中碰到的IE問(wèn)題

    這篇文章主要介紹了React項(xiàng)目中碰到的IE問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 基于React實(shí)現(xiàn)虛擬滾動(dòng)的方案詳解

    基于React實(shí)現(xiàn)虛擬滾動(dòng)的方案詳解

    這篇文章將以固定高度和非固定高度兩種場(chǎng)景展開(kāi)React中虛擬滾動(dòng)的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • React實(shí)現(xiàn)歌詞滾動(dòng)效果(跟隨音樂(lè)播放時(shí)間滾動(dòng))

    React實(shí)現(xiàn)歌詞滾動(dòng)效果(跟隨音樂(lè)播放時(shí)間滾動(dòng))

    這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)歌詞滾動(dòng)效果(跟隨音樂(lè)播放使勁按滾動(dòng)),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2024-02-02
  • React模仿網(wǎng)易云音樂(lè)實(shí)現(xiàn)一個(gè)音樂(lè)項(xiàng)目詳解流程

    React模仿網(wǎng)易云音樂(lè)實(shí)現(xiàn)一個(gè)音樂(lè)項(xiàng)目詳解流程

    這篇文章主要介紹了React模仿網(wǎng)易云音樂(lè)實(shí)現(xiàn)一個(gè)音樂(lè)項(xiàng)目的詳細(xì)流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08

最新評(píng)論

武城县| 凤山市| 洞头县| 庆安县| 宜阳县| 分宜县| 鹿邑县| 玉环县| 平乡县| 成安县| 三原县| 牟定县| 潮州市| 鹰潭市| 秦安县| 韶关市| 阿拉善右旗| 洛扎县| 五华县| 和顺县| 德昌县| 郁南县| 拉萨市| 白玉县| 福安市| 西畴县| 东平县| 东阿县| 紫金县| 孝感市| 丰台区| 霍山县| 翁源县| 莱州市| 武城县| 南安市| 鹤山市| 宜兰市| 黑河市| 麻阳| 武义县|