英文:
AppState event persists across all app screens even when cleaned
问题
我使用AppState API监听器来在应用程序从后台切换到活动状态时运行函数。我在useEffect清理中删除了它,但它仍然在其他屏幕上被调用,就好像从未被清理过。
const MyRoute = ({ navigation, route }) => {
const appStateRef = useRef(AppState.currentState);
useEffect(() => {
getUserData();
function updateRouteData(nextAppState) {
if (appStateRef.current.match(/inactive|background/) && nextAppState === 'active') {
getRoutes(); // <--
}
appStateRef.current = nextAppState;
}
AppState.addEventListener('change', updateRouteData);
return () => {
AppState.removeEventListener('change', updateRouteData);
};
}, []);
// ...
}
AppState事件监听器仍然存在于其他屏幕上。
react-native版本: "0.64.4"
英文:
I use the AppState API listener to run a function when the app comes from background to active state. I remove it on the useEffect cleanup, but it is still being called on the other screens like it was never cleaned.
const MyRoute = ({ navigation, route }) => {
const appStateRef = useRef(AppState.currentState);
useEffect(() => {
getUserData();
function updateRouteData(nextAppState) {
if (appStateRef.current.match(/inactive|background/) && nextAppState === 'active') {
getRoutes(); // <--
}
appStateRef.current = nextAppState;
}
AppState.addEventListener('change', updateRouteData);
return () => {
AppState.removeEventListener('change', updateRouteData);
};
}, []);
// ...
}
The AppState event listener persists on the other screens.
react-native: "0.64.4"
答案1
得分: 0
将事件监听器存储在变量中,然后移除它。
const appStateListener = AppState.addEventListener();
appStateListener?.remove();
英文:
Get the event listener in a variable and then remove it.
const appStateListener = AppState.addEventListener()
appStateListener?.remove();
答案2
得分: 0
I found a solution.
Instead of calling the appstate logic inside a useEffect, I call it with the useFocusEffect from the react navigation. When leaving the screen you can trigger a cleanup function to remove the listener.
I created a custom hook to use it on my app.
const useAppStateListener = (callback) => {
const appStateRef = useRef(AppState.currentState);
useFocusEffect(
useCallback(() => {
async function updateRouteData(nextAppState) {
if (appStateRef.current.match(/inactive|background/) && nextAppState === 'active') {
await callback();
}
appStateRef.current = nextAppState;
}
AppState.addEventListener('change', updateRouteData);
return () => {
AppState.removeEventListener('change', updateRouteData);
};
}, [callback]),
);
return appStateRef;
};
英文:
I found a solution.
Instead of calling the appstate logic inside a useEffect, I call it with the useFocusEffect from the react navigation. When leaving the screen you can trigger a cleanup function to remove the listener.
I created a custom hook to use it on my app.
const useAppStateListener = (callback) => {
const appStateRef = useRef(AppState.currentState);
useFocusEffect(
useCallback(() => {
async function updateRouteData(nextAppState) {
if (appStateRef.current.match(/inactive|background/) && nextAppState === 'active') {
await callback();
}
appStateRef.current = nextAppState;
}
AppState.addEventListener('change', updateRouteData);
return () => {
AppState.removeEventListener('change', updateRouteData);
};
}, [callback]),
);
return appStateRef;
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论