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

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

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

前言

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

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

自定義 Hooks 簡單實(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)化后再測試

鼠標(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)惰性初始stateinitialState` 只會(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使用react-bootstrap當(dāng)輪子造車

    詳解react使用react-bootstrap當(dāng)輪子造車

    本篇文章主要介紹了詳解react使用react-bootstrap當(dāng)輪子造車,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-08-08
  • 一文詳解ReactNative狀態(tài)管理rematch使用

    一文詳解ReactNative狀態(tài)管理rematch使用

    這篇文章主要為大家介紹了ReactNative狀態(tài)管理rematch使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • ReactNative踩坑之配置調(diào)試端口的解決方法

    ReactNative踩坑之配置調(diào)試端口的解決方法

    本篇文章主要介紹了ReactNative踩坑之配置調(diào)試端口的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 關(guān)于React中setState同步或異步問題的理解

    關(guān)于React中setState同步或異步問題的理解

    相信很多小伙伴們都一直在疑惑,setState 到底是同步還是異步。本文就詳細(xì)的介紹一下React中setState同步或異步問題,感興趣的可以了解一下
    2021-11-11
  • React Component存在的幾種形式詳解

    React Component存在的幾種形式詳解

    這篇文章主要給大家介紹了關(guān)于React Component存在的幾種形式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • 在React中集成第三方庫和插件方式

    在React中集成第三方庫和插件方式

    本文詳細(xì)介紹了如何在React項(xiàng)目中高效集成第三方庫和插件,包括選擇合適的庫、封裝為React組件、按需加載、避免直接操作DOM、處理庫的更新和卸載、樣式處理與主題定制、性能優(yōu)化以及調(diào)試與維護(hù)等方面,通過遵循這些最佳實(shí)踐,可以確保集成過程高效且優(yōu)雅
    2025-03-03
  • React引入css的三種方式小結(jié)

    React引入css的三種方式小結(jié)

    這篇文章主要介紹了React引入css的三種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 淺談react useEffect閉包的坑

    淺談react useEffect閉包的坑

    筆者最近用react useEffect閉包,其中踩到了一些坑在此與大家分享一下。需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • React深入分析useEffect源碼

    React深入分析useEffect源碼

    useEffect是react?v16.8新引入的特性。我們可以把useEffect?hook看作是componentDidMount、componentDidUpdate、componentWillUnmounrt三個(gè)函數(shù)的組合
    2022-11-11
  • React?Native?中限制導(dǎo)入某些組件和模塊的方法

    React?Native?中限制導(dǎo)入某些組件和模塊的方法

    這篇文章主要介紹了React?Native?中限制導(dǎo)入某些組件和模塊的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08

最新評(píng)論

武邑县| 堆龙德庆县| 红河县| 平度市| 东乌珠穆沁旗| 耿马| 科技| 本溪| 定西市| 科技| 肥城市| 厦门市| 大港区| 万州区| 东山县| 梁山县| 吴江市| 灌云县| 芜湖市| 双城市| 桂林市| 廉江市| 石渠县| 共和县| 大厂| 贵定县| 贺兰县| 昌吉市| 开阳县| 霍山县| 余姚市| 安化县| 方城县| 白山市| 新田县| 健康| 湛江市| 嘉善县| 得荣县| 太保市| 潮安县|