💡 forEach and map
forEach ( function (벨류, 인덱스, 어레이) ) - 각각에 접근할 때 마다 function 호출
다만, forEach는 접근해서 새로 만든 결과물을 받을 방법이 없음map( function (벨류, 인덱스, 어레이) )
forEach와 같은 역할이지만 return이 있음
import React, {Component} from 'react'
import {View, Text, StyleSheet, Button} from 'react-native'
export default class MainComponent extends Component {
render(): React.JSX.Element {
//앱을 개발하면서 가장 많은 제작빈도를 가진 리스트 형태 레이아웃 만들기
//RN에서 제공하는 ListView용 컴포넌트를 사용하지 않고 리스트 형태 만들어보기
//1번 실습 ) 사용할 const변수 : JSX컴포넌트 객체를 변수에 저장
const aaa : JSX.Element = <Text style={{margin : 2}}>Nice</Text>
// 2번 실습 ) 변수 하나에 여러개 컴포넌트 저장하기 위해 큰 뷰그룹 사용
const bbb : JSX.Element = <View style={{margin : 2}}><Text>Hello</Text><Button title="클릭"></Button></View>
// 5번 실습 ) 배열의 요소로 JSX의 컴포넌트를 저장 배치
const arr : [JSX.Element,JSX.Element,JSX.Element] = [ aaa, bbb, bbb ]
const arr2 : JSX.Element[] = [ aaa, bbb, bbb ] //타입 다 같으면 이렇게 줄여 쓸 수 있음
// 6번 실습 ) 리스트에 보여줄 대량이 데이터 배열
let datas:String[] = ["aaa", "bbbb", "ccc", "ddd","aaa", "bbbb", "ccc", "ddd","aaa", "bbbb", "ccc", "ddd"]
// 스트링은 뷰를 보여줄 수 없어서 adaper를 만들어야함 - 안드
// 자스에서는 배열이 가진 메소드 중 'forEach' 사용하여 만들기
// forEach ( function (벨류, 인덱스, 어레이) ) - 각각에 접근할 때 마다 function 호출
// 하지만 접근해서 새로 만든 결과물을 받을 방법이 없음
// 따라서, forEach와 같은 역할이지만 return이 있는 ''''map()'''' 을 사용하여 한다!!
// 배열의 map() 메소드를 이용하여 리턴 하여 온 것을 새로운 배열에 넣는다
// 컴포넌트 형태로 출력하기 위해 datas를 컴포넌트를 포함한 새로운 배열로 만든다
return (
<View style={style.root}>
<Text style={style.title}>List Layout Test</Text>
{/* 1. 변수에 JSX 문법을 사용한 컴포넌트를 저장한 후에 사용 */}
{ aaa }
{/* 변수에 저장되어 있으니 여러번 사용가능 */}
{ aaa }
{/* { aaa } */}
{/* 2. 변수 하나에 여러개 컴포넌트 넣어서 사용하기 */}
{ bbb }
{/* { bbb } */}
{/* 3. 함수(메소드)를 호출하여 JSX컴포넌트를 리턴받아 사용하기 */}
{this.showItemView()}
{/* {this.showItemView()} */}
{/* 4. 함수를 호출하면서 파라미터 전달 */}
{ this.showItemView2("sam", "first", "indigo") }
{/* { this.showItemView2("jeni", "second", "pink") } */}
{/* 5. 배열변수에 jsx컴포넌트들을 요소로 넣어서 사용하기 */}
{/* SJ는 배열을 출력하면 자동으로 요소값을 나열함!! */}
{/* { arr } */}
{/* 6. 실제 앱 개발과정에서는 대량의 데이터가 JSX컴포넌트 이기 보단 일반 데이터인 경우가 많음 */}
{/* {datas} Error - 일반 스트링 데이터는 컴포넌트가 아님*/}
{datas.map( function( value, index, array ){
return (
// 배열로 만든 아이템뷰는 식별자로 key 속성을 반드시 필수로 요구함
<View key={index} style={style.itemView}>
<Text>{value}</Text>
</View>
)
} )
}
{/* 배열의 .map() 메소드 이용한 단점 */}
{/* 1. key 속성을 개별적으로 지적해야 하는 것 */}
{/* 2. 개수가 많아져도 자동 스크롤 되지 않음 */}
{/* 3. 가로 스크롤이나 스크롤바 제어 등 리트스뷰에서의 기능이 없음 */}
{/* 그래서 RN에서는 리스트뷰용 컴포넌트를 별도로 제공 */}
</View>
)
}
//4번 실습) 메소드
showItemView2(name:String, btnTitle:String, btnColor:String) : JSX.Element{
return (
<View style={{margin : 2}}>
<Text>{name}</Text>
<Button title={btnTitle} color={btnColor}></Button>
</View>
)
}
// 3번 실습) 사용할 메소드
showItemView():JSX.Element{
return (
<View style={{marginTop:16}}>
<Text>Nice world</Text>
<Button title='press me'></Button>
</View>
)
}
}
//스타일스트 객체
const style= StyleSheet.create({
root:{ flex:1, padding:16, },
title:{ fontSize:24, fontWeight:'bold', color:'black'},
itemView:{
padding:16,
margin:8,
borderWidth:1,
borderRadius:8,
}
})
💡 배열의 .map() 메소드 이용한 단점
- key 속성을 개별적으로 지정해야 하는 것
- 개수가 많아져도 자동 스크롤 되지 않음
- 가로 스크롤이나 스크롤바 제어 등 리트스뷰에서의 기능이 없음
=> 그래서 RN에서는 리스트뷰용 컴포넌트를 별도로 제공
import React, {Component} from "react";
import { View, Text, StyleSheet, FlatList, ListRenderItemInfo } from "react-native";
export default class Maine extends Component {
//RN에서 ListView의 역할을 하는 컴포넌트 2가지 종류가 있음
// 1. FlatList : 일반적인 리스트 뷰
// 2. SectionList : 섹션에 따라 구분 지어서 리스트할 때 사용
//먼저 FlatList에서 사용할 대량의 데이터 배열 - 데이터변경에 실시간 대응하려면 state 사용
state : React.ComponentState = {
//1.일반 간단한 string 문자열 배열
datas : ["aaa", "bbbb", "ccc", "ddd"], //객체의 멤버로 만들땐 자료형 쓰지 않음
}
render(): React.JSX.Element {
return (
<View style={style.root}>
<Text style={style.title}>FlatList</Text>
{/* 1. FlatList : RN의 기본 리스트뷰 컴포넌트 */}
{/* 필수 2가지 속성(props) - data, renderItem */}
{/* data : 대량의 데이터, FlatList기 보여줄 데이터들 */}
{/* renderItem : 아이템 뷰 레이아웃, 아이템 하나의 모양(컴포넌트)를 만들어서 리턴하는 ''콜백함수'' 지정 */}
{/* <FlatList data={this.state.datas} renderItem={ ( obj : ListRenderItemInfo<any> ) => { //파라미터 1개 : 렌더링할 아이템정보 객체 (parameter) obj: ListRenderItemInfo<any>
return <Text> {obj.index} : {obj.item} </Text>
} }></FlatList> */}
{/* 위 renderIte의 obj 파라미터 객체를 구조분해 할당!! */}
<FlatList data={this.state.datas}
renderItem={ ( {item, index} ) => { //obj객체의 idex와 item 멤버를 뽑아옴
return <Text> {index} : {item} </Text>
} }></FlatList>
</View>
)
}
}
//스타일
const style=StyleSheet.create({
root: {flex:1, padding:16},
title: {fontSize :24, fontWeight : "bold", color:"black", textAlign:"center", paddingTop:8, paddingBottom:16},
itemView: {
borderWidth:1,
borderRadius:8,
margin: 8,
padding:8,
}
})
import React, {Component} from "react";
import { View, Text, StyleSheet, FlatList, ListRenderItemInfo, TouchableOpacity, Alert, Image } from "react-native";
export default class Maine extends Component {
//RN에서 ListView의 역할을 하는 컴포넌트 2가지 종류가 있음
// 1. FlatList : 일반적인 리스트 뷰
// 2. SectionList : 섹션에 따라 구분 지어서 리스트할 때 사용
//먼저 FlatList에서 사용할 대량의 데이터 배열 - 데이터변경에 실시간 대응하려면 state 사용
state : React.ComponentState = {
//1.일반 간단한 string 문자열 배열
datas : ["aaa", "bbbb", "ccc", "ddd","aaa", "bbbb", "ccc", "ddd","aaa", "bbbb", "ccc", "ddd"], //객체의 멤버로 만들땐 자료형 쓰지 않음
//2. 텍스트가 2개 이미지가 1개 아이템 뷰 데이터들
items : [
{name : "sam", message:"Hello", img:{uri: 'https://cdn.pixabay.com/photo/2017/12/15/13/51/polynesia-3021072_640.jpg'}},
{name : "lee", message:"hhihi", img:{uri: 'https://cdn.pixabay.com/photo/2018/08/21/23/29/forest-3622519_640.jpg'}},
{name : "kim", message:"hehehe", img:{uri: 'https://cdn.pixabay.com/photo/2017/06/07/10/47/elephant-2380009_640.jpg'}},
{name : "lisa", message:"hohoho", img:{uri: 'https://cdn.pixabay.com/photo/2016/11/14/04/45/elephant-1822636_640.jpg'}},
{name : "jisoo", message:"ohoho", img:{uri: 'https://cdn.pixabay.com/photo/2017/05/08/13/15/bird-2295431_640.jpg'}},
{name : "minee", message:"bye", img:{uri: 'https://cdn.pixabay.com/photo/2017/01/14/12/59/iceland-1979445_640.jpg'}},
{name : "jene", message:"bye bye", img:{uri: 'https://cdn.pixabay.com/photo/2017/02/20/18/03/cat-2083492_640.jpg'}},
{name : "rose", message:"안녕", img:{uri: 'https://cdn.pixabay.com/photo/2016/03/27/22/22/fox-1284512_640.jpg'}},
{name : "bae", message:"내일봐", img:{uri: 'https://cdn.pixabay.com/photo/2014/11/30/14/11/cat-551554_640.jpg'}},
{name : "moon", message:"리액트", img:{uri: 'https://cdn.pixabay.com/animation/2023/03/28/02/15/02-15-52-868_512.gif'}},
{name : "son", message:"네이티브", img:{uri: 'https://cdn.pixabay.com/animation/2022/07/29/16/42/16-42-21-375_512.gif'}},
{name : "big", message:"재밌다", img:{uri: 'https://cdn.pixabay.com/animation/2023/05/15/03/12/03-12-04-14_512.gif'}},
]
}
render(): React.JSX.Element {
return (
<View style={style.root}>
<Text style={style.title}>FlatList</Text>
{/* 1. FlatList : RN의 기본 리스트뷰 컴포넌트 */}
{/* 필수 2가지 속성(props) - data, renderItem */}
{/* data : 대량의 데이터, FlatList기 보여줄 데이터들 */}
{/* renderItem : 아이템 뷰 레이아웃, 아이템 하나의 모양(컴포넌트)를 만들어서 리턴하는 ''콜백함수'' 지정 */}
{/* <FlatList data={this.state.datas} renderItem={ ( obj : ListRenderItemInfo<any> ) => { //파라미터 1개 : 렌더링할 아이템정보 객체 (parameter) obj: ListRenderItemInfo<any>
return <Text> {obj.index} : {obj.item} </Text>
} }></FlatList> */}
{/* 위 renderIte의 obj 파라미터 객체를 구조분해 할당!! */}
{/* <FlatList data={this.state.datas}
renderItem={ ( {item, index} ) => { //obj객체의 idex와 item 멤버를 뽑아옴
return <Text> {index} : {item} </Text>
} }></FlatList> */}
{/* 아이템뷰의 클릭 이벤트 처리 */}
{/* <FlatList data={this.state.datas}
renderItem={ ( {item, index} ) => //리턴값 하나라서 중괄호랑 return 삭제, 파라미터에 {} 있으면 무조건 구조분해 할당임
<TouchableOpacity style={style.itemView} onPress={() => Alert.alert(item)}>
<Text>index : {index}</Text>
<Text>data : {item}</Text>
</TouchableOpacity>
}></FlatList> */}
{/* 2. 텍스트 2개와 이미지 1개 아이템 뷰 모양 */}
<FlatList data={this.state.items}
renderItem={ ( {item, index} ) => //리턴값 하나라서 중괄호랑 return 삭제, 파라미터에 {} 있으면 무조건 구조분해 할당임
<TouchableOpacity style={style.itemWarp} onPress={() => this.showAlert(item, index)}>
<Image source={item.img} style={style.itemImg}></Image>
<View>
<Text style={style.itemName}>{item.name}</Text>
<Text style={style.itemMsg}>{item.message}</Text>
</View>
</TouchableOpacity>
}></FlatList>
</View>
)
}
showAlert = (item : any, index : number) => {
Alert.alert(item.name + " : " + index)
}
}
//스타일
const style=StyleSheet.create({
root: {flex:1, padding:16},
title: {fontSize :24, fontWeight : "bold", color:"black", textAlign:"center", paddingTop:8, paddingBottom:16},
itemView: {
borderWidth:1,
borderRadius:8,
margin: 8,
borderRadius:8,
},
itemWarp: {
flexDirection : "row",
borderWidth : 1,
borderRadius:4,
borderRadius:4,
marginBottom: 12,
},
itemImg : {
width : 120,
height : 120,
resizeMode : "cover",
marginRight : 8,
},
itemName : {
fontSize : 24,
fontWeight : "bold",
color : "black",
},
itemMsg : {
fontSize : 16,
fontStyle : "italic",
}
})
💡 SectionList 객체의 필수!
SectionList의 세션 하나 객체에는 반드시 title, data 2개의 프로퍼티가 필요하다, 이름 정해져있음 못 바꿈!!!
💡 SectionList에 필요한 필수 속성 3개
1. sections : 세션에 해당하는 title과 data를 가진 배열
2. renderSectionHeader : 세션 별 title영역이 그려질 render 컴포넌트를 리턴하는 콜백함수 지정
3. renderItem : section별 item들(string)이 그려질 렌더뷰를 리턴하는 콜백 함수 지정[FlatList와 동일]
import React, {Component} from "react";
import { View, Text, StyleSheet, SectionList, TouchableOpacity, Alert } from "react-native";
export default class Maine extends Component {
//리스트뷰의 섹션별 헤더뷰를 가질 수 있는 SectionList 컴포넌트
//대량의 데이터
state:React.ComponentState = {
//SectionList의 세션 하나 객체에는 반드시 title, data 2개의 프로퍼티가 필요하다, 이름 정해져있음 못 바꿈!!!
sectionDatas : [
{title: '한식', data:['백반', '비빔밥', '된장찌개']},
{title: '중식', data:['짜장면', '짬뽕', '탕수육']},
{title: '일식', data:['초밥', '라멘', '덮밥']},
]
}
render(): React.JSX.Element {
return (
<View style={style.root}>
<Text style={style.title}>SectionList</Text>
{/* SectionList에 필요한 필수 속성 3개 */}
{/* 1. sections : 세션에 해당하는 title과 data를 가진 배열 */}
{/* 2. renderSectionHeader : 세션 별 title영역이 그려질 render 컴포넌트를 리턴하는 콜백함수 지정 */}
{/* 3. renderItem : section별 item들(string)이 그려질 렌더뷰를 리턴하는 콜백 함수 지정[FlatList와 동일]*/}
<SectionList
sections={this.state.sectionDatas} //대량의 데이터 주기
renderSectionHeader={({section}) => { //헤더모양 - 위 sections 속성에 지정한 배열의 요소개수만큼 반복하여 헤더영역 컴포넌트 리턴
return (
<View style={style.sectionHeader}>
<Text style={style.sectionTitle}>{section.title}</Text>
</View>
)
}}
renderItem={({item, index, section})=>{ //아이템
return (
//section 별로 index번호가 다시 0부터 나옴
<TouchableOpacity style={style.sectionItem} onPress={() => Alert.alert(index +" : " +item+ "~" + section.title)}>
<Text>{item}</Text>
</TouchableOpacity>
)
}}
>
</SectionList>
</View>
)
}
}
//스타일
const style=StyleSheet.create({
root: {flex:1, padding:16},
title: {
fontSize :24,
fontWeight : "bold",
color:"black",
textAlign:"center",
paddingTop:8,
paddingBottom:16
},
sectionHeader : {
padding:8,
backgroundColor: 'grey',
},
sectionTitle : {
fontSize : 18,
fontWeight : 'bold',
color : 'black',
},
sectionItem : {
padding : 8
}
})