React中Toggle功能第二次点击时状态切回false的实现原理
React Toggle 开关状态切换原理解答
核心原因很简单:每次状态更新触发组件重渲染时,useState都会返回最新的状态值,而代码里的!是取反运算符,永远会把当前拿到的状态值翻转为相反的布尔值。
逐步骤执行逻辑
对应你梳理的流程,第二次点击的完整逻辑是这样的:
- 组件首次挂载:
useState(false)完成初始化,此时state值为false,页面不展示文本内容,changeState函数里能拿到的初始state就是false - 第一次点击按钮:执行
setState(!state),也就是把!false的计算结果true设为新状态,React触发组件重新渲染 - 第一次重渲染完成:
useState返回更新后的状态值true,页面展示Show Content,这一轮渲染生成的changeState函数,闭包里捕获到的state已经是最新的true了 - 第二次点击按钮:触发的是重渲染后新的
changeState函数,此时取到的state是true,执行setState(!true)也就是把false设为新状态,再次触发重渲染 - 第二次重渲染完成:
state回到false,内容隐藏,回到初始状态,之后每次点击都会重复这个取反-更新-重渲染的循环
补充优化提示
你现在的写法在普通场景下能正常运行,但如果遇到连续快速触发状态更新的场景,可能因为闭包缓存了旧的state值导致更新不符合预期,更稳妥的写法是用函数式更新,直接拿到上一次的最新状态做计算:
import React, {useState} from 'react' function App() { const [state,setState]=useState(false); console.log(state); const changeState=()=>{ // 函数式更新,prev永远是上一轮更新后的最新状态 setState(prev => !prev); } return ( <> {state ? <div>Show Content</div> : null} <button onClick={changeState}>Toggle</button> </> ) } export default App
简单说就是:你每次点击时用到的
state,永远是当前页面正在展示时对应的那个最新状态值,点的时候是true,取反就变false,点的时候是false,取反就变true,自然就能来回切换。
内容的提问来源于stack exchange,提问作者Ren Jitsm
相关产品推荐
相关产品推荐

