React Navigation - Rerender a component after closing drawer - react-native

There is some way to rerender a component after closing the drawer navigation (from
React-Navigation library)? Like an event or something like that?
Let me explain my problem: I'm not using a drawer navigation only for navigation purposes but also for settings in my app. For that reason, I want to change, for exemple, the language in my app and rerender the component behind the drawer (check the image). How can I achieve this?
Hope you can help me, thank you!

1) - Connect drawer to redux
2) - Dispatch and event when a setting is changed.
3) - Connect the component that needs re-rendering to redux settings state.
If the state is changed the component will automatically be re-rendered.
If you are not using redux you could try MobX or other alternatives:
https://medium.com/#machnicki/why-redux-is-not-so-easy-some-alternatives-24816d5ad22d
Without a proper state management what you want to achieve would probably add many ugly workarounds in the code.

I have done what you want to do with Redux, and I think that it is a good idea to use it.
Having said that, here is some code to know when the drawer is closed:
const defaultGetStateForAction = DrawerStack.router.getStateForAction;
DrawerStack.router.getStateForAction = (action, state) => {
switch (action.type) {
case "Navigation/DRAWER_CLOSED":
// Drawer is closing code goes here...
break;
}
return defaultGetStateForAction(action, state);
};

Related

How to add redux selector state to useStack hook when moving back to original screen. react-native

First-of-all I apologise because I'm new to this concept of redux haha so bare with me here :)
I have implemented a very simple redux in my app
I have one screen here ListAnItem
Here there is a button.
Add size when pressing this they get navigated to another screen called SizeSelector
SizeSelector
here there is a button called dispatch size when they press this button it runs the following.
dispatch({type: "ADD_SIZE", payload: size })
this works perfectly with useSelector.
once this dispatch has been run I use navigation.goBack() to send the user back to the ListAnItem screen.
but once they come to this screen I want to add this useSelector redux state value to a useState hook something like this;
const [sizeState, setSizeState] = React.useState(null)
how can I change this state the minute something has been added to useSelector value of ADD_SIZE.
if that makes sense 😂.
Thanks,
Arnav.

How to pass params in React Native Navigation for the goBack() function

I know this is a stupid question.
I have a component lets call it Component that is used in several screens for Example Screen1,Screen2,...
And in the Component I am navigating to a new Screen when the user click a button, lets call it ImagePicker.
my Question is how do I go back and pass a parameter( in this case image data) and get it back in the Component
I tried using navigation.goBack({img: image}) but that didn't work. I also can't use navigation.navigate('Screen') since my functions are in the Component component.
So what is the best solution for my problem ?
We cannot pass any params to the goBack method.
If we have to do so then, we can use the navigate method to navigate to the back screen, and using this method we can pass the params to the previous screen.
For ex.
navigation.navigate('PrevScreenName', {key: value})
Check out the official docs for the react-navigation.
React Navigation
If I understand your problem well, just do
navigation.navigate('Screen', {img: image})
instead of navigation.goBack({img: image}) and it should work
In the component code, I would pass along a callback function to the image picker screen
handleImageData = (data) =>
{
// do whatever
}
...
navigation.navigate('ImagePickerScreen',{mycallback:this.handleImageData});
and then in the screen code just call it like
this.props.route.params.mycallback(data);
navigation.goBack();

Set state to initial state in react native

I would like to know if it's possible to set the state to the initial state values whenever we press back the button in the tabBar ? At the moment, when I leave the tabBar and come back after a few navigation in the app, the infos that the user enter in TextField persist.
Thanks !
You could use React hooks to achieve similar results to lifecycle methods in class functions.
The useEffect method runs on component render. You can set the state in there.
const [currentState, setCurrentState] = useState(null);
useEffect(()=>{
// This will run after 1st render
setCurrentState("");
},[]);

react-navigation Infinite loop inside componentWillReceiveProps

I Have 2 components, component a and component b
I want to navigate from component a to component b after changing a state.
When i change state, it triggers my componentWillReceiveProps function and i am navigation from there.
componentWillReceiveProps(nextProps) {
const { navigate } = nextProps.navigation;
navigate('b');
}
Now i got in an infinite loop, it starts triggering componentWillReceiveProps again and again instead of navigating
Help needed.
If you don't need compare current this.props and nextProps, you better trigger navigate action in somewhere else.
This link might also help you: https://facebook.github.io/react/docs/react-component.html#the-component-lifecycle

react native route flux re-render component on stack pop

How do you re-run React Component Lifecycle methods to determine if a re-render is necessary when transitioning back to previous screens from stack using React Native Router Flux?
Scenario: Scene A -> B -> A
Lets say, A is the initial scene and we navigate from A to B with a push i.e Actions.SceneB. From B to A with a Pop. When the stack is popped to show Scene-A, none of the React Component methods are called for Scene-A. How do I determine if a re-render is necessary? I searched the Issues listed on the github repo and many seems to have this problem without a solution. How is this problem addressed?
I have the ugly work around of calling Actions.refresh() with a setTimeout.
Work Around that works!
This workaround seems to be hacky. There must be a better way to hook into component lifecycle to determine if a re-render is required. Perhaps a callback into the Component?
<TouchableHighlight underlayColor='#efefef' onPress={() => { Actions.pop(); setTimeout(()=> Actions.refresh(), 500)}} style={styles.cancel}>
Options that do not work
Actions.pop({type: 'reset'})
OR
Actions.refresh({"key" : "sceneA"})
Work Around that works! This workaround seems to be hacky. There must be a better way to hook into component lifecycle to determine if a re-render is required.
<TouchableHighlight underlayColor='#efefef' onPress={() => { Actions.pop(); setTimeout(()=> Actions.refresh(), 500)}} style={styles.cancel}>
This will call shouldComponentUpdate() method which gives an option to determine, if a re-render is required.
I was facing the same issue below code gave me required result.
let count = 0;
moveToMainScreen = () => {
count += 1;
Actions.pop({ refresh: { test: count } });
};
<Button onPress={this.moveToMainScreen}> Click </Button>