반응형
인덱스페이지
const [isFriendSectionOpen, setIsFriendSectionOpen] = useState(true); ... <FriendSection friendProfileLen={friendProfiles.length} onPress={() => setIsFriendSectionOpen(!isFriendSectionOpen)} isOpen={isFriendSectionOpen} /> {/* isOpen이 true일 때만 FriendList 컴포넌트가 보이도록 설정 */} {isFriendSectionOpen && <FriendList friendProfiles={friendProfiles} />}
부모컴포넌트(페이지)에서 친구섹션오픈 상태일때 친구목록 렌더링
FriendSection에서 버튼누를때마다 상태 토글함
친구목록에 친구프로필 데이터를 내려준다.
FriendList 컴포넌트

import { ProfileType } from "@/assets/data"; import React from "react"; import { ScrollView, View } from "react-native"; import Margin from "./Margin"; import Profile from "./Profile"; interface FriendListProps { friendProfiles: ProfileType[]; } const FriendList = (props: FriendListProps) => { return ( // scroll인디케이터 안보이게 설정 <ScrollView style={{ width: "100%" }} showsVerticalScrollIndicator={false} > {props.friendProfiles.map((profile) => ( <View key={profile.name}> <Profile name={profile.name} source={profile.source} introduction={profile.introduction} size={"small"} /> <Margin height={10} /> </View> ))} </ScrollView> ); }; export default FriendList;
MyProfile 컴포넌트를 공용컴포넌트로 수정
MyProfile 컴포넌트를 공용컴포넌트로 수정해서 친구목록에서도 사용할것임
데이터파일 수정(이미지 require + uri 동시 사용)
export const myProfile = { source: {uri:"https://png.pngtree.com/thumb_back/fh260/back_pic/03/54/06/62579986dba62df.jpg"}, name: "지은", introduction: "inspiring day", }; export const friendProfiles = [ { source: require("./images/img_user01.png"), name: "진실이", introduction: "패캠강의듣기", }, { source: {uri:"https://cdn.pixabay.com/photo/2017/08/30/01/05/milky-way-2695569__480.jpg"}, name: "김민호", introduction: "Minho Kim", }, ];
이미지에 로컬이미지사용 + 웹이미지(주소)사 동시에 사용해볼것임.
로컬이미지사용일때 require, 웹이미지일때 uri 이렇게 사용이 안된다고함.
require는 동적으로 사용할수 없다.
- 정적으로 선언된 파일만 참조가능하고 변수를 통해 동적으로 불러올 수 없다.
- require를 사용할 때 컴파일 시점에 이미지 파일을 분석하여 번들링하므로, 문자열 변수를 전달하면 정상적으로 동작하지 않음.
기존에는 uri: "https://www.xxx.xxx/xx.jpg"
였는데source: require("로컬파일")
또는 source: {uri:"https://www.xxx.xxx/xx.jpg"},
로
친구프로필, 내프로필 똑같이 데이터 구조를 변경함
<Image source={props.source} style={{ width: 50, height: 50 }} />
soure데이터는 이미지컴포넌트에서 이렇게 사용함
export interface ProfileType { source?: ImageSourcePropType; // require() + { uri: ... } 모두 지원 name: string; introduction: string; }
이때 source의 타입은 ImageSourcePropType을 사용하면 require과 uri를 모두 지원한다.
Profile 컴포넌트
import { ProfileType } from "@/assets/data"; import React from "react"; import { Image, StyleSheet, Text, View } from "react-native"; interface MyProfileProps extends ProfileType { size?: "small" | "large"; } export default (props: MyProfileProps) => { return ( <View style={styles.ProfileContainer}> <View style={ props.size == "small" ? styles.smallImageArea : styles.largeImageArea } > {/* require(props.source): 동적매핑이 안된다고함 */} {/* images[props.source] */} <Image source={props.source} style={{ width: 50, height: 50 }} /> </View> <View style={styles.textArea}> <Text style={{ fontWeight: "bold", marginBottom: 4, fontSize: props.size == "small" ? 14 : 16, }} > {props.name} </Text> <Text style={{ fontSize: 12, color: "gray" }}> {props.introduction} </Text> </View> </View> ); }; const styles = StyleSheet.create({ ProfileContainer: { flexDirection: "row", alignItems: "center", width: "100%", // paddingVertical: 10, }, largeImageArea: { width: 50, height: 50, borderRadius: 20, overflow: "hidden", }, smallImageArea: { width: 40, height: 40, borderRadius: 16, overflow: "hidden", }, textArea: { marginLeft: 12, }, });
강의에서는 프로필을 차이없이 똑같이 사용했는데
난 최대한 비슷하게 하기위해 친구목록에선 사이즈가 작아야돼서 사이즈를 받을거임
small일때와 large일때 스타일을 다르게 줬다.
반응형
'Frontend > React Native' 카테고리의 다른 글
React Native 2-1. 카카오톡 친구목록 클론코딩(6): ScrollView vs FlatList (1) | 2025.03.15 |
---|---|
React Native 2-1. 카카오톡 친구목록 클론코딩(4): 친구목록 상단 컴포넌트들 (0) | 2025.03.15 |
React Native 2-1. 카카오톡 친구목록 클론코딩(3): expo 기본앱에서 tabbar 커스텀 하기 (0) | 2025.03.13 |
React Native 2-1. 카카오톡 친구목록 클론코딩(2) (0) | 2025.03.10 |
React Native 2-1. 카카오톡 친구목록 클론코딩(1) (0) | 2025.03.10 |