欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React?Hooks useReducer?逃避deps組件渲染次數(shù)增加陷阱

 更新時(shí)間:2022年09月06日 16:45:22   作者:qwer  
這篇文章主要介紹了React?Hooks?之?useReducer?逃避deps后增加組件渲染次數(shù)的陷阱詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

在快樂使用 React Hooks 開發(fā)自定義 Hooks 過程中,使用了 useEffect,useReducer,useRefuseCallback 等官方提供的 Hooks,將一些通用邏輯抽離出來,提高代碼復(fù)用性。

但在組合使用 useEffect,useReducerReact.memo 時(shí),發(fā)生了組件在狀態(tài)未發(fā)生變化時(shí)觸發(fā)渲染,因?yàn)榇藙?dòng)作發(fā)生在 mousemove 鼠標(biāo)移動(dòng)時(shí),所以組件不必要渲染次數(shù)非常多。

自定義 Hooks 簡(jiǎn)單實(shí)現(xiàn)

import { useReducer } from "react";
const reducer = (state, action) => {
  const { sliding, lastPos, ratio } = state;
  switch (action.type) {
    case "start":
      return {
        ...state,
        slideRange: action.slideRange,
        lastPos: action.x,
        sliding: true,
      };
    case "move":
      if (!sliding) {
        return state;
      }
      const offsetX = action.x - lastPos;
      const newRatio = ratio + offsetX / state.slideRange;
      if (newRatio > 1 || newRatio < 0) {
        return state;
      }
      return {
        ...state,
        lastPos: action.x,
        ratio: newRatio,
      };
    case "end":
      if (!sliding) {
        return state;
      }
      return {
        ...state,
        sliding: false,
      };
    case "updateRatio":
      return {
        ...state,
        ratio: action.ratio,
      };
    default:
      return state;
  }
};
export function useSlider(initialState) {
    const [state, dispatch] = useReducer(reducer, initialState);
    return [state, dispatch];
}

在組件中使用自定義 Hooks

const [state, dispatch] = useSlider(initialState);
  const { ratio, sliding, lastPos, slideRange } = state;
  useEffect(() => {
    const onSliding = (e) => {
      dispatch({ type: "move", x: e.pageX });
    };
    const onSlideEnd = () => {
      dispatch({ type: "end" });
    };
    document.addEventListener("mousemove", onSliding);
    document.addEventListener("mouseup", onSlideEnd);
    return () => {
      document.removeEventListener("mousemove", onSliding);
      document.removeEventListener("mouseup", onSlideEnd);
    };
  }, [dispatch]);
  const handleThumbMouseDown = useCallback(
    (event) => {
      const hotArea = hotAreaRef.current;
      dispatch({
        type: "start",
        x: event.pageX,
        slideRange: hotArea.clientWidth,
      });
      if (event.target.className !== "point") {
        dispatch({
          type: "updateRatio",
          ratio: (event.pageX - 30) / hotArea.clientWidth,
        });
      }
    },
    [dispatch]
  );

鼠標(biāo)每次移動(dòng),都會(huì)觸發(fā) dispatch({ type: "move", x: e.pageX }),在 reducer 函數(shù)中,當(dāng) !sliding 時(shí),不修改 state 數(shù)據(jù)原樣返回,但是組件仍然進(jìn)行了渲染。

提前阻止 dispatch 觸發(fā)

sliding 判斷移動(dòng)到 useEffect 中,提前阻止 dispatch 觸發(fā),并將 sliding 設(shè)置到 useEffect(fn, deps) deps 中,保證監(jiān)聽函數(shù)中能取到 sliding 最新值。

useEffect(() => {
    const onSliding = (e) => {
      if(!sliding) {
        return;
      }
      dispatch({ type: "move", x: e.pageX });
    };
    const onSlideEnd = () => {
      if (!sliding) {
        return;
      }
      dispatch({ type: "end" });
    };
    document.addEventListener("mousemove", onSliding);
    document.addEventListener("mouseup", onSlideEnd);
    return () => {
      document.removeEventListener("mousemove", onSliding);
      document.removeEventListener("mouseup", onSlideEnd);
    };
  }, [sliding]);

優(yōu)化后再測(cè)試

