我在這里有一個簡化的反應原生應用程式,它可以進行網路呼叫并在加載時設定一個標志。有一個按鈕 onPress 處理程式呼叫另一個方法 doSomething,根據 vscode 中的詳盡-deps 插件,useCallback 中的兩個方法和依賴陣列都是正確的。
當應用程式加載時,我可以看到 isInitialized 標志設定為 true,但是之后按下按鈕顯示標志在 doSomething 方法中仍然為 false。在這種情況下,似乎沒有根據它們的依賴陣列重新生成 useCallback 方法。
import React, {useEffect, useState, useCallback} from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
export default function App() {
const [isInitialized, setIsInitialized] = useState(false);
useEffect(() => {
fetch("http://www.google.com").then(() => setIsInitialized(true) );
}, []);
const onPress = useCallback(() => {
doSomething();
}, [doSomething]);
const doSomething = useCallback(() => {
console.log("doSomething", { isInitialized });
}, [isInitialized]);
return (
<View style={{flex:1, justifyContent:"center", alignItems:"center"}}>
{isInitialized &&
<Text>Initialized</Text>
}
<TouchableOpacity onPress={onPress} style={{padding:30, borderWidth:1}}>
<Text>Press Me</Text>
</TouchableOpacity>
</View>
);
}
有人可以解釋為什么會這樣嗎?請注意,陳舊狀態僅在網路呼叫后設定標志時發生,并且僅在使用 useCallback() 的方法之間發生兩次躍點時發生。如果按鈕 onPress 直接設定為 doSomething,則標志正確顯示為 true。
我在整個代碼中都以這種方式使用 useCallback,并且由于不了解這里發生的事情,我害怕在意想不到的地方發現陳舊狀態。
uj5u.com熱心網友回復:
類似的帖子在這里。另請參閱useCallback 上的 React 檔案。
當你在 中封裝一個函式時useCallback,你是在告訴 React 不要更新函式,除非其中一個依賴項發生了變化。但是,更改中的依賴項useCallback不會觸發組件的重新渲染。由于您useEffect沒有依賴項,因此組件將永遠不會使用新值重新渲染。
您有以下代碼:
useEffect(() => {
fetch("http://www.google.com").then(() => setIsInitialized(true) );
}, []);
const onPress = useCallback(() => {
doSomething();
}, [doSomething]);
const doSomething = useCallback(() => {
console.log("doSomething", { isInitialized });
}, [isInitialized]);
這三個函式可以重寫為:
useEffect(() => {
fetch("http://www.google.com").then(() => setIsInitialized(true) );
}, []);
useEffect(() => {
console.log({ isInitialized }):
}, [isInitialized]);
const doSomething = useCallback((isInitialized) => {
console.log("doSomething", { isInitialized });
});
這樣,doSomething將始終有一個新的值傳遞給它。然后,您將像這樣重寫您的 TouchableOpacity:
<TouchableOpacity onPress={() => doSomething(isInitilized)} style={{padding:30, borderWidth:1}}>
...
這樣isInitialized,通過強制在您的 second 中重新渲染組件,可以確保 的最新值useEffect。
我不確定您的用例,但useCallback要小心使用。它的重點是及時凍結一個函式并防止它被重新初始化。僅當您有一個需要大量重新渲染的組件時,這才有價值;如果你只做一個fetch,而且fetch不會發生太多,useCallback會導致比它為你解決的問題更多的問題。
uj5u.com熱心網友回復:
函式doSomething是undefined當您將其作為依賴項傳遞給useCallback 時,因此函式不會隨isInitialized. 將doSomething 的宣告移到onPress之上。到處使用useCallback可能不是最好的主意,但我不知道你的用例,我希望你衡量性能和收益:)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/406374.html
標籤:
