From b4b6b9de5a29d44751f1d5f03488e8a722e180d1 Mon Sep 17 00:00:00 2001 From: Chris Glein <26607885+chrisglein@users.noreply.github.com> Date: Wed, 20 Sep 2023 09:24:43 -0700 Subject: [PATCH] Fix issue when emptying nav stack on Windows (#1890) ## Description When using a `StackNavigator` on an app on Windows, when you popped the stack you would end up with no displayed content instead of the first page. ## Changes The Windows stack implementation wasn't updating `Content` to the top of the stack (after the removal and motification of the vector). Also the Windows project had an aggressive assertion of SDK version, causing apps to unnecessarily either download an older SDK or patch their app. See https://github.com/react-native-async-storage/async-storage/pull/810 for a similar fix. ## Test code and steps to reproduce ```jsx import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; // ,,, const Stack = createNativeStackNavigator(); export default function App() : JSX.Element { return ( ); } ``` Somewhere else ```jsx navigation.navigate('Details'); ``` And then later ```jsx navigation.goBack(); ``` Result: rendering nothing instead of the 'Home' page. Yep, that's all it took. As far as I can tell this was broken since implementation, but the usage I know of on Windows was using Drawer and that part's all fine. ## Checklist - [x] Included code example that can be used to test this change - [x] Updated TS types **N/A** - [x] Updated documentation: **N/A** - [x] Ensured that CI passes **No tests on Windows :'(** - [x] _Tested via patch-packing in an app_ --- windows/RNScreens/RNScreens.vcxproj | 9 ++++++--- windows/RNScreens/ScreenStack.cpp | 16 ++++++++++++++++ windows/RNScreens/ScreenStack.h | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/windows/RNScreens/RNScreens.vcxproj b/windows/RNScreens/RNScreens.vcxproj index 679da2844a..0d7b49dc7f 100644 --- a/windows/RNScreens/RNScreens.vcxproj +++ b/windows/RNScreens/RNScreens.vcxproj @@ -13,13 +13,16 @@ true Windows Store 10.0 - 10.0.18362.0 - 10.0.16299.0 - $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\ + + + 10.0.18362.0 + 10.0.16299.0 + + Debug diff --git a/windows/RNScreens/ScreenStack.cpp b/windows/RNScreens/ScreenStack.cpp index 15cd03a924..9219b34715 100644 --- a/windows/RNScreens/ScreenStack.cpp +++ b/windows/RNScreens/ScreenStack.cpp @@ -35,6 +35,7 @@ void ScreenStack::removeAllChildren() { void ScreenStack::removeChildAt(int64_t index) { m_children.RemoveAt(static_cast(index)); + onChildModified(index); } void ScreenStack::replaceChild( @@ -45,5 +46,20 @@ void ScreenStack::replaceChild( return; m_children.SetAt(index, newChild); + onChildModified(index); +} + +void ScreenStack::onChildModified(int64_t index) { + // Was it the topmost item in the stack? + if (index >= m_children.Size() - 1) { + if (m_children.Size() == 0) { + // Nobody left + Content(nullptr); + } else { + // Focus on the top item + auto uiElement = m_children.GetAt(m_children.Size() - 1); + Content(uiElement); + } + } } } // namespace winrt::RNScreens::implementation diff --git a/windows/RNScreens/ScreenStack.h b/windows/RNScreens/ScreenStack.h index c1979581bd..7968133384 100644 --- a/windows/RNScreens/ScreenStack.h +++ b/windows/RNScreens/ScreenStack.h @@ -17,6 +17,7 @@ class ScreenStack m_children; private: + void onChildModified(int64_t index); winrt::Microsoft::ReactNative::IReactContext m_reactContext{nullptr}; }; } // namespace winrt::RNScreens::implementation