이번 시간에는 리액트 네이티브 화면 구성을 어떻게 하는지 기본적인 스타일과 면적을 결정하는 방법을 보도록 하겠습니다.
Style
모든 코어 컴포넌트들은 style prop를 사용할 수 있습니다. 스타일의 이름과 값은 웹에서 사용되는 css와 동일하지만 다른 점이 있습니다. 표기할 때 낙타 법 표기법으로 사용합니다. 예시를 들자면 background-color대신 backgroundColor를 사용합니다.
Text 컴포넌트 내부에 스타일을 줄줄이 바로 작성할 수도 있습니다. 예제 코드와 무언가 빠르게 확인할 때는 유용합니다. 하지만 가독성과 코드 작성의 편리성을 위해서 styles이라는 배열을 만들어서 컴포넌트에다가 디자인 작업을 진행합니다. 스타일 배열을 만들어 놓고 필요로 하는 스타일을 입혀주시면 됩니다.
View 컴포넌트에는 container 스타일을 줘서 View 내부에 모든 컴포넌트에 적용을 하였고, Text 컴포넌트에는 원하는 스타일만 주는 모습도 보실 수 있습니다.
View 컴포넌트를 사용해서 블록들을 구분 지어줍니다. 면적을 고정시키기 위해서 width, height 스타일을 직접 명시를 해주시면 됩니다. 블록의 구분을 위해서 배경색도 부여했습니다 :) 크게 어렵지 않죠?
Flex Dimensions
우리의 모바일은 수십 가지의 종류가 있습니다. 그렇기에 화면의 크기도 모두 달라지는데요. 컴포넌트별로 상대적으로 크기를 지정해줄 필요성이 있습니다. 위의 방식으로 크기를 고정시켜놓으면 모바일에 따라 스크린이 크던 작던 크기가 고정되어 보입니다. 그럼 사용자는 좋지 않은 UI 구성을 보게 되는데요.
이런 문제를 해결하고자 화면 크기별에 따른 상대적으로 면적을 지정하는 방법이 있습니다. 스타일에 flex라는 속성을 부여해주시면 돼요.
쉬운 이해를 위해서 코드와 화면을 같이 보겠습니다. 첫 번째 전체 뷰에는 고정된 높이 300 그리고 화면을 잘 보기 위해서 탑으로부터 떨어질 수 있도록 top 50을 부여했습니다.
전체 뷰 높이를 300으로 고정시켜 놓고 내부에 3개의 뷰 3개를 선언을 해놓았는데요. 이 내부 뷰에는 모두 flex를 부여했습니다. flex는 주어진 스크린의 상대적인 크기를 나눠 갖습니다. 각 뷰들의 비율은 부모 높이 300이라는 크기 안에서 1:2:3이 되는 겁니다.
코드는 JS로 작성이 됩니다. RN은 ES2015(ES6-구 JS가 아닌 신 JS버전을 뜻합니다)를 지원합니다. 그렇기에 ES6로 JS 코드로 작성을 해주셔야 됩니다. 익숙지 않은 구조가 보입니다. 리액트를 학습을 하셨다면 아시겠지만 JS에서 사용하지 않는 문법인 JSX 문법이 있습니다. 리턴 안에 보시면 <View><Text>Hello, World!</Text></View> 코드가 있습니다.
JSX는 리액트(네이트브)에서 사용되는 문법으로써 JS에 XML을 사용하는 문법입니다. <View>, <Text>는 흔히 html에서 사용하는 <div>, <span> 사용하는 태그처럼 리액트(네이티브)에서 사용되는 태그들입니다.
HelloWorldApp은 컴포넌트입니다. 리액트는 컴포넌트 기반으로 코드를 작성합니다. 컴포넌트는 화면을 보여주는 하나하나의 구성입니다. 지금은 Hello World! 를 보여주는 컴포넌트입니다. 컴포넌트는 render() 함수를 필요로 하고 이는 JSX를 리턴이 됩니다.
여기서 또 JSX 내부에서 {}를 씌어 JS를 사용하시는 모습도 보실 수 있으시고요. View는 스타일과 레이아웃을 잡을 때 자주 사용하는 컴포넌트입니다.
이렇게 props를 사용해주시면 컴포넌트를 다른 컴포넌트에서도 재사용하실 수 있습니다. props가 단순히 부모로부터 전달받는 데이터가 아닌 재사용을 위한 프로퍼티라는 의미도 잘 봐주세요 :)
3. State
리액트에서 데이터를 다루는 방법은 2가지가 있습니다. 첫 번째로는 위에서 설명드린 props와 두 번째는 이번에 설명드릴 state입니다. props 값은 부모로부터 전달받고 컴포넌트의 생명주기 동안에 값이 고정이 됩니다.
이와 다르게 변화되는 값을 다루기 위해서는 State를 사용하셔야 됩니다. 일반적으로는 state값은 생성자에서 초기화를 하고 setState() 함수를 통해서 값을 변경합니다. state값은 직접 변경하지 않습니다.
예제 코드를 보도록 하겠습니다.
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
class Blink extends Component {
componentDidMount(){
// Toggle the state every second
setInterval(() => (
this.setState(previousState => (
{ isShowingText: !previousState.isShowingText }
))
), 1000);
}
//state object
state = { isShowingText: true };
render() {
if (!this.state.isShowingText) {
return null;
}
return (
<Text>{this.props.text}</Text>
);
}
}
export default function App() {
return (
<View style={styles.container}>
<Text>Hello World!</Text>
<Blink text='I love to blink' />
<Blink text='Yes blinking is so great' />
<Blink text='Why did they ever take this out of HTML' />
<Blink text='Look at me look at me look at me' />
</View>
);
}
(스타일 코드는 위와 동일합니다)
Blink 컴포넌트를 App에서 호출합니다. 이때 text props를 전달해주는 모습도 보실 수 있습니다.
state를 초기화(state = { isShowingText:true })를 해준 이후에 render가 됩니다.
컴포넌트가 마운트 된다면 componentDidMount() 함수가 호출되는데 이때, setInterval 함수를 통해서 isShowingText 값을 스위칭시켜주고 있습니다. setState() 함수를 통해서 말이죠.
setState() 함수가 호출될 때 BlinkApp 컴포넌트는 다시 렌더가 됩니다.
다시 렌더가 될 때마다 isShowingText 값이 true인지 false인지 따라서 <Text> 또는 null이 렌더가 됩니다. 그럼 화면이 깜박깜박 되겠죠:)
실제 개발에서는 state변경을 사용자 입력 또는 서버로부터의 응답을 받아서 setState() 됩니다. 이점 참고를 해주세요.
실제 모습은 깜박입니다 :)
이번 시간에는 React Native의 기본 모습과 props와 state를 학습했습니다.