我有 1 个函数 checkCondition
应该根据一些逻辑检查返回真/假。我想将返回值传递到组件下的变量 isMatched
中。我尝试使用 useEffect 然后进行调试。但变量根本没有改变
export function checkCondition(): boolean {
...
}
export default function App() {
const [isMatched, setMatched] = useState(false)
useEffect(()=>{
const aa = checkCondition()
console.log({aa})
setMatched(aa) //get correct expected
console.log({isMatched}) //always false
}, [isMatched])
console.log({isMatched}) //always false
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Edit to see some magic happen!</h2>
</div>
);
}
答案 0 :(得分:1)
我正在浏览您放在此处的代码:
const [isMatched, setMatched] = useState(false)
您已将 isMatched
的初始值设置为 false
。
useEffect(()=>{
...
}, [isMatched])
此处 useEffect
已注册为回调但尚未运行。
console.log({isMatched})
控制台记录 false
,因为 useEffect
尚未运行。
然后呈现 return()
JSX。
现在调用了 useEffect
。
const aa = checkCondition() //aa gets checkCondition value
console.log({aa}) //aa is logged to console
setMatched(aa)//isMatched is set to aa's value, but this update will not happen immediately
console.log({isMatched})//This will output false(since initial value of isMatched is false), setState doesn't update immediately remember?
上面解释的每一行。
现在这个 useEffect
已经被赋予了 deps [isMatched]
,这意味着这段代码会在开始时运行一次,然后每次 isMatched
值改变。现在你为什么要这样做,我不知道,我假设你看到了 lint 警告说 React Hook React.useEffect has a missing dependency: 'isMatched'. Either include it or remove the dependency array. (react-hooks/exhaustive-deps)eslint
并将它放在那里,这是错误的,因为你只将它用于 console.log
。无论哪种方式,现在只要您使用与之前不同的值调用 setMatched(在此循环中,之前的值为 false
),它都会重新运行 useEffect
回调。 >
这意味着如果 checkCondition
输出为 true
,useEffect
将再次运行,如果为 false
则不会。这里不会陷入无限循环,因为布尔值是原始值,因此 false===false
和 true===true
比较都是 true
。如果 checkCondition
输出是一个对象引用,它有可能陷入无限循环,因为 isMatched
依赖项很可能每次都指向不同的引用。
答案 1 :(得分:0)
为了避免评论中的无限循环,请以这种方式更新您的状态,
useEffect(()=>{
const aa = checkCondition()
setMatched(() => aa));
}, [])
答案 2 :(得分:0)
function App(props){
// init update
const [isMatched, setMatched] = useState(props.matched);
//updates through props
useEffect(() => {
setMatched(props.matched);
},[props.matched]);
// update through object
return <div onClick={() => setMatched(true)}>this</div>
}
答案 3 :(得分:0)
const [isMatched, setMatched] = useState(() => checkCondition());
useEffect(()=> {
const matched = checkCondition();
setMatched(matched);
}, [isMatched]);