我正在阅读 React hooks 的示例。我发现他们写
setCount(count + 1)
Run Code Online (Sandbox Code Playgroud)
但我通常这样写
setCount(prev => prev + 1)
Run Code Online (Sandbox Code Playgroud)
有什么区别吗?哪一个更好?
有一个区别,首先,由于函数中的闭包,计数将基于渲染发生时的当前值。
第二个将始终使用最新的增量值。
由于闭包是一个复杂的主题,因此这里有一些示例。第一个显示了两者之间的主要区别。
第二个示例展示了几种使闭包和效果/钩子能够正常工作的方法
const { useState, useEffect } = React;
function Example(){
const [count1, setCount1] = useState(0);
useEffect(()=>{
setCount1(count1 + 1);
setCount1(count1 + 1);
setCount1(count1 + 1);
},[])
const [count2, setCount2] = useState(0);
useEffect(()=>{
setCount2(prev=> prev + 1);
setCount2(prev=> prev + 1);
setCount2(prev=> prev + 1);
},[])
return <div>
Both count1 and count2 have had 3 increments.
<br/>
count1 stays at 1 because the count1 variable in the useEffect isn't change due to the closure in the arrow function in the useEffect
<br/>
Current count1: {count1}
<br/>
Current count2: {count2}
</div>
}
ReactDOM.render(<Example/>,document.getElementById('root'))Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"/>Run Code Online (Sandbox Code Playgroud)
const { useState, useEffect, useRef } = React;
function Example(){
const [count1, setCount1] = useState(0);
const [count2, setCount2] = useState(0);
const [count3, setCount3] = useState(0);
const count3Ref = useRef(count3);
count3Ref.current = count3;
useEffect(()=>{
const id = setInterval(()=>{
setCount1(count1+1);
setCount2(prev=>prev+1);
setCount3(count3Ref.current+1);
},300)
return ()=>{clearInterval(id)}
},[])
const [count4, setCount4] = useState(0);
useEffect(()=>{
const id = setTimeout(()=>{
setCount4(count4+1);
},300)
return ()=>{clearTimeout(id)}
},[count4])
return <div>
All of the counts theoretically increment every 300ms
<br/>
<br/>
count1 stays at 1 because the count1 variable in the useEffect isn't change due to the closure in the arrow function in the useEffect
<br/>
Current count1: {count1}
<hr/>
count2 uses the functional version of setCount2 so it always uses the latest version and will update properly
<br/>
Current count2: {count2}
<hr/>
count3 increments because refs are mutable by nature and allow us to bypass the closure.
<br/>
Current count3: {count3}
<hr/>
Another possiblity: count4 increments because we properly use the dependency array and force the useEffect to re-run every time count4 changes.
<br/>
Current count4: {count4}
</div>
}
ReactDOM.render(<Example/>,document.getElementById('root'))Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
<div id="root"/>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6798 次 |
| 最近记录: |