Skip to content

Commit 4ef6b37

Browse files
authored
Fix issue when creating a ContentIslandComponentView when the root ReactNativeIsland is not connected (#15649)
* Fix issue when creating a ContentIslandComponentView when the root ReactNativeIsland is not connected * Change files * Unregister from state changed events after we have used it to connect
1 parent 8f763bf commit 4ef6b37

3 files changed

Lines changed: 57 additions & 2 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "Fix issue when creating a ContentIslandComponentView when the root ReactNativeIsland is not connected",
4+
"packageName": "react-native-windows",
5+
"email": "30809111+acoates-ms@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}

vnext/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,19 @@ ContentIslandComponentView::ContentIslandComponentView(
4242
});
4343
}
4444

45-
void ContentIslandComponentView::OnMounted() noexcept {
45+
winrt::Microsoft::UI::Content::ContentIsland ContentIslandComponentView::ParentContentIsland() noexcept {
46+
auto root = rootComponentView();
47+
if (!root)
48+
return nullptr;
49+
return root->parentContentIsland();
50+
}
51+
52+
void ContentIslandComponentView::ConnectInternal() noexcept {
53+
if (!m_islandToConnect)
54+
return;
55+
4656
m_childSiteLink = winrt::Microsoft::UI::Content::ChildSiteLink::Create(
47-
rootComponentView()->parentContentIsland(),
57+
m_parentContentIsland,
4858
winrt::Microsoft::ReactNative::Composition::Experimental::CompositionContextHelper::InnerVisual(Visual())
4959
.as<winrt::Microsoft::UI::Composition::ContainerVisual>());
5060
m_childSiteLink.ActualSize({m_layoutMetrics.frame.size.width, m_layoutMetrics.frame.size.height});
@@ -68,6 +78,7 @@ void ContentIslandComponentView::OnMounted() noexcept {
6878
m_childSiteLink.Connect(m_islandToConnect);
6979
m_islandToConnect = nullptr;
7080
}
81+
UnregisterForRootIslandEvents();
7182

7283
ParentLayoutChanged();
7384
auto view = Parent();
@@ -84,12 +95,42 @@ void ContentIslandComponentView::OnMounted() noexcept {
8495
}
8596
}
8697

98+
void ContentIslandComponentView::RegisterForRootIslandEvents() noexcept {
99+
m_parentContentIsland = ParentContentIsland();
100+
101+
if (m_parentContentIsland.IsConnected()) {
102+
ConnectInternal();
103+
} else {
104+
m_islandStateChangedToken = m_parentContentIsland.StateChanged(
105+
[wkThis = get_weak()](
106+
const winrt::Microsoft::UI::Content::ContentIsland & /*island*/,
107+
const winrt::Microsoft::UI::Content::ContentIslandStateChangedEventArgs & /*args*/) {
108+
if (auto strongThis = wkThis.get()) {
109+
strongThis->ConnectInternal();
110+
}
111+
});
112+
}
113+
}
114+
115+
void ContentIslandComponentView::UnregisterForRootIslandEvents() noexcept {
116+
if (m_islandStateChangedToken) {
117+
m_parentContentIsland.StateChanged(m_islandStateChangedToken);
118+
m_islandStateChangedToken = {};
119+
m_parentContentIsland = nullptr;
120+
}
121+
}
122+
123+
void ContentIslandComponentView::OnMounted() noexcept {
124+
RegisterForRootIslandEvents();
125+
}
126+
87127
void ContentIslandComponentView::OnUnmounted() noexcept {
88128
m_layoutMetricChangedRevokers.clear();
89129
if (m_navigationHostDepartFocusRequestedToken && m_navigationHost) {
90130
m_navigationHost.DepartFocusRequested(m_navigationHostDepartFocusRequestedToken);
91131
m_navigationHostDepartFocusRequestedToken = {};
92132
}
133+
UnregisterForRootIslandEvents();
93134
}
94135

95136
void ContentIslandComponentView::ParentLayoutChanged() noexcept {

vnext/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,16 @@ struct ContentIslandComponentView : ContentIslandComponentViewT<ContentIslandCom
5858
void OnMounted() noexcept;
5959
void OnUnmounted() noexcept;
6060
void ParentLayoutChanged() noexcept;
61+
void ConnectInternal() noexcept;
62+
void RegisterForRootIslandEvents() noexcept;
63+
void UnregisterForRootIslandEvents() noexcept;
64+
winrt::Microsoft::UI::Content::ContentIsland ParentContentIsland() noexcept;
6165

6266
bool m_layoutChangePosted{false};
67+
winrt::Microsoft::UI::Content::ContentIsland m_parentContentIsland{nullptr};
6368
winrt::Microsoft::UI::Content::ContentIsland m_islandToConnect{nullptr};
69+
winrt::event_token m_islandStateChangedToken;
70+
6471
winrt::event_token m_mountedToken;
6572
winrt::event_token m_unmountedToken;
6673
std::vector<winrt::Microsoft::ReactNative::ComponentView::LayoutMetricsChanged_revoker> m_layoutMetricChangedRevokers;

0 commit comments

Comments
 (0)