如何在 useEffect 下设置 useState 变量?

时间:2021-06-29 02:42:53

标签: reactjs typescript react-hooks

我有 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>
  );
}

4 个答案:

答案 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 输出为 trueuseEffect 将再次运行,如果为 false 则不会。这里不会陷入无限循环,因为布尔值是原始值,因此 false===falsetrue===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]);