为什么我的另一个屏幕在导航之前加载?



我只用了导航。我有飞溅,登录和主标签屏幕。我的堆栈已经从飞溅->登录——比;主要选项卡。最终,当启动时,登录屏幕首先加载,但屏幕显示闪屏部分。在登录加载时,我会检查与域的连接,问题出现告诉Warning: Can't perform a React state update on an unmounted component

navigation-container.js

const LoginStack = createNativeStackNavigator();
function NavigatorLogin() {
return (
<LoginStack.Navigator>
<LoginStack.Screen name="AppSignIn" component={AppSignIn} />
{* .... etc *}
</LoginStack.Navigator>
);
}
const MainTabStack = createNativeStackNavigator();
function NavigatorMainTab() {
return (
<MainTabStack.Navigator>
{* .... etc *}
</SupervisorStack.Navigator>
);
}
const StackApp = createNativeStackNavigator();
export const AppStackNavigator = () => {
const [appState, setAppState] = React.useState({});
const [dataState, setDataState] = React.useState({});
const [initialRoute, setInitialRoute] = React.useState('NavigatorLogin');
const state = { appState, setAppState };
const datas = { dataState, setDataState };
React.useEffect(() => {
setAppState({ IsLoading: true, IsLoggedIn: false });
setDataState({ taskitem: {} });
console.log('App state 1: ', appState);
}, []);
React.useEffect(() => {
console.log('App state: ', appState);
}, [appState]);
return (
<AppContext.Provider value={state}>
{appState.IsLoading ? (
<AppSplash />
)
: (
<NavigationContainer>
<StackApp.Navigator initialRouteName={initialRoute}>
{
appState.IsLoggedIn
?
<StackApp.Screen name='NavigatorMainTab' component={NavigatorMainTab}/>
:
<StackApp.Screen name='NavigatorLogin' component={NavigatorLogin}/>
}
</StackApp.Navigator>
</NavigationContainer>
)}
</AppContext.Provider>
)
}

AppSignIn.js

export const AppSignIn = () => {
const isMountedRef = React.useRef(false);
const { appState, setAppState } = React.useContext(AppContext);
React.useState(() => {
console.log('Hello from sign in screen; ', appState)
isMountedRef.current = true;
if (isMountedRef.current) {
// check domain connection
}
return () => {
unsubscribe();
isMountedRef.current = false;
}
}, []);
return (
<SafeAreaView style={{ flex: 1 }}>
</SafeAreaView>
)
}

在终端上显示如下:

LOG  Running "myproject" with {"rootTag":41}
LOG  Hello from sign in screen;  {}
LOG  App state 1:  {}
LOG  App state:  {}
ERROR  Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in AppSignIn (at SceneView.tsx:126)
in StaticContainer
in EnsureSingleNavigator (at SceneView.tsx:118)
in SceneView (at useDescriptors.tsx:209)
in RCTView (at View.js:32)
in View (at DebugContainer.native.tsx:27)
in DebugContainer (at NativeStackView.native.tsx:71)
in MaybeNestedStack (at NativeStackView.native.tsx:229)
in RNSScreen (at createAnimatedComponent.js:243)
in AnimatedComponent (at createAnimatedComponent.js:296)
in AnimatedComponentWrapper (at src/index.native.tsx:169)
in Screen (at NativeStackView.native.tsx:175)
in SceneView (at NativeStackView.native.tsx:277)
in RNSScreenStack (at NativeStackView.native.tsx:268)
in NativeStackViewInner (at NativeStackView.native.tsx:322)
in RCTView (at View.js:32)
in View (at SafeAreaProviderCompat.tsx:42)
in SafeAreaProviderCompat (at NativeStackView.native.tsx:321)
in NativeStackView (at createNativeStackNavigator.tsx:67)
in NativeStackNavigator (at navigation-container.js:20)
in NavigatorLogin (at SceneView.tsx:126)
in StaticContainer
in EnsureSingleNavigator (at SceneView.tsx:118)
in SceneView (at useDescriptors.tsx:209)
in RCTView (at View.js:32)
in View (at DebugContainer.native.tsx:27)
in DebugContainer (at NativeStackView.native.tsx:71)
in MaybeNestedStack (at NativeStackView.native.tsx:229)
in RNSScreen (at createAnimatedComponent.js:243)
in AnimatedComponent (at createAnimatedComponent.js:296)
in AnimatedComponentWrapper (at src/index.native.tsx:169)
in Screen (at NativeStackView.native.tsx:175)
in SceneView (at NativeStackView.native.tsx:277)
in RNSScreenStack (at NativeStackView.native.tsx:268)
in NativeStackViewInner (at NativeStackView.native.tsx:322)
in RNCSafeAreaProvider (at SafeAreaContext.tsx:76)
in SafeAreaProvider (at SafeAreaProviderCompat.tsx:46)
in SafeAreaProviderCompat (at NativeStackView.native.tsx:321)
in NativeStackView (at createNativeStackNavigator.tsx:67)
in NativeStackNavigator (at navigation-container.js:72)
in EnsureSingleNavigator (at BaseNavigationContainer.tsx:430)
in BaseNavigationContainer (at NavigationContainer.tsx:132)
in ThemeProvider (at NavigationContainer.tsx:131)
in NavigationContainerInner (at navigation-container.js:71)
LOG  App state:  {"IsLoading": true, "IsLoggedIn": false, "IsSupervisor": false}
LOG  splash info here
LOG  Hello from sign in screen;  {"IsLoading": false}
LOG  App state:  {"IsLoading": false}

最初我没有使用useRef。我用它发现了类似的问题,但它仍然错误。我也使用函数如下,但仍然有错误。我不确定其他选项或如何告诉什么是正确的这就是我的问题。

function useIsMountedRef() {
const isMountedRef = React.useRef(null);
React.useEffect(() => {
isMountedRef.current = true;
return () => isMountedRef.current = false;
}, []);
return React.useCallback(() => isMountedRef.current, []);
}
.
.
.
const isMountedRef = useIsMountedRef();

经过几天的搜索和尝试错误,最终警告消失了。

因为我使用上下文API来代替交换机导航器,所以我在挂载的情况下使用上下文而不是isMountedRef来检查。

删除旧代码

编辑:通过在屏幕挂载上放置一个变量检查,这绝对是不合适的,因为当连接到服务器失败时,计时器将不会运行。解决方案在于navigation-container.js

/// This is original from first post
const [appState, setAppState] = React.useState({});
/// I change to this
const [appState, setAppState] = React.useState({ IsLoading: true, IsLoggedIn: false });

我AppSignIn.js

React.useEffect(() => {
console.log('Login screen mounted');
const unsubscribe = NetInfo.addEventListener(async state => {
setIsPhoneConnected(state.isConnected);
console.log('Phone connected? ' + state.isConnected + ', Server connected? ' + IsServerConnected)
});

CheckServerConnection()
.then((response) => {
console.log(response);
setIsServerConnected(true);
})
.catch((error) => {
setIsServerConnected(false);
ResetTimer(5);
});
return () => {
unsubscribe();
}
}, []);

最新更新