鼠標(biāo)僅移動(dòng)時(shí),slidingfalse,直接 return,不會(huì)觸發(fā) dispatch 動(dòng)作。

好處

避免了組件在 state 未修改時(shí)不必要渲染。

壞處

部分處理邏輯被移動(dòng)到使用自定義 hooks 的組件中,sliding 數(shù)據(jù)改變時(shí),add EventListener函數(shù)會(huì)重新注冊(cè)。

結(jié)論

不能為了不在 useEffect(fn, deps) 設(shè)置 deps,使用 useReducer,并把所有數(shù)據(jù)變更都放在 reducer 中。 本篇文章通過把不修改 reducer state 的動(dòng)作提前阻止,避免使用此自定義 hooks 的組件發(fā)生不必要渲染,提高代碼復(fù)用性的同時(shí)也兼顧了組件性能。

題外

  • React.memo 對(duì) props 進(jìn)行淺比較,一種組件性能優(yōu)化方式
  • useCallback(fn, deps) 緩存函數(shù)
  • useMemo(() => fn, deps) 緩存昂貴變量
  • useState(initialState)惰性初始state,initialState` 只會(huì)在組件初始渲染中起作用,后續(xù)渲染時(shí)會(huì)被

參考文獻(xiàn)

React 官方文檔

以上就是React Hooks 之 useReducer 逃避deps后增加組件渲染次數(shù)的陷阱的詳細(xì)內(nèi)容,更多關(guān)于React Hooks useReducer組件渲染的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • react router 4.0以上的路由應(yīng)用詳解

    react router 4.0以上的路由應(yīng)用詳解

    本篇文章主要介紹了react router 4.0以上的路由應(yīng)用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • react如何修改循環(huán)數(shù)組對(duì)象的數(shù)據(jù)

    react如何修改循環(huán)數(shù)組對(duì)象的數(shù)據(jù)

    這篇文章主要介紹了react如何修改循環(huán)數(shù)組對(duì)象的數(shù)據(jù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • create-react-app中添加less支持的實(shí)現(xiàn)

    create-react-app中添加less支持的實(shí)現(xiàn)

    這篇文章主要介紹了react.js create-react-app中添加less支持的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • React實(shí)現(xiàn)復(fù)雜搜索表單的展開收起功能

    React實(shí)現(xiàn)復(fù)雜搜索表單的展開收起功能

    本節(jié)對(duì)于需要展開收起效果的查詢表單進(jìn)行概述,主要涉及前端樣式知識(shí)。對(duì)React實(shí)現(xiàn)復(fù)雜搜索表單的展開-收起功能感興趣的朋友一起看看吧
    2021-09-09
  • 使用?React?Hooks?重構(gòu)類組件的示例詳解

    使用?React?Hooks?重構(gòu)類組件的示例詳解

    這篇文章主要介紹了如何使用?React?Hooks?重構(gòu)類組件,本文就來通過一些常見示例看看如何使用 React Hooks 來重構(gòu)類組件,需要的朋友可以參考下
    2022-07-07
  • React 子組件向父組件傳值的方法

    React 子組件向父組件傳值的方法

    本篇文章主要介紹了React 子組件向父組件傳值的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • TypeScript在React項(xiàng)目中的使用實(shí)踐總結(jié)

    TypeScript在React項(xiàng)目中的使用實(shí)踐總結(jié)

    這篇文章主要介紹了TypeScript在React項(xiàng)目中的使用總結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • D3.js(v3)+react 實(shí)現(xiàn)帶坐標(biāo)與比例尺的柱形圖 (V3版本)

    D3.js(v3)+react 實(shí)現(xiàn)帶坐標(biāo)與比例尺的柱形圖 (V3版本)

    這篇文章主要介紹了D3.js(v3)+react 制作 一個(gè)帶坐標(biāo)與比例尺的柱形圖 (V3版本) ,本文通過實(shí)例代碼文字相結(jié)合的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2019-05-05
  • React模仿網(wǎng)易云音樂實(shí)現(xiàn)一個(gè)音樂項(xiàng)目詳解流程

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

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

    Electron+React應(yīng)用打包全流程

    本文主要介紹了Electron+React應(yīng)用打包全流程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01

最新評(píng)論