- 在下面的代码中,如何使
status
变量的值在setStatus(!status)
之后立即更改?我知道React中的状态更新是分批的,因此我使用带有回调的useEffect
,但在第一次单击按钮时,status
的值仍然记录为false
(好像它没有立即更改( - 考虑到应用程序渲染在任何方面都不依赖于
status
变量(实际上,我甚至更希望该变量的更改不会触发渲染(,完全不使用useEffect
并将status
设为"0"是不是一种糟糕的做法;正常的";变量,像status = true
一样分配
function App() {
const [status, setStatus] = React.useState(false)
React.useEffect(() => toggleStatus, [status])
function onClickHandler() {
toggleStatus()
console.log(status)
}
function toggleStatus() {
setStatus(!status)
}
return (
<div>
<button onClick={onClickHandler}>Toggle & log status</button>
</div>
)
}
ReactDOM.render( < App /> , document.getElementById('root'))
<script src="https://unpkg.com/react@^16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
<div id="root"></div>
- 单击
onClickHandler
时触发===>toggleStatus
和console.log(status)
是同步触发的(toggleStatus的setStatus(!status)
是异步触发的。所以你可以看到false
被记录了。并且您使用useEffect
不正确。React.useEffect(() => toggleStatus, [status])
表示useEffect
返回toggleStatus
函数的第一个自变量,即useEffect
的清除动作
尝试此操作以查看记录的状态
React.useEffect(() =>{
//you can see true after first click here
console.log(status)
}, [status])
- 如果要立即更改
status
而不重新渲染组件,则应使用useRef
我会评论你的代码
function App() {
const [status, setStatus] = React.useState(false)
React.useEffect(() => toggleStatus, [status]) // here you are toggle the status again when the status change
function onClickHandler() {
toggleStatus()
console.log(status)
}
function toggleStatus() {
setStatus(!status) // here you can do setStatus(prevStatus => !prevStatus)
}
return (
<div>
<button onClick={onClickHandler}>Toggle & log status</button>
</div>
)
}
ReactDOM.render( < App /> , document.getElementById('root'))
<script src="https://unpkg.com/react@^16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
<div id="root"></div>
你可以尝试在useEffect中使用console.log(状态(,看看是否一切正常。
React.useEffect(() => console.log(status), [status])
现在谈谈第二点,在我看来,这是一个不错的做法。根据React文档:
状态包含特定于此组件的数据,这些数据可能会更改随着时间的推移。[…]如果你不在render((中使用它,它就不应该在州。例如,您可以将计时器ID直接放在例子
React状态用于跟踪应用程序状态,并在底层状态发生变化时重新呈现应用程序。
现在,如果不希望重新渲染,则当status
发生更改时,应将status
声明为常规变量。
如果需要,您仍然可以使用useEffect
react钩子。您可以在这里初始化status
。useEffect
被称为组件安装/呈现在浏览器DOM 上
在下面的代码中,如何使状态变量的值在
setStatus(!status)
之后立即更改?
您不能立即更改状态,因为更改状态是异步的。
我甚至更希望这个变量的更改不会触发渲染(,完全不使用
useEffect
并将状态设为";正常的";变量,像status=true一样赋值?
首先,检查useEffect
的用例是什么。
关于制作";正常的";相反,这确实是一种糟糕的做法:
const Component = () => {
let variable = ...;
return <>...</>
}
这是因为,在每次渲染时,这些变量都会被重新分配(因为在每次渲染中执行的函数组件的主体(通常,这不是所需的行为。
相反,您希望使用具有useRef
的引用。查看useRef
和变量之间的区别。
更改引用值不会触发渲染,因此不会更新UI。