-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Add setupListeners example for react-native #1931
base: master
Are you sure you want to change the base?
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit d818363:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea documenting that!
But I think instead of defining a new setupListenersReactNative
, we should probably show calling setupListeners
with the callback instead.
Could you please test the following code and if it works update the PR accordingly?
import NetInfo from '@react-native-community/netinfo'
import { AppState } from 'react-native'
let initialized = false;
setupListeners(
store.dispatch,
(dispatch, { onFocus, onFocusLost, onOnline, onOffline }) => {
let unsubscribeOnChange: NativeEventSubscription | undefined
let unsubscribeOnNetworkStatusChange: NetInfoSubscription | undefined
if (!initialized) {
// Handle focus events
unsubscribeOnChange = AppState.addEventListener('change', (state) => {
if (state === 'active') {
dispatch(onFocus())
} else if (state === 'background') {
dispatch(onFocusLost())
}
})
// Handle connection events
unsubscribeOnNetworkStatusChange = NetInfo.addEventListener((state) => {
if (state.isConnected) {
dispatch(onOnline())
} else {
dispatch(onOffline())
}
})
initialized = true
}
const unsubscribe = () => {
unsubscribeOnChange?.remove()
unsubscribeOnNetworkStatusChange?.()
initialized = false
}
return unsubscribe
}
)
I don't quite love that this signature requires the entirety of this function to either be defined in the same file as your store setup or called as a side-effect of importing it. This is my current solution to those concerns, but feel free to give more feedback; you have more experience with teaching best practices. export const setupListenersReactNative = (
dispatch: ThunkDispatch<any, any, any>
) => {
let initialized = false;
return setupListeners(
dispatch,
(dispatch, { onFocus, onFocusLost, onOnline, onOffline }) => {
let unsubscribeOnChange: NativeEventSubscription | undefined;
let unsubscribeOnNetworkStatusChange: NetInfoSubscription | undefined;
if (!initialized) {
// Handle focus events
unsubscribeOnChange = AppState.addEventListener("change", (state) => {
if (state === "active") {
dispatch(onFocus());
} else if (state === "background") {
dispatch(onFocusLost());
}
});
// Handle connection events
unsubscribeOnNetworkStatusChange = NetInfo.addEventListener((state) => {
if (state.isConnected) {
dispatch(onOnline());
} else {
dispatch(onOffline());
}
});
initialized = true;
}
const unsubscribe = () => {
unsubscribeOnChange?.remove();
unsubscribeOnNetworkStatusChange?.();
initialized = false;
};
return unsubscribe;
}
);
}; |
Well, that is how the existing Of course people can wrap that all they want in the end to accomodate for their code style/architecture, but the most basic thing here is that you should always call the existing |
We could split it up another way a bit, but I'm not sure from the back of my head how that would play with TS: import NetInfo from '@react-native-community/netinfo'
import { AppState } from 'react-native'
let initialized = false;
export const RNListeners = (dispatch, { onFocus, onFocusLost, onOnline, onOffline }) => {
let unsubscribeOnChange: NativeEventSubscription | undefined
let unsubscribeOnNetworkStatusChange: NetInfoSubscription | undefined
if (!initialized) {
// Handle focus events
unsubscribeOnChange = AppState.addEventListener('change', (state) => {
if (state === 'active') {
dispatch(onFocus())
} else if (state === 'background') {
dispatch(onFocusLost())
}
})
// Handle connection events
unsubscribeOnNetworkStatusChange = NetInfo.addEventListener((state) => {
if (state.isConnected) {
dispatch(onOnline())
} else {
dispatch(onOffline())
}
})
initialized = true
}
const unsubscribe = () => {
unsubscribeOnChange?.remove()
unsubscribeOnNetworkStatusChange?.()
initialized = false
}
return unsubscribe
}
// potentially in another file
setupListeners(
store.dispatch,
RNListeners
) |
Seems it's cause infinity query loop on Android.
|
Are you using |
Hello, I found a similar issue in the "facebook/react-native" repo but it's still open without a solution Any advice will be highly appreciated |
I'm sorry but if this is a RN thing I don't think we can really help with that. |
Hi @msutkowski, is there any update on this? Would be nice to get this into the official docs:) |
Thanks worked for me🙏 import { ThunkDispatch } from '@reduxjs/toolkit'; type Dispatch = ThunkDispatch<any, any, any>; let initialized = false; export const RNListeners = ( //called from another file: import { setupListeners } from '@reduxjs/toolkit/query'; setupListeners(store.dispatch, RNListeners); |
This worked for me in react-native with typescript
and then use this with
|
Does this work with |
I recently had to create this for myself when experimenting with rtk-query in a react-native project.
I figured this could be useful for somebody else.