how can i add event on pressing tab bar in react native? - react-native

I have a react native app in which i am using react navigation v3. I want to create an event on pressing a particular tab bar. On my home tab bar i have a barcode scanner. When the user scans, the app directs to different tab with the barcode data setting the data to async storage.But when i try to scan again it goes blank.
So, i want to create an event on which i can clear the async storage when the user goes to home tab to scan again. How can i add that event on home tab bar?

Try below code it will help you,
import {NavigationEvents} from "react-navigation";
<NavigationEvents
onWillFocus={payload => console.log('will focus',payload)}
onDidFocus={payload => console.log('did focus',payload)}
onWillBlur={payload => console.log('will blur',payload)}
onDidBlur={payload => console.log('did blur',payload)}
/>
NavigationEvents component you can added in your render method of page where you want to track event of users, and handle like AsyncStorage and whatever action you want.
Only add one event if you don't need all
For more detail you may visit here
Thank you

You could listeners to the navigation lifecycle events.
It is fairly straight forward to set up. Here is an example of how to set it up in your screen.
import React, {Component} from 'react';
import { View, StyleSheet, Text } from 'react-native';
export default class Screen2 extends React.Component {
// willFocus - the screen will focus
// didFocus - the screen focused (if there was a transition, the transition completed)
// willBlur - the screen will be unfocused
// didBlur - the screen unfocused (if there was a transition, the transition completed)
componentDidMount () {
// add listener
this.willFocusSubscription = this.props.navigation.addListener('willFocus', this.willFocusAction);
this.didFocusSubscription = this.props.navigation.addListener('didFocus', this.didFocusAction);
this.willBlurSubscription = this.props.navigation.addListener('willBlur', this.willBlurAction);
this.didBlurSubscription = this.props.navigation.addListener('didBlur', this.didBlurAction);
}
componentWillUmount () {
// remove listener
this.willFocusSubscription.remove()
this.didFocusSubscription.remove();
this.willBlurSubscription.remove();
this.didBlurSubscription.remove();
}
willBlurAction = () => {
console.log('willBlur Screen', new Date().getTime())
}
didBlurAction = () => {
console.log('didBlur Screen', new Date().getTime());
}
didFocusAction = () => {
console.log('didFocus Screen', new Date().getTime());
}
willFocusAction = () => {
console.log('willFocus Screen', new Date().getTime());
}
render() {
return (
<View style={styles.container}>
<Text>Screen</Text>
</View>
)
}
}
You don't need to add all the listeners, only the ones that you require.
Most likely you will want to clear your value from AsyncStorage inside the willFocus event. That way it occurs before the screen has come into focus.

Related

How do I update react-native component, when click on tab on bottom Tab Navigator

I am using bottom tab navigator in React-native for Navigation. When I switches tab, component are not updating.
Pls let me know how can I update/refresh whole component when I tap on tab at bottom Tab Navigator
Here is a simple solution.
import { useFocusEffect } from '#react-navigation/native';
useFocusEffect(
React.useCallback(() => {
console.log("Function Call on TAb change")
}, [])
);
Here is the link you can read more. https://reactnavigation.org/docs/function-after-focusing-screen/
You can use Navigation listener check Navigation Events, when screen gets focused it will trigger a function like this:
useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
//Your refresh code gets here
});
return () => {
unsubscribe();
};
}, [navigation]);
And class component like this:
componentDidMount() {
this._unsubscribe = navigation.addListener('focus', () => {
//Your refresh code gets here
});
}
componentWillUnmount() {
this._unsubscribe();
}
If you want to force update check this question

How to prevent Back Button from hiding my keyboard in my react native app?

So I have a simple input, When I focus on it, the keybord pops up, but I want that my keybord hide only if If click on ok, or Enter, But what I see is that when I click the 'BACK' button of my phone, the keyboard disappear, and I don't want that, or at least I want to detect it in my component.
This is how I handle the back click in my app ! Knowing that I have three screens in my app, authentication screen ( LOGIN ), main screen ( MAIN ) , and route screen ( ROUTE ).
import { BackHandler } from 'react-native';
import { prevScreen } from '../../helpers/NavigationService';
import { SCREENKEYS } from '../../business/constants';
import { useEffect } from 'react';
const useBackAction = screen => {
useEffect(() => {
const backAction = () => {
if (screen === SCREENKEYS.LOGIN) BackHandler.exitApp();
else if (screen === SCREENKEYS.MAIN) return true;
else prevScreen();
return true;
};
const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction);
return () => backHandler.remove();
}, [screen]);
};
export default useBackAction;
Is there something I have to add to prevent the back click from hiding mu keybord view ?

