jutsu-react-native:react-native-components

React Native Components

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "jutsu-react-native:react-native-components" with this command: npx skills add thebushidocollective/han/thebushidocollective-han-jutsu-react-native-react-native-components

React Native Components

Use this skill when building user interfaces with React Native's core components and creating custom reusable components.

Key Concepts

Core Components

React Native provides platform-agnostic components that map to native views:

import React from 'react'; import { View, Text, Image, ScrollView, TextInput, TouchableOpacity, SafeAreaView, } from 'react-native';

export default function App() { return ( <SafeAreaView style={{ flex: 1 }}> <ScrollView> <View> <Text>Hello, React Native!</Text> <Image source={{ uri: 'https://example.com/image.jpg' }} style={{ width: 200, height: 200 }} /> <TextInput placeholder="Enter text" style={{ borderWidth: 1, padding: 10 }} /> <TouchableOpacity onPress={() => console.log('Pressed')}> <Text>Press Me</Text> </TouchableOpacity> </View> </ScrollView> </SafeAreaView> ); }

View Component

The fundamental building block:

import { View } from 'react-native';

function Container({ children }: { children: React.ReactNode }) { return ( <View style={{ flex: 1, padding: 16, backgroundColor: '#fff', }}> {children} </View> ); }

Text Component

All text must be wrapped in <Text> :

import { Text } from 'react-native';

function Heading({ children }: { children: string }) { return ( <Text style={{ fontSize: 24, fontWeight: 'bold', color: '#333', }}> {children} </Text> ); }

function Body({ children }: { children: string }) { return ( <Text style={{ fontSize: 16, lineHeight: 24, color: '#666', }}> {children} </Text> ); }

Image Component

Display images from various sources:

import { Image } from 'react-native';

// Remote image <Image source={{ uri: 'https://example.com/image.jpg' }} style={{ width: 200, height: 200 }} />

// Local image <Image source={require('./assets/logo.png')} style={{ width: 100, height: 100 }} />

// With resize mode <Image source={{ uri: 'https://example.com/image.jpg' }} style={{ width: 200, height: 200 }} resizeMode="cover" />

Best Practices

Use SafeAreaView for iOS Notch

Always use SafeAreaView to handle safe areas:

import { SafeAreaView } from 'react-native';

export default function App() { return ( <SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}> {/* Your content */} </SafeAreaView> ); }

FlatList for Long Lists

Use FlatList instead of ScrollView for performance:

import { FlatList, Text, View } from 'react-native';

interface Item { id: string; title: string; }

