簡體   English   中英

無限循環React鈎子

[英]Infinite loop React hooks

我不明白為什么我在使用中獲得無限循環點擊我看到我使用setVal更改useEffect中的狀態值但是useEffect應該只對第二個參數中指定的onClick有效。 我認為這是因為onClick on pass的param是memoized但是沒有調用回調(我使用console.log檢查了它('go set')

function useClick(onClick, setVal, val) {
  React.useEffect(() => {
    console.log('Click');
    setVal(val + 1);
  }, [onClick]);
}

const Home = () => {
  const [val, setVal] = React.useState(0);
  const incrementOnClick = React.useCallback(() => {
    console.log('go set');
    setVal(val + 1);
  } , [setVal, val]);
  useClick(incrementOnClick, setVal, val);
  return <div>
    <div>{val}</div>
    <button onClick={incrementOnClick}>Click me</button>
 </div>
}

valsetVal將在每個渲染上更改,這反過來將導致incrementOnClick成為新的函數引用,並且將始終調用useClick效果。

您可以改為將函數作為setVal第一個參數。 此函數將當前val作為參數,並返回新值。 這種方式incrementOnClick將始終是相同的功能。

 const { useEffect, useState, useCallback } = React; function useClick(onClick, setVal, val) { useEffect(() => { console.log("Click"); setVal(val + 1); }, [onClick]); } const Home = () => { const [val, setVal] = useState(0); const incrementOnClick = useCallback(() => { console.log("go set"); setVal(val => val + 1); }, []); useClick(incrementOnClick, setVal, val); return ( <div> <div>{val}</div> <button onClick={incrementOnClick}>Click me</button> </div> ); }; ReactDOM.render(<Home />, document.getElementById("root")); 
 <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div> 

上面的代碼展示了如何擺脫無限循環並且對於實驗很有價值,但大部分都沒有必要。 您可以編寫相同的功能:

 const { useState } = React; const Home = () => { const [val, setVal] = useState(1); return ( <div> <div>{val}</div> <button onClick={() => setVal(val + 1)}>Click me</button> </div> ); }; ReactDOM.render(<Home />, document.getElementById("root")); 
 <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div> 

看看你想要做什么,我相信你錯過了Hooks&React最有用的功能,以及那個組合。

這是你所做的一個例子,但只是創建另一個名為<IncrementButton/>組件,對我來說它只是使代碼更容易理解/調試。 自定義掛鈎很棒,但為了做到這一點,我相信這是錯誤的工具..

 const { useEffect, useState } = React; const IncrementButton = props => { const {val, setVal, children} = props; return <button onClick={() => setVal(val + 1)} >{children}</button>; } const Home = () => { const [val, setVal] = useState(0); return ( <div> <div>{val}</div> <IncrementButton val={val} setVal={setVal}> Click me </IncrementButton> </div> ); }; ReactDOM.render(<Home />, document.getElementById("root")); 
 <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM