Updating state values from different screen - react-native

Very new to ReactNative.
Please let me know if I'm doing something unproperly.
On Screen A, I have a interval that handle a REST request and updates my Screen A state and its components.
Working fine so far!
To navigate to Screen B
this.props.navigation.navigate('ScreenB', {state: this.state});
and I'm using that state values to mount ScreenB components.
Even with ScreenB showing, at some point ScreenA interval updates my ScreenA state with new data.
What is the proper way to pass these new data to ScreenB state and update its components?
I thought passing state on navigation props would keep the same object (state) on all screens, but this is apparently wrong.

The best way is to add a common state management library like redux and use it across your screens. Once you have updated the data in one screen, you can dispatch an action to update the store. The page2 which is now showing will consume the change and rerender the new data changes.

Related

How to refresh screen in componentdidmount ( react native )?

I am use bottom navigation, i get value form asyncStorage in componentDidMount but every time i have to hard refresh for new value, when i please first screen to second screen and get new value in first screen but new value is not updated. so how refresh first screen with new value
In bottom navigation the component does not go out of scope. In other words, component does not reload so componentDidMount() won't be called again. Better to use state management like Redux or Mobx. Let them handle the changes instead of reading from asyncStorage. If a Mobx Store gets updated it'll automatically refresh your values wherever you are accessing it.
ComponentDidMount is executed only at the start. So if you want to update data again and again after a specified time you might have to use something like setInterval in componentDidMount or if you want to fetch new data whenever a user clicks on something then you can do that by making a new separate function which would fetch data and update the state.
Whenever you update the state, the component almost instantly rerender.
Try Setting unmountOnBlur to true in navigation options
So every time the screen goes out of focus it is unmounted and when you come back to screen it is mounted again and data will be refreshed
Using unmountOnBlur - Bottom Navigation

React-Native navigation : Share data between components, update params when the state changes

I'm learning React-native and I'm blocking on navigation. before, when I updated a parent (his state), props and children were updating. So it was enough for me to provide the children with the methods to change the state of a parent.
But with the navigation, I don't know how to do it.
The first "page" in the navigation gets the geolocation, which changes all the time, in his state, I want to give this data to the other components which succeed.
This method: this.props.navigation.navigate('RouteName', { /* params go here */ }) is not good for me because it's not dynamic. When the position changes, the other components which succeed don't change. And I want to be able to modify the state of a previous component in the navigation too.
Can you help me?
For that, I think you'll have to use Redux

componentDidMount is not working when redirect to a screen

I am having componentDidMount to list set of files(images) in a screen A, from this screen A I am having another screen B link where I can see detailed view of a file and there I have an option to delete a document.
When screen A is called using
<TouchableOpacity style={Styles.HomeButton} onPress={ () => this.props.navigation.navigate('Gallery')}>
<Text style={Styles.HomeButtonText}>View Photos</Text>
</TouchableOpacity>
componentDidMount working fine, But when I delete a file (i am using react-native-fs) on unlink callback I am calling the navigation like
this.props.navigation.navigate('Gallery');
Which is working fine redirecting to Screen A, but componentDidMount is not working which means I can still see that deleted file in the list.
i.e Screen A is not refreshing, is there any possible solution?
In react-navigation, the component will not unmount if you navigate to other screens unless you reset the stack in stack navigation. So when you come back to the previous screen, as it is already mounted, componentDidMount will not trigger.
You can bind a react navigation event listener to trigger some piece of code when you get back to the screen.
this.focusListner = this.props.navigation.addListener("didFocus",() => {
// Update your data
});
Don't forget to remove event listeners while you unmount the component.
componentWillUnmount() {
// remove event listener
this.focusListner.remove();
}
Possible reason, why your componentDidMount() is not working, is because screen B may be possible a modal.
In the case of modals, the previous component does not unmount, and the next screen just opens upon it. So when you go back to the previous screen, it does not mount again. That's why your list is not updating.
Solution
You have to change the state of the component which is supposed to rerender. The best solution here, and which I also use, is a state management library like Redux. So when you delete the item from screen B, just also update the redux store accordingly. So every component that using that reducer will rerender and you can also save one hit to your server.
You should consider refreshing your list on navigation's didFocus event. Clearly if you are using a stack navigation with A -> B, and once you delete your file from B and goes back to A, provided that A is already in the stack so the didMount wont work when you navigate back.
So, ideally you must refresh your list on the didFocus event of the navigation using some kind of flag set in redux when you delete the file and once you get back to A you read the status of the flag and refresh your list accordingly.
You can refer this to better understand the navigation props and the lifecycle events
You may want to check the NavigationEvents API here : https://reactnavigation.org/docs/en/navigation-events.html .
To solve your problem you want to use the navigation event onDidFocus instead of componentDidMount !
This is a way easier way to than to use the imperative API as it takes care of subscribing and unsubscribing the listeners.

When redux rerenders a view containing a StackNavigator it reset itself to initial screen

I am using react-navigation:
If i change the login property of the redux state when redux rerenders the View my StackLogin resets to initial state (If i am in the SignIn view it goes back to Login). Its like its not maintaining its own state. Maybe its something im missing about this library.
Regards
When the login prop changes, React will re-render your component. To determine what to render, the render() method is executed. Your render() method creates a new StackNavigator every time it is run. Therefore your <StackLogin /> is effectively reset when the prop changes.
What you probably want to do is to define StackLogin outside of the Login class. You certainly want to do it outside of the render() method.

React Navigation and Redux: goBack() doesn't refresh my props

This is a React Native project that includes React Navigation and Redux.
I have two scenes, the first one contains a ListView and a Button to add a new element to the list. This buttons navigates to a new Scene where I fill up a little form to create a new record that will appear on the list of the first scene.
When hitting the save button and going back to the first scene (list view), mapStateToProps reflects the change but no other life cycle method is called (componentWillReceiveProps, shouldComponentUpdate, etc), none of them.
Now, both Scenes use connect from redux and I'm going back from Scene 2 to Scene 1 with the goBack() method from React Navigation. I'm wondering if redux get's "disconnected" from a view when showing a new one and how can I connect it back? Again, the mapStateToProps from the ListView scene is showing the data updated but it seems no props are being mapped.
It just seem the props don't refresh if the redux state value hasn't really change. Copying the list array before modifying it and then assigning it to the payload seems to fix the issue.