
리액트 기본 제공 함수들.
리액트 네이티브는 리액트 (React.js) 라이브러리 기반으로 만들어진 프레임워크이기에 기본 구조는 리액트를 닮음
@ 리액트 -> 컴포넌트마다 데이터를 보유/관리할 수 있고, 그 데이터를 state 라고 부름
state 는 리액트 라이브러리에서 제공해주는 useState 로 생성하고, setState 로 정/변경
state 로 관리되는 데이터가 변경되면 화면이 바뀜
UI = component(state)
UI = f(state)
화면이 그려진 다음 가장 먼저 실행되는 함수.
보통 데이터를 준비할 때 사용.
데이터 준비 = 데이터를 서버로부터 혹은 어디선가로부터 받은 후 state 에 반영한다는 뜻
실행 순서 = 화면 그려짐 -> useEffect 가 데이터 준비 -> state 가 업데이트 -> 화면 다시 그려짐
useEffect(() => {
...화면이 그려진 다음 가장 먼저 실행되야 할 코드 작성
}, [])
[state, setState] 에서
state는 이 컴포넌트에서 관리될 상태 데이터를 담고 있는 변수
setState는 state를 변경시킬때 사용해야하는 함수
모두 다 useState가 제공해줌
useState()안에 전달되는 값은 state 초기값
import React,{useState,useEffect} from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView} from 'react-native';
import data from '../data.json';
export default function MainPage() {
// state 설정하고
const [state,setState] = useState([])
// 데이터 준비 (현재 useEffect 를 거쳐야 state 에 데이터가 담김)
useEffect(() => {
setState(data)
}, [])
// 상태에서 data 꺼내 옴
let tip = state.tip;
return (
// 전후 생략
<View style={styles.cardContainer}>
{tip.map((content,i)=>{
return (<Card content={content} key={i}/>)})
}
</View>
);
}
const styles = StyleSheet.create({});
위와 같이 작성되면
앱 기동 -> return () 구문 안에서 state 를 꺼내 쓰려할 때,
useEffect 를 거치치 않았기 때문에 처음 state에 데이터가 담기지 않아서,
꺼내올 수 없고, 오류가 발생함
-> state, component, useEffect 를 이용 로딩화면을 만들어 해결 가능
import React,{useState,useEffect} from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView} from 'react-native';
import data from '../data.json';
// 로딩 화면 하나 만들어서 설정하고
import Loading from '../components/Loading';
export default function MainPage() {
// state 설정하고
const [state,setState] = useState([])
// 컴포넌트에 복수의 state 작성해도 ok
// state 이름과 함수는 자유롭게 정의 가능
// 초기 상태 값으로 list, true/false, dictionary, number, text 등 다양한 값이 들어갈 수 있음
const [ready, setReady] = useState(true)
// 데이터 준비 (useEffect 를 거쳐야 state 에 데이터가 담김)
useEffect(() => {
// 뒤의 1000 숫자 = 1초
// setTimeout(() => {}, 1000) 은 , 뒤에 있는 숫자 (1초)만큼 지연됐다가 안에 있는 코드가 실행되는 지연 함수
setTimeout(()=>{
setState(data)
setReady(false)
}, 1000)
},[])
// 상태에서 data 꺼내 옴
let tip = state.tip;
// 삼항연산자 사용, 처음 ready 값은 true 이므로 ? 바로 뒤의 값이 반환되어 화면이 그려짐
// useEffect로 인해 데이터 준비 -> ready 값이 변경되면 : 뒤의 값이 반환되어 화면이 다시 그려짐
return ready ? <Loading/> : (
// 전후 생략
<View style={styles.cardContainer}>
{tip.map((content,i)=>{
return (<Card content={content} key={i}/>)})
}
</View>
);
}
const styles = StyleSheet.create({});
1) ready 값이 true이므로 return 구문에서 ? 물음표 바로 뒤의 Loading 컴포넌트가 화면에 그려짐
2) 화면이 그려지고 난다음, 1초 후 상태값들이 채워지고 변경됨
3) ready 상태 값이 false가 됨
4) 상태값이 변경되었으므로 화면이 다시 그려짐
5) ready 값이 false 이므로 return 구문에서 : 콜론 뒤의 MainPage 컴포넌트가 화면에 그려짐
엑스포의 기능 이용하는 방법도 있음
import AppLoading from 'expo-app-loading';
먼저 카테고리의 state 를 만들고,각 카테고리에 연결할 함수를 만들어서
각 카테고리에 따라 카테고리 state 상태 데이터를 새롭게 구성해준다.
import React,{useState,useEffect} from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView} from 'react-native';
import data from '../data.json';
import Loading from '../components/Loading';
export default function MainPage() {
// 기존 데이터를 저장한 state
const [state, setState] = useState([])
// 카테고리에 따라 다른 데이터를 그때그때 저장관리할 state
const [cateState, setCateState] = useState([])
const [ready, setReady] = useState(true)
useEffect(() => {
setTimeout(()=>{
// 기존 데이터로 모두 초기화 준비, 아무 카테고리 선택 안했을 때 모두 출력
let tip = data.tip;
setState(tip)
setCateState(tip)
setReady(false)
}, 1000)
},[])
const category = (cate) => {
if(cate == 'All'){
// All 이면 원래 데이터를 담고 있는 상태값으로 다시 초기화
setCateState(state)
}else{
setCateState(state.filter((d))=>{
return d.category == cate
})
}
}
return ready ? <Loading/> : (
// 전후 생략
<ScrollView style={styles.middleContainer} horizontal indicatorStyle={"white"}>
<TouchableOpacity style={styles.middleButtonAll} onPress={()=>{category('All')}}><Text style={styles.middleButtonTextAll}>All</Text></TouchableOpacity>
<TouchableOpacity style={styles.middleButton01} onPress={()=>{category('Lifehack')}}><Text style={styles.middleButtonText}>Lifehack</Text></TouchableOpacity>
<TouchableOpacity style={styles.middleButton03} onPress={()=>{category('For Cats')}}><Text style={styles.middleButtonText}>For Cats</Text></TouchableOpacity>
<TouchableOpacity style={styles.middleButton04} onPress={()=>{category('Bookmarks')}}><Text style={styles.middleButtonText}>Bookmarks</Text></TouchableOpacity>
</ScrollView>
<View style={styles.cardContainer}>
{cateState.map((content,i)=>{
return (<Card content={content} key={i}/>)})
}
</View>
);
}
const styles = StyleSheet.create({});
setCateState(state.filter((d))=>{ return d.category == cate })
배열.filter 를 걸면 배열의 요소를 하나씩 담아서 함수를 호출함.
리스트에서 조건문을 만족하는 내용을 모아 재 리스팅.
state 라는 json 리스트에서 각 딕셔너리를 d 라고 하고 리스트를 반복으로 돌렸을 때
-> d 딕셔너리의 키값 중 하나인 category 가 cate 의 내용과 일치하는 (true) 딕셔너리만을 가져와서
-> json 형태로 재 리스팅