๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“ฑ Cross Platform/React Native

[React Native] List์— Component ์ ์šฉํ•˜๊ธฐ (feat. FlatList,Pressable)

by Fomagran ๐Ÿ’ป 2022. 6. 17.
728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š” Foma ์ž…๋‹ˆ๋‹ค!

 

์˜ค๋Š˜์€ React Native์—์„œ Component๋ฅผ ๋งŒ๋“ค์–ด List์— ์ ์šฉํ•ด ๋ณด๋Š” ๊ฒƒ์„ ์ •๋ฆฌํ•ด ๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

(iOS๋กœ ๋งํ•˜๋ฉด TableView๋ฅผ ๋งŒ๋“ค์–ด Cell์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•˜๋”๋ผ๊ตฌ์š”.)

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~

 

์–ธ์–ด๋Š” TypeScript, ํ™˜๊ฒฝ์€ Expo๋กœ ์ง„ํ–‰ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!


Model

 

Person.ts

 

๋ฐ์ดํ„ฐ๋ฅผ ๋„์šธ ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

export interface Person {
  name: string;
  age: number;
  gender: string;
}

Component

 

List์— ๋„์šธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„์„ PersonCell๋กœ ๋งŒ๋“ค์–ด ์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค. (iOS ์Šคํƒ€์ผ๋กœ...ใ…Ž)

 

ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์•„์ดํ…œ์„ Person์œผ๋กœ ์ง€์ •ํ•ด ์ฃผ๊ณ  ๊ฐ ํ”„๋กœํผํ‹ฐ๋ฅผ Text๋กœ ๋„์›Œ์ค๋‹ˆ๋‹ค.

 

PersonCell.tsx

 

import { View, Text, StyleSheet } from "react-native";
import { Person } from "./Person";

export default function PersonCell({ item }: { item: Person }) {
  return (
    <View style={styles.container}>
      <Text style={styles.name}>{item.name}</Text>
      <Text style={styles.age}>{item.age} years old</Text>
      <Text style={styles.gender}>
        {item.gender} {item.gender == "Male" ? "โ™‚" : "โ™€"}
      </Text>
    </View>
  );
}


PersonCell Stylesheet

 

๊ฐ ํƒœ๊ทธ์— ๋งž๊ฒŒ ์Šคํƒ€์ผ๋„ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

const styles = StyleSheet.create({
  container: {
    borderRadius: 10,
    borderColor: "white",
    borderWidth: 1,
    padding: 10,
    marginBottom: 10,
    color: "white",
    backgroundColor: "rgba(50,50,50,1)",
  },
  name: {
    color: "white",
    fontSize: 15,
    fontWeight: "bold",
    marginBottom: 5,
  },
  gender: {
    color: "white",
    fontSize: 15,
  },
  age: {
    color: "white",
    fontSize: 15,
  },
});

Data

 

Person ๋ชจ๋ธ์˜ ํ˜•์‹์— ๋งž๋Š” Json ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

personData.json

 

[
  {
    "name": "Kalid",
    "age": 15,
    "gender": "Male"
  },
  {
    "name": "Fomagran",
    "age": 20,
    "gender": "Male"
  },
  {
    "name": "May",
    "age": 19,
    "gender": "Female"
  },
  {
    "name": "Julia",
    "age": 29,
    "gender": "Female"
  },
  {
    "name": "Hunter",
    "age": 18,
    "gender": "Male"
  },
  {
    "name": "Jane",
    "age": 28,
    "gender": "Female"
  },
  {
    "name": "Kendrick",
    "age": 34,
    "gender": "Male"
  },
  {
    "name": "Kali",
    "age": 25,
    "gender": "Female"
  },
  {
    "name": "Jay",
    "age": 37,
    "gender": "Male"
  },
  {
    "name": "Mac",
    "age": 31,
    "gender": "Male"
  }
]

List

 

App.tsx

 

List๋ฅผ ๋„์šฐ๊ธฐ ์œ„ํ•ด FlatList๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

FlatList๋Š” ScrollView์™€ ๊ฑฐ์˜ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

 

๋‹ค๋งŒ FlatList๋Š” ํ™”๋ฉด์— ์•ˆ๋ณด์—ฌ์ง€๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ Œ๋”๋ง ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ€๋ณ€์ ์ด๊ณ  ๋งŽ์„ ๋•Œ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ข‹์Šต๋‹ˆ๋‹ค.

 

data์—๋Š” personData๋ฅผ Person ํ˜•์œผ๋กœ ๋ฐ”๊ฟ”์ค˜์„œ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

 

renderItem = PersonCell์„ ์ ์šฉํ•ด์ฃผ๊ณ 

 

keyExtractor ์–ด๋Š ํ”„๋กœํผํ‹ฐ ๊ธฐ์ค€์œผ๋กœ ๋งŒ๋“ค๊ฑด์ง€๋ฅผ ์ •ํ•ด ์ค๋‹ˆ๋‹ค.

 

import { StyleSheet, Text, View, FlatList } from "react-native";
import { Person } from "./Person";
import PersonCell from "./PersonCell";
import personData from "./personData.json";

export default function App() {
  return (
    <View style={styles.container}>
      <Text style={styles.header}>Person List</Text>
      <FlatList
        data={personData as Person[]}
        renderItem={PersonCell}
        keyExtractor={(item) => item.name}
      />
    </View>
  );
}

 

App StyleSheet

 

const styles = StyleSheet.create({
  container: {
    padding: 20,
    flex: 1,
    backgroundColor: "rgba(50,50,50,1)",
  },
  header: {
    fontSize: 20,
    marginBottom: 20,
    fontWeight: "bold",
    color: "white",
  },
});

์‹คํ–‰ ํ™”๋ฉด

 

์•„๋ž˜์™€ ๊ฐ™์ด List ์•ˆ์— ๋ฐ์ดํ„ฐ์˜ ๋‚ด์šฉ์— ๋งž๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋„์›Œ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 


Pressable

 

๋งŒ์•ฝ ๋ฆฌ์ŠคํŠธ์— ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ํด๋ฆญ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด Pressable์ด๋ผ๋Š” react-native ์ž์ฒด์—์„œ ์ œ๊ณตํ•˜๋Š” component๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

App.tsx

 

Pressable์„ import ํ•ด์ค๋‹ˆ๋‹ค.

 

import { Pressable } from "react-native";

 

ํด๋ฆญ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก Component๋ฅผ <Pressable> ํƒœ๊ทธ๋กœ ๊ฐ์‹ธ์ค๋‹ˆ๋‹ค.

 

ํด๋ฆญ ํ–ˆ์„ ๋•Œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์•Œ๋ฆผ์ฐฝ์„ ๋„์šฐ๋„๋ก ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

const PressableItem = ({ item }: { item: Person }) => {
  return (
    <Pressable onPress={() => alert(`Pressed: ${item.name}`)}>
      <PersonCell item={item} />
    </Pressable>
  );
};

 

renderItem์— ์œ„์—์„œ ๊ฐ์‹ธ์ค€ PressableItem์œผ๋กœ ์ ์šฉํ•ด ์ค๋‹ˆ๋‹ค.

 

export default function App() {
  return (
    <View style={styles.container}>
      <Text style={styles.header}>Person List</Text>
      <FlatList
        data={personData as Person[]}
        renderItem={PressableItem}
        keyExtractor={(item) => item.name}
      />
    </View>
  );
}

 

๋ฆฌ์ŠคํŠธ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์•Œ๋ฆผ์ฐฝ์ด ๋œจ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€