How to reset the navigation state properly? - react-native

So basically here's what's going on, I have two navigation flows:
Products flow: I have a StackNavigator with two screens, the first rendering a list of all products in the stock, clicking on one product item would take you to the details screen as expected.
Admin flow: I have another StackNavigator where I'm rendering user products, basically the products that were added by the user (admin) into the stock, he can also add new products, delete, edit existing products. Any changes made by the user to his own products will be reflected in the products flow also since the global state will be updated.
Note: The two flows are conntected and accessible using a DrawerNavigator.
My issue
When the user opens the details screen after clicking on one of his own products and then navigates to the admin flow and deletes that product, I get an on error in the details screen because it's trying to render a javascript object that doesn't exist anymore which of course makes perfect sense.
My solution
So I figured since this error occurs only when the details screen has been already opened, meaning it's already in the navigation state's history, Im attempting to solve the problem by checking if the details screen is present in the routes array each time the delete button is clicked, if it's present, meaning the screen is loaded in memory, I try resetting the navigation state by keeping the previous state as it is and simply filtering out the details screen from the previous routes array and setting the new array as the new routes property.
Here's the code that attempts to reset the navigation state each time the delete button is clicked
navigation.dispatch(state => {
const routes = state.routes.filter(
route => route.name !== 'ProductDetail',
);
return CommonActions.reset({
...state,
routes: routes,
});
});
The problem is when I click on the delete button I get the following error
TypeError: undefined is not an object (evaluating 'action.target')
So where am I missing something? Any insight at all would be much apperciated.

Related

VueJS2: Drop down menus and navigating away: If user returns to menu, how to pre-select the option he had chosen?

I have a form with a dropdown list of country options like so:
When the user selects an option, the form will load some data from an API so the user can make changes. However, some parts of the form have some deeply nested components where the user can edit additional data on a separate page. The problem is that when the user changes navigation and then clicks the back button on the browser, the drop down list is 'reset' and he has to select again the country that he was editing.
Can someone suggest a way to handle this issue so that if user clicks the back button on his browser (or the page has a "back to results link"), he will go back to the form and it will already be pre-selected with his option?
Should I be handling this via $route.query, localstorage, vuex? I would prefer not to use Vuex but I guess I can if needed.
Is $router query all i need here? I can capture the country's id and run the API call again on navigation back to the drop down selection page?
Example data from API:
{
id: 1,
name: 'Afghanistan'
}
When user selects a country from menu, I run an API get request like so:
async setSelectedCountryObj(value) {
if (value) {
const response = await APIService.tempISOCountryById(value.code)
....snip...
it's possible to handle with router, but that not a good way, you should go with vuex, that best way, just create store, and dispatch after select value, and always get value when come on that component, that essay not that much difficult, let me know if you need but i know you can.

Route do not been cleaned when unmountOnBlur

I have an application that pass an order from the screen 1 as a param utilizing this.props.navigation.navigate('Screen',{order}) to the screen 2 and do some stuff in the screen 2. Then I navigate to another screen using the Drawer side menu. When I come back to the screen 2 utilizing the drawer menu the order still in the param (the route was not reseted).
I'm using class Component in my project and when I tried to put something like a reset in the componentWillUnmount, but the react native don't let me do that because this would be a asyncronous call.
In my order class I did (Screen 2):
componentWillUnmout() {
// some code
this.props.navigation.reset();
}
In the Screen 1 I did:
this.props.navigation.navigate('Screen 2', {order});
I tried do what was decribed in this question: https://github.com/react-navigation/react-navigation/issues/6915 but I had no sucess.
How could I reset this params in this conditions? Could I made a listener to reset the route when a navigate to another page in the Drawer Menu?
If your second page is an order details, you better use the stack pile of screens by pushing a new one.
this.props.navigation.push('orderDetails', {order});
Like that, you push a screen at the top of the stack. Navigate function search in your route history and if the screen was already open previously, it came back to it.

Navigating in the same scene with different props

I'm learning react-native with redux and I'm trying to make a kind of social network application.
My problem is: when I'm on a user-1 profile screen and I navigate to user-2 profile, so basically I navigate from Profile.js to Profile.js (same screen) with different props. The problem is when I press the 'back' button, I get the user-2 profile while I should see user-1 profile.
The profile informations are saved in the store with redux.
For navigation I use Actions.sceneKey() from react-native-router-flux.
I already tried :
this.props.navigation.navigate('profile', { key: someRandomKey });
I get "Promise returned from navigate is ignored".
T also tried to save every user profile informations that I visit in an array but I don't know how to manipulate this array when I press back button...

Data from Redux Store doesn't reset after change Screen Component

I have a problem with reset redux store data. I have Register component when I click signup button then I get errors and record them in store, then I draw under the inputs.
Now, if I back to Login screen and then go back again to Register screen the errors still shown but I don't want to see them.
How I can solve this problem? I understand that I need to set initial state every time when I go to a screen. I tried to set initial state to createStore but it doesn't work. Also I use Redux Observable's Epics.

Saving state on back button press in vue-electron

I want to make a desktop app in vue-electron. I am new to both vue.js and electron.
I am having some problems while managing state.
When I click on login button https://cloudup.com/cFl9MTY6cnn I send data i.e sessionId and username to next screen https://cloudup.com/c76fmL8OGbF and on this screen I display these props https://cloudup.com/csahnc6Z04J using this code https://cloudup.com/cdR0F6Qyt-3 but as I go to the third screen https://cloudup.com/c0F1ztX8qu3 and then come back then this data disappears https://cloudup.com/cTFW32DxeRa
I am going back to second screen using router.go(-1) https://cloudup.com/cvpxk4GsIRx
The vue-router documentation https://router.vuejs.org/en/essentials/navigation.html says that
“router.push method pushes a new entry into the history stack, so when the user clicks the browser back button they will be taken to the previous URL.”
and router.go(n) "This method takes a single integer as parameter that indicates by how many steps to go forwards or go backwards in the history stack"
However in my case, lifecycle hooks are called again when I go back to history stack. So does that mean when we come to previous page that component is created again and not popped from stack. I actually don’t want to refresh / reload the page on back button.
You need to send the data to the third screen,too.
Instead of
<route-link to="third_screen"></router-link>
You need to write,
<router-link :to="{ path: 'third_screen', params: { session_id: this.session_id, userName:this.user_name}}">User</router-link>
And instead of router.go(-1) you need to send the data as params again to your second screen using router.push() method.
But I won't suggest the above method as you need to pass the same data as params to all routes.
You should also have a look at Vuex.
Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.
You should store your Session Id as cookie instead of passing it as props.
Update
Also have a look at <keep-alive></keep-alive>.
Reference