<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

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

    共 3498字,需瀏覽 7分鐘

     ·

    2024-04-11 11:46

    前言

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

    副作用

    副作用指的是當(dāng)調(diào)用函數(shù)時(shí),除開返回函數(shù)值之外,還對主調(diào)用函數(shù)產(chǎn)生附加的影響。JS的部分內(nèi)置函數(shù)是有副作用的,例如:

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

    無限循環(huán)

    下面我們通過幾個(gè)例子來認(rèn)識下useEffect的不恰當(dāng)用法導(dǎo)致的無限循環(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」框輸入時(shí)會去更新value的值,這時(shí)候頁面會重新渲染,因?yàn)?strong style="color:rgb(145,109,213);">「useEffect」沒有依賴參數(shù),這個(gè)時(shí)候便會每次渲染都會執(zhí)行副作用回調(diào),每次回調(diào)都會更新count,于是又會執(zhí)行回調(diào);陷入了無限循環(huán)。

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

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

    數(shù)組或?qū)ο笞鳛橐蕾?/p>

    「useEffect」只有當(dāng)依賴發(fā)生改變時(shí)才會去觸發(fā)回調(diào),而且是通過淺層對象比較是否發(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>

     );
    }

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

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

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

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

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

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

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

    函數(shù)作為依賴

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

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

    總結(jié)

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



    瀏覽 41
    點(diǎn)贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評論
    圖片
    表情
    推薦
    點(diǎn)贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    一道本无码在线视频 | 免费国产视频 | 又色又爽又黄18 网站 | 国产精品久久久久久苍井空 | seseseseavse |