Javascript 在刷新列表时,Hooks useCallback将继续使用旧值
下面的useCallback有什么问题?我没有在每次调用函数Javascript 在刷新列表时,Hooks useCallback将继续使用旧值,javascript,reactjs,react-native,react-hooks,Javascript,Reactjs,React Native,React Hooks,下面的useCallback有什么问题?我没有在每次调用函数onRefresh时获得下面的值? 如何使用钩子使其返回预期值 调用刷新2x时的示例 期望值: true 0 20 false true 0 20 false 价值:收到 false 0 0 false false 20 20 false 状态变量的初始化 const [refreshing, setRefreshing] = useState(false) const [offsetQuestions, setOffsetQu
onRefresh
时获得下面的值?
如何使用钩子使其返回预期值
调用刷新2x时的示例
期望值:
true
0
20
false
true
0
20
false
价值:收到
false
0
0
false
false
20
20
false
状态变量的初始化
const [refreshing, setRefreshing] = useState(false)
const [offsetQuestions, setOffsetQuestions] = useState(0)
使用useCallback进行函数调用:
const fetchSomeData = async () => {
await new Promise(resolve => setTimeout(resolve, 3000)) // 3 sec
}
const onRefresh = useCallback( async () => {
setRefreshing(true)
setOffsetQuestions(0)
console.log(refreshing)
console.log(offsetQuestions)
await fetchSomeData()
setOffsetQuestions(20)
setRefreshing(false)
console.log(offsetQuestions)
console.log(refreshing)
}, [refreshing, offsetQuestions])
调用函数时:
<FlatList
data={questionsLocal}
refreshing={refreshing}
onRefresh={onRefresh}
...
/>
您得到的是钩子中的预期行为。都是关于闭包的。react中的每个渲染都有自己的道具、状态、函数和事件处理程序,对于特定渲染,它们永远保持不变。所以这里发生的是,useCallback
正在关闭该特定渲染的状态变量,因此,console.log
即使在setState
之后也会始终为您提供特定渲染的状态值,因为闭包您可以使用UseRef钩子使用当前状态值而不是词法值
const ref = useRef();
useEffect(() => {
ref.current = value;
});
这就是如何在引用中设置值并在任何地方使用它的方法
下面是您可以详细了解此问题并提供可能解决方案的链接
谢谢这种情况让许多开始使用钩子的开发人员感到困惑。您可能希望React是被动的,并且在调用setX
后会更改状态的值,但是如果您仔细想想,就不能期望React停止执行流更改状态变量并继续执行
因此,您得到的是创建useCallback
(反复阅读)的范围内的状态变量
让我们将其分解为两部分,范围和useCallback,因为要使用useState
和useCallback
,您必须了解这两个不同的方面
范围:
假设您有一个名为age
的状态,以及一个写入/读取该状态的函数(目前不使用useCallback
)
从中可以看出,每个渲染都定义了一个新的age
变量(如果React给出了该值),还定义了一个新的increaseAge
函数,可以访问保存age
变量的范围
这就是作用域的工作原理,这就是为什么在调用setAge
之后不会得到一个新值age
。为了能够在age
React上获得新值,必须重新渲染组件,因此将在新范围上定义一个新的age
变量。这正是调用setAge
后发生的情况,React将触发新的渲染
useCallback
现在,假设您不想一次又一次地定义increaseAge
函数,您希望保留相同的引用(可以帮助防止无用的渲染)。这是您希望使用useCallback
的地方
使用useCallback
时,React会为每个渲染提供相同的函数引用,除非其中一个依赖项发生更改
如果不向useCallback
提供依赖项,React将不会重新创建函数,函数将访问创建它的作用域(第一次渲染),当向useCallback
提供正确的依赖项时,它将重新创建,现在可以使用最新的状态变量访问作用域
这应该解释为什么必须提供依赖项,以及如何访问状态变量(作用域)。您是否也可以回答问题的第二部分:“如何使用钩子使其返回预期值?”@justdvl正如我上面所说,您从控制台日志中得到的是react钩子中的预期行为,这一切都与闭包有关。相反,请解释为什么在调用setRefreshing
之后,您希望立即获取/读取同一函数中的更新值,我可以帮助您解决这个问题。
const [age, setAge] = useState(42);
const increaseAge = () => {
setAge(age + 1); // this "age" is the same "age" from above
console.log(age); // also this one
}