我有个简单的密码,
onClick -> doSomething() -> testFunction()
doSomething()是一个useCallback函数,它调用另一个useCallback函数testFunction()
由于首先声明了doSomething(),然后声明了testFunction(),所以当调用doSomething()时,testFunction()会变得陈旧。
doSomething()不应该引用最新的testFunction(),因为我添加了[testFunction]作为它的依赖项?
https://codesandbox.io/s/react-hooks-counter-demo-forked-18gpk?file=/src/index.js
/**
* To simulate, click on Increment until the count is 2,
* and click on Testbutton which console.log(count) and the value is 0.
* Even though the count value is > 0, 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);
let testFunction;
const doSomething = useCallback(() => {
// Do something else here
testFunction();
}, [testFunction]);
testFunction = useCallback(() => {
console.log("count", count); // stale count value
}, [count]);
return (
<div className="App">
<h1>
Click increment button until count is 2, then click TestButton and see
console log
</h1>
<h2>You clicked {count} times!</h2>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={doSomething}>TestButton</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);临时解决方案:
[count]作为doSomething()的依赖项解决了问题,但它会提示错误React有一个不必要的依赖项:'count‘。要么排除它,要么删除依赖数组Reacti-钩子/详尽-deps。
testFunction()移动到doSomething()上方, const testFunction = useCallback(() => {
console.log("count", count); // no more stale
}, [count]);
const doSomething = useCallback(() => {
// Do something else here
testFunction();
}, [testFunction]);因此,当屏幕重新呈现testFunction (运行第一次)时将得到一个新的引用,而运行第二次的doSomething将得到一个新的testFunction引用。然而,函数声明的顺序应该不重要,因为我知道函数正在被提升?
发布于 2021-08-03 08:52:31
当代码到达第一个testFunction时,不会定义useCallback。因此,doSomething的依赖数组实际上是[undefined]。因此,第一个useCallback调用在第一个呈现之后不再更新的陈旧testFunction。
正如您已经说过的,将testFunction移到doSomething之上解决了这个问题。
关于依赖数组,ESlint实际上是正确的。count对于doSomething来说是不必要的,因为您没有直接使用它。如果您正确地添加了doSomething的依赖项之一,testFunction将在doSomething更新后立即更新。我不知道为什么您认为更改它们的顺序会破坏init代码约定。
发布于 2021-08-04 10:14:47
我对执行no-use-before-define规则犹豫不决,因为它与将StyleSheet放在https://reactnative.dev/docs/stylesheet底部的共同惯例相冲突(甚至官方的反应渠道也遵循它)。
我遇到的解决这个问题的链接是:(不知道为什么会起作用)
"no-use-before-define": ["error", { functions: false, classes: false, variables: false }],

https://stackoverflow.com/questions/68632458
复制相似问题