How do we implement Scroll to top functionality on tapping of the corresponding tab button on a bottom tab navigator in react navigation?

The React Navigation version I am using is v5. In the ScrollView corresponding to a Bottom Tab Icon, if the user is already on that given screen, I want to enable functionality where the user scrolls to the top when this icon is pressed.
As stated in the documentation, this feature should be already implemented. But I think you have placed your ScrollView inside a nested StackNavigator, right?
In that case, you probably need to subscribe to TabNavigator event and fire your scrollToTop manually
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabPress', e => {
// Get your scrollView ref and dispatch scrollToTop
});
return unsubscribe;
}, [navigation]);
Hope it'll help you!
None of the solutions worked for me on the web, not using listener and not using useScrollToTop which is provided by react-navigation. Because I have nested stacks and navigators and also custom tabbar.
I solved the problem by setting a navigation param for scrolling to the top.
I have custom tabbar, and I needed to scroll to top on the homepage which was the first route of the tab stack.
So, in the homepage I set the scrollToTop parameter for the navigator:
const homelistRef = React.useRef<FlatList | null>(null)
useFocusEffect(
useCallback(() => {
navigation.setParams({
scrollToTop: () => homelistRef.current?.scrollToOffset({ offset: 0, animated: true }),
});
}, [navigation, homelistRef]),
);
return (
<FlatList
ref={homelistRef}
...{other Flatlist configs}
/>
)
And in my Tabbar component, I read this new param and execute it in the onPress function of the tabs:
interface IProps extends BottomTabBarProps {}
const TabBar: React.FC<IProps> = ({ state, navigation }) => {
const handleTabPress = useCallback(
(route) => async () => {
const currentRoute = state.routes?.[state.index];
if (
route === currentRoute?.name &&
state.routes?.[0].state?.routes?.[0]?.params?.scrollToTop
) {
state.routes[0].state.routes[0].params.scrollToTop();
}
},
[navigation, state],
);
return (
{render tab component}
)
}
And that's the ultimate solution for executing some action on active tabs.

How to replicate onDidBlur or onWillBlur with React Navigation 5?

As they point out in the docs, they've gotten rid of the 4 navigation event listeners and instead decided to use Lifecycle events.
But the problem I'm running into with React Navigation 5 is that the blur event doesn't work as I need it to! Before, I could add an onWillBlur listener, and do stuff when the user temporarily leaves (not closes) the app (such as close a socket connection, and then reopen it when the user reenters the app).
How can I replicate the onWillBlur or onDidBlur events for such a use case? I don't need to know if Screen A is blurred after the user is taken to Screen B after clicking a button.
You can use the hook useFocusEffect.
Documentation here
EDIT:
Added example from React Navigation.
import { useFocusEffect } from '#react-navigation/native';
function Profile() {
useFocusEffect(
React.useCallback(() => {
// Do something when the screen is focused, onFocus
return () => {
// Do something when the screen is unfocused, onBlur
// Useful for cleanup functions
};
}, [])
);
return <ProfileContent />;
}
EDIT 2:
I didn't test it on home button but I found a post that helps with that too
Check here
I hope this time you are pleased with my answer.
And here you have a working example :
import React from 'react'
import { Text, AppState } from 'react-native'
const MyComponent = () => {
const [appState, setAppState] = React.useState(AppState.currentState)
React.useEffect(() => {
AppState.addEventListener('change', handleChanges)
setAppState(AppState.currentState)
return AppState.removeEventListener('change')
},[])
const handleChanges = (nextAppState) => {
if (appState.match(/inactive|background/) && nextAppState === 'active') {
console.log('App has come to the foreground!');
} else {
console.log('App has gone to the background!');
// start your background task here
}
setAppState(nextAppState)
}
return <Text>{appState}</Text>
}

React native not refresh screens when navigate navigation drawer

I develop a app use navigation drawer.that navigate screens use navigation drawer.but that screens are not refresh when navigate.how i fix this
Add the following code in your componentDidMount()
componentDidMount() {
this.subs = this.props.navigation.addListener("didFocus", () => {
//Your logic, this listener will call when you open the class every time }
);
}
And don't remember to remove listener in componentWillUnmount(),
componentWillUnmount() {
this.subs.remove();
}