function ItemList({ items }: { items: Item[] }) { return ( <FlatList data={items} keyExtractor={(item) => item.id} renderItem={({ item }) => ( <View style={{ padding: 16 }}> <Text>{item.title}</Text> </View> )} // Performance optimizations removeClippedSubviews={true} maxToRenderPerBatch={10} updateCellsBatchingPeriod={50} initialNumToRender={10} windowSize={10} /> ); }

Touchable Components

Use appropriate touchables for platform:

import { TouchableOpacity, TouchableHighlight, Pressable } from 'react-native';

// Modern approach - Pressable (recommended) <Pressable onPress={() => console.log('Pressed')} style={({ pressed }) => [ { padding: 12, backgroundColor: pressed ? '#ddd' : '#fff' } ]}

{({ pressed }) => ( <Text style={{ color: pressed ? '#000' : '#333' }}>Press Me</Text> )} </Pressable>

// TouchableOpacity - simple fade effect <TouchableOpacity onPress={() => console.log('Pressed')} activeOpacity={0.7}

<Text>Press Me</Text> </TouchableOpacity>

Component Composition

Build complex UIs from simple components:

import React from 'react'; import { View, Text, StyleSheet } from 'react-native';

interface CardProps { title: string; subtitle?: string; children?: React.ReactNode; }

function Card({ title, subtitle, children }: CardProps) { return ( <View style={styles.card}> <View style={styles.header}> <Text style={styles.title}>{title}</Text> {subtitle && <Text style={styles.subtitle}>{subtitle}</Text>} </View> {children && <View style={styles.content}>{children}</View>} </View> ); }

const styles = StyleSheet.create({ card: { backgroundColor: '#fff', borderRadius: 8, padding: 16, marginVertical: 8, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, }, header: { marginBottom: 12, }, title: { fontSize: 18, fontWeight: 'bold', color: '#333', }, subtitle: { fontSize: 14, color: '#666', marginTop: 4, }, content: { marginTop: 8, }, });

export default Card;

Common Patterns

List with Pull-to-Refresh

import React, { useState, useCallback } from 'react'; import { FlatList, RefreshControl, Text, View } from 'react-native';

interface Item { id: string; title: string; }

function RefreshableList({ items, onRefresh }: { items: Item[]; onRefresh: () => Promise<void>; }) { const [refreshing, setRefreshing] = useState(false);

const handleRefresh = useCallback(async () => { setRefreshing(true); await onRefresh(); setRefreshing(false); }, [onRefresh]);

return ( <FlatList data={items} keyExtractor={(item) => item.id} renderItem={({ item }) => ( <View style={{ padding: 16 }}> <Text>{item.title}</Text> </View> )} refreshControl={ <RefreshControl refreshing={refreshing} onRefresh={handleRefresh} /> } /> ); }

Infinite Scroll List

import React from 'react'; import { FlatList, ActivityIndicator, View } from 'react-native';

interface Item { id: string; title: string; }

function InfiniteList({ items, loading, onEndReached }: { items: Item[]; loading: boolean; onEndReached: () => void; }) { return ( <FlatList data={items} keyExtractor={(item) => item.id} renderItem={({ item }) => ( <View style={{ padding: 16 }}> <Text>{item.title}</Text> </View> )} onEndReached={onEndReached} onEndReachedThreshold={0.5} ListFooterComponent={ loading ? ( <View style={{ padding: 16 }}> <ActivityIndicator size="large" /> </View> ) : null } /> ); }

Modal Component

import React from 'react'; import { Modal, View, Text, TouchableOpacity, StyleSheet, } from 'react-native';

interface CustomModalProps { visible: boolean; title: string; children: React.ReactNode; onClose: () => void; }

function CustomModal({ visible, title, children, onClose }: CustomModalProps) { return ( <Modal visible={visible} animationType="slide" transparent={true} onRequestClose={onClose} > <View style={styles.overlay}> <View style={styles.modal}> <View style={styles.header}> <Text style={styles.title}>{title}</Text> <TouchableOpacity onPress={onClose}> <Text style={styles.closeButton}>✕</Text> </TouchableOpacity> </View> <View style={styles.content}>{children}</View> </View> </View> </Modal> ); }

const styles = StyleSheet.create({ overlay: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.5)', justifyContent: 'center', alignItems: 'center', }, modal: { width: '80%', backgroundColor: '#fff', borderRadius: 12, padding: 20, }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16, }, title: { fontSize: 20, fontWeight: 'bold', }, closeButton: { fontSize: 24, color: '#666', }, content: { marginTop: 8, }, });

export default CustomModal;

Form Input Component

import React, { useState } from 'react'; import { View, TextInput, Text, StyleSheet, TextInputProps, } from 'react-native';

interface FormInputProps extends TextInputProps { label: string; error?: string; }

function FormInput({ label, error, ...props }: FormInputProps) { const [isFocused, setIsFocused] = useState(false);

return ( <View style={styles.container}> <Text style={styles.label}>{label}</Text> <TextInput {...props} style={[ styles.input, isFocused && styles.inputFocused, error && styles.inputError, ]} onFocus={() => setIsFocused(true)} onBlur={() => setIsFocused(false)} /> {error && <Text style={styles.error}>{error}</Text>} </View> ); }

const styles = StyleSheet.create({ container: { marginVertical: 8, }, label: { fontSize: 14, fontWeight: '600', marginBottom: 4, color: '#333', }, input: { borderWidth: 1, borderColor: '#ddd', borderRadius: 8, padding: 12, fontSize: 16, }, inputFocused: { borderColor: '#007AFF', }, inputError: { borderColor: '#FF3B30', }, error: { color: '#FF3B30', fontSize: 12, marginTop: 4, }, });

export default FormInput;

Anti-Patterns

Don't Nest ScrollViews

// Bad - Nested ScrollViews cause issues <ScrollView> <ScrollView> <Text>Content</Text> </ScrollView> </ScrollView>

// Good - Use single ScrollView <ScrollView> <View> <Text>Content</Text> </View> </ScrollView>

Don't Use Inline Styles for Static Values

// Bad - Creates new object on every render <View style={{ padding: 16, backgroundColor: '#fff' }}> <Text>Content</Text> </View>

// Good - Use StyleSheet const styles = StyleSheet.create({ container: { padding: 16, backgroundColor: '#fff', }, });

<View style={styles.container}> <Text>Content</Text> </View>

Don't Forget to Set keyExtractor

// Bad - May cause rendering issues <FlatList data={items} renderItem={({ item }) => <Text>{item.title}</Text>} />

// Good - Provide unique key <FlatList data={items} keyExtractor={(item) => item.id} renderItem={({ item }) => <Text>{item.title}</Text>} />

Don't Use Index as Key

// Bad - Index as key causes issues with reordering <FlatList data={items} keyExtractor={(item, index) => index.toString()} renderItem={({ item }) => <Text>{item.title}</Text>} />

// Good - Use unique identifier <FlatList data={items} keyExtractor={(item) => item.id} renderItem={({ item }) => <Text>{item.title}</Text>} />

Related Skills

  • react-native-styling: Styling components with StyleSheet

  • react-native-navigation: Navigation between screens

  • react-native-performance: Optimizing component performance

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

android-jetpack-compose

No summary provided by upstream source.

Repository SourceNeeds Review
General

fastapi-async-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

storybook-story-writing

No summary provided by upstream source.

Repository SourceNeeds Review
General

atomic-design-fundamentals

No summary provided by upstream source.

Repository SourceNeeds Review