useEffect無限調用問題


1.useEfect()的基本用法

 const [test,setTest] = useState(1)
    const init=()=>{
        setTest(2)
    }
  useEffect(()=>{
      init()
      console.log('kkk',test)
  },[test])

紅色'test'則是監聽的數據,這里的監聽數據要分為兩種,1是基本數據類型,2是對象和數組

2.監聽原理基本理解.

  簡單來說就是當修改后的值不同於修改之前就會執行.test默認為1,setTest()之后變成了2,又會執行init(),但是再次setTest()之后,test還是2,所以只會執行2次.一次默認,一次更改之后.

 但是,當每次執行test都變化時將會無限次執行

const [test,setTest] = useState(1)
    const init=()=>{
        setTest(test+1)
    }
  useEffect(()=>{
      init()
      console.log('kkk',test)
  },[test])

test每次更改都會和上次不一樣,所以他會無限執行

3.監聽對象和數組

當你在useEffect中監聽對象或數組的時候,它會無條件無限執行.你可以理解為引用數據類型數據在監聽時每次都生成了一個新的數據.所以必定會執行.

故,不要把數組或者對象作為監聽對象.

//不能這么寫
const [test,setTest] = useState({name:'小明',age:'18'}) const init=()=>{ setTest({name:'小紅',age:'16'}) } useEffect(()=>{ init() console.log('kkk',test) },[test])

解決方案:

   如果我每次更改的就是對象,那我怎么監聽.

   1.標記法

     同步更新一個可檢測的數據,然后監聽這個數據.

const [test,setTest] = useState({name:'小明',age:'18'})
    const [index,setIndex] = useState(0)
    const init=()=>{
        setTest({name:'小紅',age:'16'})
        setIndex(1)
    }
  useEffect(()=>{
      init()
      console.log('kkk',test)
  },[index])

  這要求每個修改都必須要同步修改index,一次都不能少.相當於又引入了一個數據,還得自己全程盯着,流程多的時候可能會亂.不建議使用

2.加判斷

假如我知道數據的走向,並且可以准確找到臨界點.那我可以通過判斷來掐斷無限更新的流程

const [test,setTest] = useState(1)
    const init=()=>{
        setTest(test+1)
    }
  useEffect(()=>{
      if(test!==2){
        init()
        console.log('kkk',test)
      }else{

      }
  },[test])

3.對象屬性監聽

 通過監聽對象屬性來判斷對象變化,同時符合監聽規則,不會無限執行

const [test,setTest] = useState({name:'小明',age:'18'})
    const init=()=>{
        setTest({name:'小紅',age:'16'})
    }
  useEffect(()=>{
        init()
        console.log('kkk',test)

  },[test.name])

4.函數式賦值.

useState()可以通過返回返回值的方式賦值,在這個函數中可以拿到上次更改的state值,並且阻斷useState自身

 

const [test,setTest] = useState(1)
    const init=()=>{
        setTest((i)=>{
           if(i<2){
               console.log('???',i)

               return i+1
           }else{
                return i
           }
        })
    }
  useEffect(()=>{
        init()
        console.log('kkk',test)
  },[test])

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM