自分用の備忘録です(編集中の箇所あり)
=====================
以下の動画に沿って React Native で Tab Bar の作成したので、手順をまとめます。
React Native: Custom Tab Radio & Filter List Data
####インポート
import React from "react";
import {
Text,
StyleSheet,
View,
Image,
TextInput,
Dimensions,
FlatList,
TouchableOpacity,
TouchableOpacityComponent,
} from "react-native";
Step1 : タブボタンを作る
const Practice = () => {
return (
<SafeAreaView style={styles.container}>
<View style={styles.listTab}>
<TouchableOpacity style={styles.btnTab}>
<Text style={styles.textTab}>All</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
);
};
export default Practice;
CSS
const styles = StyleSheet.create({
container: {
justifyContent: "center",
backgroundColor: "#fff",
padding: 15,
},
listTab: {
flexDirection: "row",
alignSelf: "center",
marginBottom: 20,
},
btnTab: {
width: Dimensions.get("window").width / 3,
flexDirection: "row",
borderWidth: 0.5,
borderColor: "#ebebeb",
padding: 10,
justifyContent: "center",
},
textTab: {
fontSize: 16,
},
});
Step2 : タブボタンを複数にする
① タブボタンの定義
const listTab = [
{
status: "All",
},
{
status: "Purple",
},
{
status: "Green",
},
];
② 定義したタブボタンをループで表示
const Practice = () => {
return (
<SafeAreaView style={styles.container}>
<View style={styles.listTab}>
//配列をループ表示 ここから
{
listTab.map((e) => (
<TouchableOpacity style={styles.btnTab}>
<Text style={styles.textTab}>{e.status}</Text>
</TouchableOpacity>
))
}
//ここまで
</View>
</SafeAreaView>
);
};
.map
で配列要素をループで表示することができます
##Step3 : ボタンをクリックした時にボタンの色を変化させる(状態変化)
背景がピンク、文字が白になるようにします。
useState
を使用
Stateは コンポーネントの状態を表すデータ です。状態ですので、状況によって値が変化します。
Stateでコンポーネントの状態を管理する
useState によって React の state の機能を関数コンポーネントに追加できます。
React
① useStateをインポート
import React, { useState } from "react";
② stateの初期値を設定
const Practice = () => {
//初期値を"All"にセット ここから
const [status, setStatus] = useState("All");
//ここまで
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.listTab}>
{listTab.map((e) => (
<TouchableOpacity
style={styles.btnTab}>
<Text style={styles.textTab}>{e.status}</Text>
</TouchableOpacity>
))}
</View>
</SafeAreaView>
);
};
useStateでは、現在の state(状態) と、それを更新するための関数とを、ペアにして返します。
上記のconst [status, setStatus]
の場合、status
という名前の state 変数を宣言しており、初期値ではそれを"All"にセットしています。現在の status の値を更新したい場合は、setStatus を呼ぶことができます。
参考:React
③ ボタンにイベントを設定
onPress
でイベントを設定
const Practice = () => {
const [status, setStatus] = useState("All");
//ファンクションを定義(内容はStep5で) ここから
const setStatusFilter = (status) => {
setStatus(status);
//ここまで
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.listTab}>
{listTab.map((e) => (
<TouchableOpacity
style={styles.btnTab}
//[onPress] クリックするとイベント(setFunctionFilter)が発生 ここから
onPress={() => setStatusFilter(e.status)}
//ここまで
>
<Text style={styles.textTab}>{e.status}</Text>
</TouchableOpacity>
))}
</View>
</SafeAreaView>
);
};
setFunctionFilter
のファンクションの中身は後で作ります
④ ボタンをクリックした時に色が変化するよう設定
return (
<SafeAreaView style={styles.container}>
<View style={styles.listTab}>
{listTab.map((e) => (
<TouchableOpacity
//クリックしたボタンにbtnTabActiveのスタイルが適用される、背景ピンクになる ここから
style={[styles.btnTab, status === e.status && styles.btnTabActive]}
//ここまで
onPress={() => setStatusFilter(e.status)}
>
<Text
//クリックしたボタンにbtnTextActiveのスタイルが適用される、文字が白になる ここから
style={[
styles.textTab,
status === e.status && styles.textTabActive,
]}
//ここまで
>
{e.status}
</Text>
</TouchableOpacity>
))}
</View>
</SafeAreaView>
);
};
CSS
btnTabActive: {
backgroundColor: "#e6838d",
},
textTabActive: {
color: "#fff",
},
##Step4 : リストを表示する
アイテムリストを並べただけ(ボタンを押してもまだ表示は変わりません)
FlatList
を使用
① リストデータを作成
const listTab = [
{
status: "All",
},
{
status: "Purple",
},
{
status: "Green",
},
];
//データ作成 ここから
const data = [
{
name: "Ronaldo",
status: "Green",
},
{
name: "Messi",
status: "Purple",
},
{
name: "Kaka",
status: "Green",
},
{
name: "Mbappe",
status: "Green",
},
{
name: "Lukakau",
status: "Purple",
},
];
//ここまで
② リストを表示
const Practice = () => {
const [status, setStatus] = useState("All");
const setStatusFilter = (status) => {
setStatus(status);
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.listTab}>
{listTab.map((e) => (
<TouchableOpacity
style={[styles.btnTab, status === e.status && styles.btnTabActive]}
onPress={() => setStatusFilter(e.status)}
>
<Text
style={[
styles.textTab,
status === e.status && styles.textTabActive,
]}
>
{e.status}
</Text>
</TouchableOpacity>
))}
</View>
//FlatList ここから
<FlatList
data={datalist}
keyExtractor={(e, i) => i.toString()}
renderItem={renderItem}
/>
//ここまで
</SafeAreaView>
);
};
③ レンダリングする
const Practice = () => {
const [status, setStatus] = useState("All");
const setStatusFilter = (status) => {
setStatus(status);
};
//レンダリング ここから追記
const renderItem = ({ item, index }) => {
return (
<View key={index} style={styles.itemContainer}>
<View style={styles.itemLogo}>
<Image
style={styles.itemImage}
source={{
uri: "https://store.juventus.com/data/store/product/2/26919/product.jpg",
}}
/>
</View>
<View style={styles.itemBody}>
<Text style={styles.itemName}>{item.name}</Text>
</View>
<View
style={[
styles.itemStatus,
{
backgroundColor: item.status === "Purple" ? "#e5848e" : "#69C080",
},
]}
>
<Text>{item.status}</Text>
</View>
</View>
);
};
//ここまで
return (
<SafeAreaView style={styles.container}>
<View style={styles.listTab}>
{listTab.map((e) => (
<TouchableOpacity
style={[styles.btnTab, status === e.status && styles.btnTabActive]}
onPress={() => setStatusFilter(e.status)}
>
<Text
style={[
styles.textTab,
status === e.status && styles.textTabActive,
]}
>
{e.status}
</Text>
</TouchableOpacity>
))}
</View>
<FlatList
data={data}
keyExtractor={(e, i) => i.toString()}
renderItem={renderItem}
/>
</SafeAreaView>
);
};
CSS
itemContainer: {
flexDirection: "row",
paddingVertical: 15,
},
itemLogo: {
padding: 10,
},
itemImage: {
width: 50,
height: 50,
},
itemBody: {
flex: 1,
paddingHorizontal: 10,
justifyContent: "center",
},
itemName: {
fontWeight: "bold",
fontSize: 16,
},
itemStatus: {
backgroundColor: "green",
paddingHorizontal: 6,
justifyContent: "center",
right: 12,
},
##Step5 : ボタンをクリックした時に表示リストを変化させる(状態変化)
Purpleのボタンを押すと「Purple」のカテゴリが、Greenを押すと「Green」が表示されるようにします
① useStateを設定
const [status, setStatus] = useState("All");
の下に記述
const [datalist, setDatalist] = useState(data);
② setFunctionFilter
ファンクションの中身を作成
const setStatusFilter = (status) => {
//statusが"All"以外だったら(Purple and Greenなら)
if (status !== "All") {
//filterメソッドで、特定カテゴリのデータが表示される(何が起きているかわからんんん)
setDatalist([...data.filter((e) => e.status === status)]);
//"All"の場合は全リスト表示
} else {
setDatalist(data);
}
setStatus(status);
};
...data
の ...
は「スプレッド構文(Spread Syntax)」と言われ、配列やオブジェクトの要素を展開する構文です。
ここでは、Step4 で定義したリストデータ data
の中身↓が展開されています。
const data = [
{
name: "Ronaldo",
status: "Green",
},
{
name: "Messi",
status: "Purple",
},
{
name: "Kaka",
status: "Green",
},
{
name: "Mbappe",
status: "Green",
},
{
name: "Lukakau",
status: "Purple",
},
];
③ <FlatList />
の data の中身を datalist に書き換え
<FlatList
data={datalist} //ここを書き換え
keyExtractor={(e, i) => i.toString()}
renderItem={renderItem}
/>
④ item separator を設定(オプション)
よくわからない
const separator = () => {
return <View style={{ height: 1, backgroundColor: "#f1f1f1" }} />;
};
<FlatList
data={datalist}
keyExtractor={(e, i) => i.toString()}
renderItem={renderItem}
ItemSeparatorComponent={separator} //ここを追記
/>
以上。
のちほど再編集していきます。