ユーザーインタラクションとリスト表示
ユーザーからの入力を受け取り、リストを表示する方法を学びましょう。
ユーザー入力 - TextInput
React Nativeでテキスト入力を扱うには、TextInputコンポーネントを使います。
基本的な使い方
import { useState } from 'react';
import { View, Text, TextInput, StyleSheet } from 'react-native';
function App() {
const [text, setText] = useState('');
return (
<View style={styles.container}>
<TextInput
style={styles.input}
value={text}
onChangeText={setText}
placeholder="ここに入力してください"
/>
<Text>入力された内容: {text}</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 20,
},
input: {
height: 40,
borderColor: '#ccc',
borderWidth: 1,
paddingHorizontal: 10,
marginBottom: 10,
},
});重要なプロパティ:
- value: 入力欄の現在の値(stateと連動)
- onChangeText: テキストが変更された時に呼ばれる関数
- placeholder: 入力前に表示されるヒントテキスト
- style: スタイルを適用
ボタン - ButtonとTouchableOpacity
React Nativeには、ユーザーのタップに反応する2つの主要なコンポーネントがあります。
1. Button - シンプルな標準ボタン
Buttonは、最もシンプルなボタンコンポーネントです。
import { View, Button } from 'react-native';
function App() {
const handlePress = () => {
console.log('ボタンが押されました');
};
return (
<View>
<Button
title="押してください"
onPress={handlePress}
/>
</View>
);
}Buttonの特徴:
✅ メリット
- シンプルで使いやすい
- 最小限のコードで実装できる
❌ デメリット
- デザインのカスタマイズができない
- プラットフォーム(iOS/Android)によって見た目が異なる
2. TouchableOpacity - カスタマイズ可能
TouchableOpacityは、自由にデザインできるタップ可能なコンポーネントです。
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
function App() {
const handlePress = () => {
console.log('カスタムボタンが押されました');
};
return (
<View>
<TouchableOpacity
style={styles.button}
onPress={handlePress}
>
<Text style={styles.buttonText}>カスタムボタン</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
button: {
backgroundColor: '#2196F3',
padding: 15,
borderRadius: 8,
alignItems: 'center',
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
});✅ メリット
- 完全にカスタマイズ可能
- タップ時に半透明になるフィードバック効果
- どんなコンポーネントでもタップ可能にできる
リスト表示 - FlatList
FlatListは、大量のデータを効率的に表示するためのコンポーネントです。
基本的な使い方
import { View, Text, FlatList, StyleSheet } from 'react-native';
function App() {
const fruits = ['りんご', 'バナナ', 'オレンジ', 'ぶどう', 'いちご'];
return (
<View style={styles.container}>
<FlatList
data={fruits} // 表示するデータ(配列)
renderItem={({ item }) => ( // 各アイテムの表示方法
<View style={styles.item}>
<Text style={styles.text}>{item}</Text>
</View>
)}
keyExtractor={(item, index) => index.toString()} // 各アイテムのユニークなキー
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
item: {
padding: 20,
borderBottomWidth: 1,
borderBottomColor: '#ccc',
},
text: {
fontSize: 18,
},
});必須のプロパティ:
- data: 表示するデータの配列
- renderItem: 各アイテムをどう表示するか定義する関数
- keyExtractor: 各アイテムのユニークなキーを返す関数
オブジェクトの配列を表示
interface User {
id: number;
name: string;
email: string;
}
function UserList() {
const users: User[] = [
{ id: 1, name: '太郎', email: '[email protected]' },
{ id: 2, name: '花子', email: '[email protected]' },
{ id: 3, name: '次郎', email: '[email protected]' },
];
return (
<FlatList
data={users}
renderItem={({ item }) => (
<View style={styles.userCard}>
<Text style={styles.name}>{item.name}</Text>
<Text style={styles.email}>{item.email}</Text>
</View>
)}
keyExtractor={(item) => item.id.toString()} // IDをキーに使う
/>
);
}ポイント:
- オブジェクトに一意のIDがある場合、それを
keyExtractorで使う - インデックスよりもIDの方が安全
実践例:Todoリスト
import { useState } from 'react';
import {
View,
Text,
TextInput,
Button,
FlatList,
TouchableOpacity,
StyleSheet
} from 'react-native';
interface Todo {
id: number;
text: string;
completed: boolean;
}
function TodoList() {
const [input, setInput] = useState('');
const [todos, setTodos] = useState<Todo[]>([]);
const addTodo = () => {
if (input.trim()) {
setTodos([
...todos,
{ id: Date.now(), text: input, completed: false }
]);
setInput('');
}
};
const toggleTodo = (id: number) => {
setTodos(
todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
);
};
return (
<View style={styles.container}>
<Text style={styles.title}>Todoリスト</Text>
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
value={input}
onChangeText={setInput}
placeholder="Todoを入力"
/>
<Button title="追加" onPress={addTodo} />
</View>
<FlatList
data={todos}
renderItem={({ item }) => (
<TouchableOpacity
onPress={() => toggleTodo(item.id)}
style={styles.todoItem}
>
<Text
style={[
styles.todoText,
item.completed && styles.completed
]}
>
{item.text}
</Text>
</TouchableOpacity>
)}
keyExtractor={(item) => item.id.toString()}
ListEmptyComponent={() => (
<Text style={styles.empty}>Todoを追加してください</Text>
)}
/>
</View>
);
}まとめ
TextInput
- ユーザーからテキスト入力を受け取る
- valueとonChangeTextで制御
- keyboardType、secureTextEntryなどで動作をカスタマイズ
ボタン
- Button: シンプルだがカスタマイズ不可
- TouchableOpacity: 自由にデザイン可能
- onPressでタップ時の処理を定義
FlatList
- 大量のデータを効率的に表示
- data、renderItem、keyExtractorが必須
- 画面に見えている部分だけレンダリング(パフォーマンスが良い)
これで、ユーザー入力を受け取り、ボタンで操作し、リストで表示する基本的なアプリが作れるようになりました!
次は、これらを組み合わせた実践的なアプリ開発を学びましょう。