Nomura Nori
Nomura Nori

Reputation: 5187

How to stop Fast refresh reset route to initialRoute automatically in React Native

How are you. I am using React Native 0.62.2. The problem is when code updated, it goes to initalRoute automatically, so I need to navigate to screen I was working to check updated. How can I stop it so when updated code, fast refresh shows update on current screen?

"react": "16.11.0",
"react-native": "0.62.2",
"@react-navigation/bottom-tabs": "^5.2.7",
"@react-navigation/drawer": "^5.5.0",
"@react-navigation/material-bottom-tabs": "^5.1.9",
"@react-navigation/native": "^5.1.5",
"@react-navigation/stack": "^5.2.10",

Thanks

Upvotes: 2

Views: 1266

Answers (3)

Simon Posada Fishman
Simon Posada Fishman

Reputation: 21

For those who are running into this problem with React Native Web.

I fixed this by configuring Linking with React Navigation.

const config = {
  screens: {
    Login: 'login',
    Home: '',
    About: 'about',
  },
};

const linking = {
  prefixes: ['https://example.com',],
  config,
};

<NavigationContainer linking={linking}>
  ...
</NavigationContainer>

Once Linking was set up, fast refresh no longer reseted the navigation to the first route.

Upvotes: 2

lazine
lazine

Reputation: 1

Maybe you can try this way. I follow the State persistence document of React Navigation to write the code down below.

https://reactnavigation.org/docs/state-persistence/

import * as React from 'react';
import { Linking, Platform } from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import { NavigationContainer } from '@react-navigation/native';

const PERSISTENCE_KEY = 'NAVIGATION_STATE';

export default function App() {
  const [isReady, setIsReady] = React.useState(__DEV__ ? false : true);
  const [initialState, setInitialState] = React.useState();

  React.useEffect(() => {
    const restoreState = async () => {
      try {
        const initialUrl = await Linking.getInitialURL();

        if (Platform.OS !== 'web' && initialUrl == null) {
          // Only restore state if there's no deep link and we're not on web
          const savedStateString = await AsyncStorage.getItem(PERSISTENCE_KEY);
          const state = savedStateString ? JSON.parse(savedStateString) : undefined;

          if (state !== undefined) {
            setInitialState(state);
          }
        }
      } finally {
        setIsReady(true);
      }
    };

    if (!isReady) {
      restoreState();
    }
  }, [isReady]);

  if (!isReady) {
  return <ActivityIndicator />;
}

  return (
    <NavigationContainer
      initialState={initialState}
      onStateChange={(state) =>
        AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state))
      }
    >
      {/* ... */}
    </NavigationContainer>
  );
}

Upvotes: 0

Matt
Matt

Reputation: 364

You can write a component that record the state of the navigation and stores it on asyncStorage. Maybe something like so:

import { InitialState, NavigationContainer } from "@react-navigation/native";
import React, { useCallback, useEffect, useState } from "react";
import { AsyncStorage } from "react-native";

const NAVIGATION_STATE_KEY = `NAVIGATION_STATE_KEY-${sdkVersion}`;

function NavigationHandler() {
  const [isNavigationReady, setIsNavigationReady] = useState(!__DEV__);
  const [initialState, setInitialState] = useState<InitialState | undefined>();

  useEffect(() => {
    const restoreState = async () => {
      try {
        const savedStateString = await AsyncStorage.getItem(
          NAVIGATION_STATE_KEY
        );
        const state = savedStateString
          ? JSON.parse(savedStateString)
          : undefined;
        setInitialState(state);
      } finally {
        setIsNavigationReady(true);
      }
    };

    if (!isNavigationReady) {
      restoreState();
    }
  }, [isNavigationReady]);

  const onStateChange = useCallback(
    (state) =>
      AsyncStorage.setItem(NAVIGATION_STATE_KEY, JSON.stringify(state)),
    []
  );

  if (!isNavigationReady) {
    return <AppLoading />;
  }

  return (
    <NavigationContainer {...{ onStateChange, initialState }}>
      {children}
    </NavigationContainer>
  );
}

I'd check LoadAsset Typescript component from @wcandillon here

Upvotes: 0

Related Questions