-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
RTK Query: refetchOnFocus is not working for me in a ReactNative app #3652
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
the same issue even if I added |
On web it works but on mobile its not working |
The current implementation is: if (typeof window !== 'undefined' && window.addEventListener) {
// Handle focus events
window.addEventListener(
'visibilitychange',
handleVisibilityChange,
false
)
window.addEventListener('focus', handleFocus, false)
// Handle connection events
window.addEventListener('online', handleOnline, false)
window.addEventListener('offline', handleOffline, false)
initialized = true
} I genuinely have no idea if that even runs on React Native. Can anyone check and confirm if those events exist in RN? |
Yes, the default implementation of See #1931 We had a PR for documentation for this, but got stuck on the final implementation to put into the docs. |
It would be great if this was supported in React Native. |
@mikemonaco afraid we're not React Native users, and I have no idea how focus gets handled in RN. We'd be open to a PR that improves this, but I don't expect us to try to work on that ourselves. |
@mikemonaco The comment directly above your comment links to a step-by-step solution on how to get this working in React Native. |
My working and tested code to set up listeners in React Native project import NetInfo, {
NetInfoState,
NetInfoSubscription,
} from '@react-native-community/netinfo'
import { ThunkDispatch } from '@reduxjs/toolkit'
import { AppState, AppStateStatus, NativeEventSubscription } from 'react-native'
let initialized = false
let appStateSubscription: NativeEventSubscription | null = null
let appState = AppState.currentState
let netInfoUnsubscribe: NetInfoSubscription | null = null
export function listenHandler(
dispatch: ThunkDispatch<any, any, any>,
{
onFocus,
onFocusLost,
onOffline,
onOnline,
}: {
onFocus: () => void
onFocusLost: () => void
onOffline: () => void
onOnline: () => void
}
) {
const handleFocus = () => dispatch(onFocus())
const handleFocusLost = () => dispatch(onFocusLost())
const handleOnline = () => dispatch(onOnline())
const handleOffline = () => dispatch(onOffline())
const _handleAppStateChange = (nextAppState: AppStateStatus) => {
const foreground = !!(
appState.match(/inactive|background/) && nextAppState === 'active'
)
if (foreground) handleFocus()
else handleFocusLost()
appState = nextAppState
}
const _handleNetInfoChange = (state: NetInfoState) => {
const { isConnected } = state
if (isConnected) handleOnline()
else handleOffline()
}
if (!initialized) {
appStateSubscription = AppState.addEventListener(
'change',
_handleAppStateChange
)
netInfoUnsubscribe = NetInfo.addEventListener(_handleNetInfoChange)
initialized = true
}
const unsubscribe = () => {
if (appStateSubscription) {
appStateSubscription.remove()
appStateSubscription = null
}
if (netInfoUnsubscribe) {
netInfoUnsubscribe()
netInfoUnsubscribe = null
}
initialized = false
}
return unsubscribe
} |
it's work with
|
On react native it doesn't |
Bless your heart, this worked! |
import { ThunkDispatch, createAction } from "@reduxjs/toolkit";
import { addNetworkStateListener } from "expo-network";
import {
Platform,
AppState,
AppStateStatus,
NativeEventSubscription,
} from "react-native";
import { type EventSubscription } from "expo-modules-core";
export const onFocus = createAction("__rtkq/focused");
export const onFocusLost = createAction("__rtkq/unfocused");
export const onOnline = createAction("__rtkq/online");
export const onOffline = createAction("__rtkq/offline");
let initialized: Boolean = false;
export function setupListeners(
dispatch: ThunkDispatch<any, any, any>,
customHandler?: (
dispatch: ThunkDispatch<any, any, any>,
actions: {
onFocus: typeof onFocus;
onFocusLost: typeof onFocusLost;
onOnline: typeof onOnline;
onOffline: typeof onOffline;
}
) => () => void
) {
const mobileDefaultHandler = () => {
const handleFocus = () => dispatch(onFocus());
const handleFocusLost = () => dispatch(onFocusLost());
const handleOnline = () => dispatch(onOnline());
const handleOffline = () => dispatch(onOffline());
let unsubscribeAppState: NativeEventSubscription;
let networkSubscription: EventSubscription;
if (!initialized) {
const handleAppStateChange = (nextAppState: AppStateStatus) => {
if (nextAppState === "active") {
handleFocus();
} else {
handleFocusLost();
}
};
unsubscribeAppState = AppState.addEventListener(
"change",
handleAppStateChange
);
networkSubscription = addNetworkStateListener(
({ type, isConnected, isInternetReachable }) => {
if (isConnected && isInternetReachable) {
handleOnline();
} else {
handleOffline();
}
console.log(
`Network type: ${type}, Connected: ${isConnected}, Internet Reachable: ${isInternetReachable}`
);
}
);
initialized = true;
}
const unsubscribe = () => {
if (unsubscribeAppState) unsubscribeAppState.remove();
if (networkSubscription) networkSubscription.remove();
initialized = false;
};
return unsubscribe;
};
const webDefaultHandler = () => {
const handleFocus = () => dispatch(onFocus());
const handleFocusLost = () => dispatch(onFocusLost());
const handleOnline = () => dispatch(onOnline());
const handleOffline = () => dispatch(onOffline());
const handleVisibilityChange = () => {
if (window.document.visibilityState === "visible") {
handleFocus();
} else {
handleFocusLost();
}
};
if (!initialized) {
if (typeof window !== "undefined" && window.addEventListener) {
// Handle focus events
window.addEventListener(
"visibilitychange",
handleVisibilityChange,
false
);
window.addEventListener("focus", handleFocus, false);
// Handle connection events
window.addEventListener("online", handleOnline, false);
window.addEventListener("offline", handleOffline, false);
initialized = true;
}
}
const unsubscribe = () => {
window.removeEventListener("focus", handleFocus);
window.removeEventListener("visibilitychange", handleVisibilityChange);
window.removeEventListener("online", handleOnline);
window.removeEventListener("offline", handleOffline);
initialized = false;
};
return unsubscribe;
};
return customHandler
? customHandler(dispatch, { onFocus, onFocusLost, onOffline, onOnline })
: Platform.OS === "web"
? webDefaultHandler()
: mobileDefaultHandler();
} |
@WhidRubeld @sleekLancelot where exactly would you set this code? |
https://gist.github.com/WhidRubeld/5dee6e32eb591e7d9bd9f8813017a5eb |
In your store.ts/.js file |
Hi, reading the docs at https://redux-toolkit.js.org/rtk-query/usage/cache-behavior#re-fetching-on-window-focus-with-refetchonfocus
I expect my queries to be refetched when the app is gaining focus again when running in the background for a while...but nothing happens.
What do I miss?
The text was updated successfully, but these errors were encountered: