Displaying Various React Native UI Components on visionOS

Now that I have managed to display an app for visionOS with React Native, I will next try displaying various components and check what they look like and whether they can be used.
This is the third post in the react-native-visionos series. The previous posts are below.
- Making and Playing with a Vision Pro App Using react-native-visionos - Yori Hiroi Frontend
- Initial Structure of a visionOS App Built with react-native-visionos - Yori Hiroi Frontend
By the way, when I tried launching the app I created in the first post again, I got the same error even though main.jsbundle existed in the project.
I recreated the project and recreated main.jsbundle, but the error message did not disappear. Then I added main.jsbundle to the Xcode project, and it finally displayed successfully.

Displaying Various UI Components
React Native provides various UI components by default. You can check what UI components are available on the official site.
This time, I placed various components in the window, mainly the major ones I expect to use often. Some look slightly different from iOS, so I think it is best to actually place them and check their behavior.
I also wanted to check layout this time, so I tried using Flexbox layout. Layout can be done without too much concern, but there was a problem where if UI components were placed in the window without specifying anything, part of them was hidden by the rounded corner in the upper left. This is something to watch out for.
Text decoration and similar styling also display as expected when styles are applied, so that seems fine. However, I have not tried everything, so I will keep in mind that some issues may appear in the future.
Is Image Display a Little Quirky?
This time, I specified ios as the platform for main.jsbundle. This is because specifying visionos causes an error, and I infer the reason is that a file named Image.ios.tsx exists, but Image.visionos.tsx does not yet exist. I feel this point will be fixed in the future, so I am not too worried.
For that reason, at the moment, an iOS build had to be performed once before images could be displayed. That is my understanding, though I may be wrong. Without doing this, visionOS only outputs an area where nothing is displayed.
I Also Displayed Two Types of Buttons
For buttons, I tried two types: a normal button and one made with the Pressable component. Both worked. Pressable seems to be a relatively new component and allows detailed style control.
I also made the buttons display a simple alert when pressed. My impression is that even simple alerts look quite cool on visionOS.

Using useState Too
When you think of React, hooks are used to control state and add various functions to components. This time, I tried managing switch state with the simplest hook, useState. This also worked successfully without any particular problem.
Code Changed from the Initial State
The code that adds the various UI components this time is below. I wrote it directly in App.tsx, but when making a more serious app, I think the folder structure should be changed. At the moment, App.tsx is directly under the root, but I expect to create and manage a src directory.
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
*/
import React, {useState} from 'react';
import type {PropsWithChildren} from 'react';
import {
ScrollView,
StyleSheet,
Text,
useColorScheme,
View,
ActivityIndicator,
Button,
Alert,
Pressable,
TextInput,
Switch,
Image,
} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
const profileImage = require('./assets/karad_2016.jpg');
type SectionProps = PropsWithChildren<{
title: string;
}>;
function Section({children, title}: SectionProps): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
return (
<View style={styles.sectionContainer}>
<Text
style={[
styles.sectionTitle,
{
color: isDarkMode ? Colors.white : Colors.black,
},
]}>
{title}
</Text>
<Text
style={[
styles.sectionDescription,
{
color: isDarkMode ? Colors.light : Colors.dark,
},
]}>
{children}
</Text>
</View>
);
}
function App(): React.JSX.Element {
const [isEnabled, setIsEnabled] = useState(false);
const toggleSwitch = () => setIsEnabled(previousState => !previousState);
return (
<ScrollView contentInsetAdjustmentBehavior="automatic">
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
{/* Display an image */}
<Section title="Image">
<View style={{flexDirection: 'row'}}>
<Image style={{width: 64, height: 64}} source={profileImage} />
</View>
</Section>
{/* Display simple text */}
<Section title="Text">
<View style={{flexDirection: 'row'}}>
<Text style={{color: 'white'}}>
React Native visionOS allows you to write visionOS with full
support for platform SDK.
</Text>
</View>
</Section>
{/* Text input */}
<Section title="Text Input">
<View style={{flexDirection: 'row'}}>
<TextInput
style={{paddingVertical: 12, paddingHorizontal: 32}}
onChangeText={() => Alert.alert('Change Text')}
placeholder="Input me"
/>
</View>
</Section>
{/* Switch */}
<Section title="Switch">
<View style={{flexDirection: 'row'}}>
<Switch onValueChange={toggleSwitch} value={isEnabled} />
</View>
</Section>
{/* Indicator usable for loading states */}
<Section title="ActivityIndicator">
<View style={{flexDirection: 'row'}}>
<ActivityIndicator size={'large'} />
</View>
</Section>
{/* Two button types */}
<Section title="Button">
<View style={{flexDirection: 'row', gap: 10}}>
<Button
title="My Button"
onPress={() => Alert.alert('Simple Button pressed')}
/>
<Pressable
style={{
backgroundColor: 'white',
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 12,
paddingHorizontal: 32,
borderRadius: 4,
elevation: 3,
}}
onPress={() => Alert.alert('Pressable Button pressed')}>
<Text style={{}}>Pressable Button</Text>
</Pressable>
</View>
</Section>
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});
export default App;