【发布时间】:2021-10-08 16:01:40
【问题描述】:
useCallback 函数声明的顺序重要吗?例如:
按此顺序声明的函数:
-
const aboveFunction = useCallback(()=>{ logCount() },[logCount]) -
const logCount = useCallback(()=>{ console.log(count) },[count]) -
const belowFunction = useCallback(()=>{ logCount() },[logCount])
注意aboveFunction 和belowFunction 指的是同一个logCount。
在我们调用setCount(2)之后,
aboveFunction() -> logCount() -> count // 0,在哪里
belowFunction() -> logCount() -> count // 2
https://codesandbox.io/s/react-hooks-counter-demo-forked-7mofy?file=/src/index.js
/**
Click increment button until count is 2, then click
Above and Below button and check console log
* Even though the count value is > 0, aboveIncrement console.log(count) still gives 0
*/
import React, { useState, useCallback } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [count, setCount] = useState(0);
/** Assuming all the functions below do some intensive stuffs to justify useCallback */
const aboveFunction = useCallback(() => {
// ...do other intensive stuff
logCount("Above count:"); // Above count: 0
}, [logCount]);
const logCount = useCallback(
(str) => {
// ...do other intensive stuff
console.log(str, count);
},
[count]
);
const belowFunction = useCallback(() => {
// ...do other intensive stuff
logCount("Below count:"); // Above count: 2
}, [logCount]);
return (
<div className="App">
<h1>
Click increment button until count is 2, then click Above/ Below button
and see console log
</h1>
<h2>You clicked {count} times!</h2>
<div
style={{
display: "flex",
alignItems: "center",
flexDirection: "column"
}}
>
<button style={{ margin: 10 }} onClick={aboveFunction}>
Above Increment Function
</button>
<button style={{ margin: 10 }} onClick={() => setCount(count + 1)}>
Increment
</button>
<button style={{ margin: 10 }} onClick={belowFunction}>
Below Increment Function
</button>
</div>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
很明显,useCallback 声明的顺序对于代码的工作很重要。但是,如果我们这样写 https://codesandbox.io/s/react-hooks-counter-demo-forked-7mofy?file=/src/index1.js
let logCount;
const aboveFunction = useCallback(() => {
logCount("Above count:"); // Above count: 0
}, [logCount]);
logCount = useCallback((str) => {
console.log(str, count);
}, [count]
);
const belowFunction = useCallback(() => {
logCount("Below count:"); // Above count: 2
}, [logCount]);
aboveFunction 仍然给出过时的计数值。有没有我遗漏的规则?
是的,这里的解决方法是应用 eslint no-use-before-define。但我想了解为什么 .. 函数在 JavaScript 中没有被提升并且声明的顺序并不重要?
【问题讨论】:
-
“假设下面的所有函数都做了一些密集的工作来证明 useCallback 的合理性” useCallback 不会改变任何关于“密集的工作”的东西。我会说,只需删除该代码中的
useCallback()s,但我不明白您到底想要实现什么/为什么首先将它们放在那里
标签: reactjs react-hooks