Skip to content

Commit f107f8b

Browse files
committed
Example using concurrentRoot and startTransition
1 parent 7ae3c59 commit f107f8b

File tree

3 files changed

+128
-18
lines changed

3 files changed

+128
-18
lines changed
Lines changed: 120 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,124 @@
1-
/**
2-
* Copyright (c) Microsoft Corporation.
3-
* Licensed under the MIT License.
4-
* @format
5-
*/
6-
import React from 'react';
7-
import {AppRegistry, View} from 'react-native';
8-
9-
export default class Bootstrap extends React.Component {
10-
render() {
11-
return (
12-
<View
13-
accessible={true}
14-
style={{borderRadius: 30, width: 60, height: 60, margin: 10}}>
15-
<View style={{backgroundColor: 'magenta', width: 60, height: 60}} />
1+
import React, { memo, useState, useTransition } from 'react';
2+
import { AppRegistry, Button, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
3+
4+
const styles = StyleSheet.create({
5+
tab: {
6+
alignItems: 'center',
7+
},
8+
post: {
9+
padding: 5,
10+
borderTopWidth: 1,
11+
backgroundColor: 'light-gray',
12+
alignItems: 'center',
13+
},
14+
activeTab: {
15+
fontSize: 20,
16+
fontWeight: 'bold',
17+
alignSelf: 'center',
18+
},
19+
pendingTab: {
20+
color: 'gray',
21+
},
22+
23+
});
24+
25+
function ContactTab() {
26+
return (
27+
<View style={styles.tab}>
28+
<Text>
29+
You can find me online here:
30+
</Text>
31+
<Text>* [email protected]</Text>
32+
<Text>* +123456789</Text>
33+
</View>
34+
);
35+
}
36+
37+
function AboutTab() {
38+
return (
39+
<View style={styles.tab}>
40+
<Text>Welcome to my profile!</Text>
41+
</View>
42+
);
43+
}
44+
45+
const PostsTab = memo(function PostsTab() {
46+
// Log once. The actual slowdown is inside SlowPost.
47+
console.log('[ARTIFICIALLY SLOW] Rendering 500 <SlowPost />');
48+
49+
let items = [];
50+
for (let i = 0; i < 500; i++) {
51+
items.push(<SlowPost key={i} index={i} />);
52+
}
53+
return (
54+
<ScrollView>
55+
{items}
56+
</ScrollView>
57+
);
58+
});
59+
60+
function SlowPost({ index }) {
61+
let startTime = performance.now();
62+
while (performance.now() - startTime < 1) {
63+
// Do nothing for 1 ms per item to emulate extremely slow code
64+
}
65+
66+
return (
67+
<TouchableOpacity>
68+
<View style={styles.post}>
69+
<Text>
70+
Post #{index + 1}
71+
</Text>
1672
</View>
17-
);
73+
</TouchableOpacity>
74+
);
75+
}
76+
77+
function TabButton({ title, isActive, onClick }) {
78+
const [isPending, startTransition] = useTransition();
79+
if (isActive || isPending) {
80+
const tabStyle = [styles.activeTab, isPending ? styles.pendingTab : null];
81+
return <Text style={tabStyle}>{title}</Text>
82+
}
83+
return (
84+
<Button
85+
onPress={() => startTransition(onClick)}
86+
title={title} />
87+
)
88+
}
89+
90+
91+
export default function App() {
92+
const [isPending, startTransition] = useTransition();
93+
const [tab, setTab] = useState('about');
94+
95+
function selectTab(nextTab) {
96+
startTransition(() => {
97+
setTab(nextTab);
98+
});
1899
}
100+
101+
return (
102+
<>
103+
<View style={{ flexDirection: 'row', justifyContent: 'space-around' }}>
104+
<TabButton
105+
isActive={tab === 'about'}
106+
onClick={() => selectTab('about')}
107+
title="About" />
108+
<TabButton
109+
isActive={tab === 'posts'}
110+
onClick={() => selectTab('posts')}
111+
title="Posts (slow)" />
112+
<TabButton
113+
isActive={tab === 'contact'}
114+
onClick={() => selectTab('contact')}
115+
title="Contact" />
116+
</View>
117+
{tab === 'about' && <AboutTab />}
118+
{tab === 'posts' && <PostsTab />}
119+
{tab === 'contact' && <ContactTab />}
120+
</>
121+
);
19122
}
20123

21-
AppRegistry.registerComponent('Bootstrap', () => Bootstrap);
124+
AppRegistry.registerComponent('Bootstrap', () => App);

packages/playground/windows/playground-composition/Playground-Composition.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ struct WindowData {
153153
std::wstring(L"file:").append(workingDir).append(L"\\Bundle\\").c_str());
154154
host.InstanceSettings().UseDeveloperSupport(true);
155155

156+
winrt::Microsoft::ReactNative::QuirkSettings::SetUseRuntimeScheduler(host.InstanceSettings(), true);
157+
156158
host.PackageProviders().Append(CreateStubDeviceInfoPackageProvider());
157159
host.PackageProviders().Append(winrt::make<CompReactPackageProvider>());
158160
winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,13 @@ void CompositionRootView::ShowInstanceLoaded() noexcept {
288288

289289
auto rootTag = ::Microsoft::ReactNative::getNextRootViewTag();
290290
SetTag(rootTag);
291+
auto initProps = DynamicWriter::ToDynamic(Mso::Copy(m_reactViewOptions.InitialProps()));
292+
if (initProps.isNull()) {
293+
initProps = folly::dynamic::object();
294+
}
295+
initProps["concurrentRoot"] = true;
291296
uiManager->startSurface(
292-
*this, rootTag, JSComponentName(), DynamicWriter::ToDynamic(Mso::Copy(m_reactViewOptions.InitialProps())));
297+
*this, rootTag, JSComponentName(), initProps);
293298

294299
m_isJSViewAttached = true;
295300
}

0 commit comments

Comments
 (0)