[英]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>
}
val
和setVal
將在每個渲染上更改,這反過來將導致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.