<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          React useEffect()的無限循環(huán)是怎樣來的

          共 3498字,需瀏覽 7分鐘

           ·

          2024-04-11 11:46

          前言

          我們都知道useEffect()用來引入具有「副作用」的操作,例如AJAX請求DOM操作啟動與結束倒計時監(jiān)聽與接觸事件等,這些都可以在useEffect鉤子去做。那么,是不是就真的那么簡單的可以直接使用了呢?不是的,你可能會遇到一個陷阱,那就是組件渲染的無限循環(huán),本文將為各位同學詳細介紹無限循環(huán)的常見場景以及如何避免。

          副作用

          副作用指的是當調用函數(shù)時,除開返回函數(shù)值之外,還對主調用函數(shù)產生附加的影響。JS的部分內置函數(shù)是有副作用的,例如:

                
                [1,2,3].pop(); // 執(zhí)行完pop函數(shù)后,原數(shù)據(jù)會少一個元素

          無限循環(huán)

          下面我們通過幾個例子來認識下useEffect的不恰當用法導致的無限循環(huán);

          缺失依賴

                
                import React, { Fragment, useState } from 'react';

          function countChange() {
           const [value, setValue] = useState('');
           const [count, setCount] = useState(0);
           useEffect(() => {
            setCount(count + 1);
           });
           return (
            <Fragment>
             <input
              type="text"
              value={value}
              onChange={({ target }) =>
           {
               setValue(target.value);
              }}
             />
             <div>count is {count}</div>
            </Fragment>

            );
          }

          上述例子中,「input」框輸入時會去更新value的值,這時候頁面會重新渲染,因為「useEffect」沒有依賴參數(shù),這個時候便會每次渲染都會執(zhí)行副作用回調,每次回調都會更新count,于是又會執(zhí)行回調;陷入了無限循環(huán)。

          這個時候,只需要給「useEffect」加上個依賴,只有value的值有更新的時候,才去執(zhí)行副作用回調。避免了無限循環(huán);依賴項為空數(shù)組時,代表只在初次渲染是調用一次;

                
                useEffect(() => {
           setCount(count + 1);
          }, [value]);

          數(shù)組或對象作為依賴

          「useEffect」只有當依賴發(fā)生改變時才會去觸發(fā)回調,而且是通過淺層對象比較是否發(fā)生改變;那如果用對象或者數(shù)據(jù)作為依賴會發(fā)生什么呢?

                
                import React, { Fragment, useState } from 'react';

          function countChange() {
           const [value, setValue] = useState('');
           const [count, setCount] = useState(0);
           const dep = ['dep'];
           const obj = {
            name'pp',
           };
           // 使用數(shù)組作為依賴
           useEffect(() => {
            setCount(count + 1);
           }, [dep]);
           // 使用對象作為依賴
           useEffect(() => {
            setCount(count + 1);
           }, [obj]);
           return (
            <Fragment>
             <input
              type="text"
              value={value}
              onChange={({ target }) =>
           {
               setValue(target.value);
              }}
             />
             <div>count is {count}</div>
            </Fragment>

           );
          }

          由于淺層對比的關系,比較的結果總是false,無論是數(shù)組還是對象作為依賴,都會一次又一次的觸發(fā)回調;導致出現(xiàn)無限循環(huán)。

          數(shù)組作為對象可以通過「useRef」解決,更改引用本身不會觸發(fā)組件重新渲染,相應代碼改為:

                
                const { current: dep } = useRef(['dep']);

          useEffect(() => {
           setCount(count + 1);
          }, [dep]);

          對象作為對象可以通過「useMemo」解決,只有在依賴關系發(fā)生變化時才會重新計算記憶化的值。相應代碼改為:

                
                const obj = useMemo(() => ({
           name'pp',
          }), [])

          useEffect(() => {
           setCount(count + 1);
          }, [obj]);

          函數(shù)作為依賴

          函數(shù)作為依賴項也是會導致無限循環(huán)的,這里不再貼代碼;我們可以通過「useCallback」來解決;「useCallback」返回一個memoized版本的回調,只有在依賴關系改變時才會改變。

                
                const func = useCallback(() => {
           return '1';
          }, []);

          總結

          「useEffect」功能很強大,但是如果使用不當便會出現(xiàn)難以想象的問題,因此一定要正確使用「useEffect」。若useEffect的依賴數(shù)組的依賴值為ObjectArrayFunction等引用型數(shù)據(jù),那么就需注意了。



          瀏覽 41
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中国 免费XXXX18 | 黑人大阴道视频在线观看 | 99re99在线 | 大香蕉网免费伊人 | 日本偷拍自拍大香蕉 |