非严格模式下如何避免React组件中useEffect触发两次打印
非严格模式下如何避免React组件中useEffect触发两次打印
嗨,我来帮你搞定这个问题!首先咱们得先弄明白为啥会出现两次打印:
你的组件里,初始booValue是false,挂载时第一个空依赖的useEffect会执行,把booValue改成true。而第二个监听booValue的useEffect,会在初始渲染完成(此时booValue是false)和booValue更新为true后各触发一次,所以就出现了两次打印。
下面给你几个可行的解决方案,按需选择:
方案一:用useRef跳过首次渲染的打印
如果必须要保留修改初始state的逻辑,咱们可以用useRef标记是否是第一次进入监听booValue的useEffect,首次直接跳过,只在state更新后打印:
import React from "react"; export default function TestComponent(){ const [booValue, setBoolValue] = React.useState(false) // 标记是否为首次渲染 const isFirstRender = React.useRef(true); React.useEffect(() => { setBoolValue(!booValue); },[]) React.useEffect(() => { // 首次渲染直接跳过 if (isFirstRender.current) { isFirstRender.current = false; return; } console.log('booValue is', booValue) },[booValue]) return ( <></> ) }
这样就只会打印booValue is true啦。
方案二:直接设置目标初始值(最简单)
如果业务逻辑允许,咱们可以直接把booValue的初始值设为true,去掉第一个修改state的useEffect,这样监听的useEffect只会在挂载时打印一次true:
import React from "react"; export default function TestComponent(){ // 直接设置初始值为目标值 const [booValue, setBoolValue] = React.useState(true) React.useEffect(() => { console.log('booValue is', booValue) },[booValue]) return ( <></> ) }
方案三:用函数式更新优化逻辑(适合复杂场景)
如果你的state更新逻辑更复杂,推荐用函数式更新的方式设置state,确保基于最新的state值修改,避免闭包陷阱:
import React from "react"; export default function TestComponent(){ const [booValue, setBoolValue] = React.useState(false) const isFirstRender = React.useRef(true); React.useEffect(() => { // 函数式更新,确保拿到最新的state值 setBoolValue(prev => !prev); },[]) React.useEffect(() => { if (isFirstRender.current) { isFirstRender.current = false; return; } console.log('booValue is', booValue) },[booValue]) return ( <></> ) }
备注:内容来源于stack exchange,提问作者kulakesh
相关产品推荐
相关产品推荐

