- Normally, when a variable depends on its’ previous state, the recommended way is to do setVarA(varA => varA + 1) instead
- setState callback equivilent in hooks? Just use
useEffectwith concerned state data. - call hooks only at top level, making sure all the hooks are called with the same order every render. Otherwise, bugs arise. If you have conditional hooks, move the condition into a top level hook.
useEffect入参是匿名函数,即,每次render都创建一个新的effect方法,如果此方法返回一个函数,则在每次新render时,即上一次render被销毁时,该返回函数会被调用,负责一些清理工作。compare these two way of coding:
function App() {const [varA, setVarA] = useState(0);useEffect(() => {let timeout;if (varA < 5) {timeout = setTimeout(() => setVarA(varA + 1), 1000);}return () => clearTimeout(timeout);}, [varA]);return <span>Var A: {varA}</span>;}
vs:
function App() {const [varA, setVarA] = useState(0);useEffect(() => {if (varA >= 5) return;const timeout = setTimeout(() => setVarA(varA + 1), 1000);return () => clearTimeout(timeout);}, [varA]);return <span>Var A: {varA}</span>;}
the difference is that in the upper way, clearTimeout is run even when setTimeout is conditionally passed. So the later one is better.
useCallback
在函数组件中,所有定义的代码都会在每次render时重新执行一遍,比如定义一个handler,则每次render时都会重新执行并生成一个新的函数,而useCallback的作用,可以将这种handler函数缓存起来,在每次render时,不用再重新创建,从而有一定的性能优化。
但使用时要小心
What do you think of the two approaches below:
const handlePreviewClick = useCallback(() => {console.log('-----------------', colorVal, tz, activeType);if (!checkColorValue(colorVal)) {message.error('You must input a vaild color value');} else if (!validateTime()) { // do something with tz, activeType, activeFrommessage.error('You must set time and timezone value');} else {setmode(UploadMode.PREVIEW);}}, [colorVal, tz, activeFrom, activeType]);
vs
const handlePreviewClick = useCallback(() => {console.log('-----------------', colorVal, tz, activeType);if (!checkColorValue(colorVal)) {message.error('You must input a vaild color value');} else if (!validateTime()) { // do something with tz, activeType, activeFrommessage.error('You must set time and timezone value');} else {setmode(UploadMode.PREVIEW);}}, [colorVal]);
在handler中使用到的state、props等变量,需要全部声明在deps数组中,否则,会拿不到最新数据,从而导致bug。
