在探索该问题时引出的新问题:
- 【原问题】什么时候需要将变量放入state?https://dev.to/colocodes/5-use-cases-of-the-usestate-reactjs-hook-4n00
- useEffect因为异步而带来的缺陷,阅读https://juejin.cn/post/6844903799098703880
- 什么情况下,函数组件会陷入无限循环?https://bobbyhadz.com/blog/react-too-many-re-renders-react-limits-the-number
- 为什么函数组件会渲染两次?https://blog.youkuaiyun.com/swallowblank/article/details/126491748
变量命名的位置
- 普通变量在函数组件之外
let count = 1;
export default Home (props) {...}
- 普通变量在函数组件之内
export default Home (props) {
let count = 1;
...
}
- 放在state之内
普通变量在函数组件之外
当props或state改变,触发rerender时,这个变量 test
依然不改变——一直是 false
(不会初始化),即使是父组件重新渲染,子组件中的这种变量依然不会刷新,log
只会触发一次。
import { useState } from "react";
let test = true;
export default function App() {
const [state, setState] = useState("hello");
if (test === true) {
console.log("test", test);
test = false;
}
return (
<div className="App">
<button onClick={() => setState(Math.random())}>
click
</button>
</div>
);
}
普通变量在函数组件之内
当props或state改变,触发rerender时,相当于会重新执行一遍这个函数,所以这个函数中定义的局部变量也会初始化,因此下面代码中,按下按钮后会触发 setState
导致重渲染,每次的 test
都会重置为 true
,因此每次都会触发 log("test", test)
。
import { useState } from "react";
export default function App() {
let test = true;
const [state, setState] = useState("hello");
if (test === true) {
console.log("test", test);
test = false;
}
return (
<div className="App">
<button onClick={() => setState(Math.random())}>
click
</button>
</div>
);
}
放在state之内
这就不必多说了
什么场景下适合用state?
官网是这么介绍state的:通常,当函数退出时,变量“消失”,但是state变量由 React 保留。因此,通俗的说,当触发组件的rerender之后,仍需保留的值应该放入State内。
在我完全理解这个问题之前,先看一下哪些情况使用state是合适的。
- State management (重渲染后需要保留的变量)
- Conditional rendering
- Toggle flags (true/false)
- Get API data and store it in state
Conditional rendering
需要利用状态来判断是否渲染某个组件,其实原理和前者一致。
const [condition, setCondition] = useState(false);
const clickHandler = () => {
setCondition(true);
};
return (
<button onClick={clickHandler}>Set condition</button>
{condition && <p>Hello!</p>}
);
假设使用局部变量:
let condition = false;
const clickHandler = () => {
condition = true;
};
return (
<button onClick={clickHandler}>Set condition</button>
{condition && <p>Hello!</p>}
);
当组件重渲染时,condition = false
会首先被执行,那么需要再次点击按钮重新展示。
Toggle flags
和前者相似。
Get API data and store it in state
一般使用api请求的数据需要保存在state中。