React 函数组件中的 setState 如何工作?
how setState in react function component works?
我编写这段代码,我希望 A 为 8,但实际为 6。为什么?
如果我删除第 6 行,它会正常工作,但如果我没有在 setState 中使用回调,它会忽略它上面的所有行。
import React, { useState, useEffect } from 'react'
function SameSet() {
const [A, setA] = useState(0)
const go = () => {
setA((preA) => preA + 1)
setA(A + 1)
setA((preA) => 2)
setA((preA) => preA + 4)
}
return (
<div>
{A}
<button onClick={() => {
go()
}}> ok</button>
</div>
)
}
export default SameSet
这些状态更新是异步的。它们可能会分批发送。无法确定前三个状态更新何时会 运行。这就是为什么使用回调始终是一种很好的做法,尤其是当您使用前一个状态值时。(您在这里使用的是模式,但使用的方式不同。)
setA((preA) => preA + 1) //Setting to 1 using previous Value
setA(A + 1) //Setting to 1
setA((preA) => 2) // Setting to 2 but not using previous Value
setA((preA) => preA + 4) //Setting to 6 using previous Value
第 6 行将值设置为稍后在使用回调模式 (prevValue) 时使用的特定值。他们不会使用当时为 0 的 prev 值。
setA((preA) => 2)
只需 returns 2 并将 A
设置为 2
。
因此在下一行之后 setA((preA) => preA + 4)
设置为 A
到 2 + 4 = 6
。
这样的问题可能有很多。请记住,console.log()
是所有开发者最好的礼物。
setA((preA) => 2)
定义了一个函数,return值为2
.
所以 A
设置为 2.
(last) 之后的行添加另一个 2
,因此 A
变为 6
,如下所示:
片段:
// Get a hook function
const {useState} = React;
const SameSet = () => {
const [A, setA] = useState(0);
const go = () => {
setA((preA) => preA + 1) // 0 + 1 = 1
setA(A + 1) // 1 + 1 = 2
setA((preA) => 2) // 2
setA((preA) => preA + 4) // 2 + 2 = 4
}
return (
<div>
{A}
<button onClick={() => {
go()
}}> ok</button>
</div>
)
}
ReactDOM.render(<SameSet />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
您可能总是想像这样将 n
添加到 prevA
以获得所需的 8
:
setA((preA) => preA + 1);
setA((preA) => preA + 1);
setA((preA) => preA + 2);
setA((preA) => preA + 4);
片段:
// Get a hook function
const {useState} = React;
const SameSet = () => {
const [A, setA] = useState(0);
const go = () => {
setA((preA) => preA + 1);
setA((preA) => preA + 1);
setA((preA) => preA + 2);
setA((preA) => preA + 4);
}
return (
<div>
{A}
<button onClick={() => {
go()
}}> ok</button>
</div>
)
}
ReactDOM.render(<SameSet />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
我编写这段代码,我希望 A 为 8,但实际为 6。为什么? 如果我删除第 6 行,它会正常工作,但如果我没有在 setState 中使用回调,它会忽略它上面的所有行。
import React, { useState, useEffect } from 'react'
function SameSet() {
const [A, setA] = useState(0)
const go = () => {
setA((preA) => preA + 1)
setA(A + 1)
setA((preA) => 2)
setA((preA) => preA + 4)
}
return (
<div>
{A}
<button onClick={() => {
go()
}}> ok</button>
</div>
)
}
export default SameSet
这些状态更新是异步的。它们可能会分批发送。无法确定前三个状态更新何时会 运行。这就是为什么使用回调始终是一种很好的做法,尤其是当您使用前一个状态值时。(您在这里使用的是模式,但使用的方式不同。)
setA((preA) => preA + 1) //Setting to 1 using previous Value
setA(A + 1) //Setting to 1
setA((preA) => 2) // Setting to 2 but not using previous Value
setA((preA) => preA + 4) //Setting to 6 using previous Value
第 6 行将值设置为稍后在使用回调模式 (prevValue) 时使用的特定值。他们不会使用当时为 0 的 prev 值。
setA((preA) => 2)
只需 returns 2 并将 A
设置为 2
。
因此在下一行之后 setA((preA) => preA + 4)
设置为 A
到 2 + 4 = 6
。
这样的问题可能有很多。请记住,console.log()
是所有开发者最好的礼物。
setA((preA) => 2)
定义了一个函数,return值为2
.
所以 A
设置为 2.
(last) 之后的行添加另一个 2
,因此 A
变为 6
,如下所示:
片段:
// Get a hook function
const {useState} = React;
const SameSet = () => {
const [A, setA] = useState(0);
const go = () => {
setA((preA) => preA + 1) // 0 + 1 = 1
setA(A + 1) // 1 + 1 = 2
setA((preA) => 2) // 2
setA((preA) => preA + 4) // 2 + 2 = 4
}
return (
<div>
{A}
<button onClick={() => {
go()
}}> ok</button>
</div>
)
}
ReactDOM.render(<SameSet />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
您可能总是想像这样将 n
添加到 prevA
以获得所需的 8
:
setA((preA) => preA + 1);
setA((preA) => preA + 1);
setA((preA) => preA + 2);
setA((preA) => preA + 4);
片段:
// Get a hook function
const {useState} = React;
const SameSet = () => {
const [A, setA] = useState(0);
const go = () => {
setA((preA) => preA + 1);
setA((preA) => preA + 1);
setA((preA) => preA + 2);
setA((preA) => preA + 4);
}
return (
<div>
{A}
<button onClick={() => {
go()
}}> ok</button>
</div>
)
}
ReactDOM.render(<SameSet />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>