본문 바로가기

React Native

[처음 배우는 리액트 네이티브] 3장. 컴포넌트

처음 배우는 리액트 네이티브

 

 

 

 

3장. 컴포넌트

 

 

재사용할 수 있는 조립 블록으로 화면에 나타나는 UI 요소

와이어프레임 : 최종 화면에 구성될 콘텐츠를 간단히 요약해서 보여주는 것

 

 

 


1. JSX

 

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
	return (
    	<View style={styles.container}>
        	<Text>Open up App.js to start working on your app!</Text>
            	<StatusBar style="auto" />
        </View>
    );
}

const styles = StyleSheet.create({
	container: {
    	flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
	},
});

 

 

1) 하나의 부모

  • JSX에서는 여러 개의 요소를 표현할 경우 반드시 하나의 부모로 감싸야 함 ➡ 반환되는 요소가 하나여야 함 (위의 코드에선 View로 감싸지 않으면 오류)
  • View는 UI를 구성하는 가장 기본적인 요소로 웹 프로그래밍에서 <div>와 비슷한 역할을 하는 컴포넌트
  • 컴포넌트를 반환할 때 View 컴포넌트처럼 특정 역할을 하는 컴포넌트로 감싸지 않고 여러 개의 컴포넌트를 반환하고 싶은 경우 Fragment 컴포넌트 사용
import { StatusBar } from 'expo-status-bar';
import React, { Fragment } from 'react';
import { Text } from 'react-native';

export default function App() {
	return (
    		<Fragment>
        		<Text>Open up App.js ~~ </Text>
            		<StatusBar style="auto" />
		</Fragment>
	);
}
  • Fragment 컴포넌트 단축 문법
import { StatusBar } from 'expo-status-bar';
import React, { Fragment } from 'react';
import { Text } from 'react-native';

export default function App() {
	return (
    	  	<>
        		<Text>Open up App.js ~~ </Text>
            		<StatusBar style="auto" />
		</>
	);
}

 

 

 

 

2) 자바스크립트 변수

JSX는 내부에서 자바스크립트의 변수를 전달하여 이용 가능

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
	const name = 'bbirong';
	return (
    	<View style={styles.container}>
        	<Text style={styles.text}>My name is {name}</Text>
            	<StatusBar style="auto" />
        </View>
    );
}

const styles = StyleSheet.create({
	container: {
    	flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
	},
    text: {
    	fontSize: 30,
	},
});

 

 

 

 

 

3) 자바스크립트 조건문

  • JSX에서도 자바스크립트의 조건문 이용해 상황에 따라 다른 요소 출력 가능
  • 하지만 제약이 있으므로 복잡한 조건인 경우 JSX 밖에서 조건에 따른 값을 설정하고 JSX 내에서 사용하는 조건문에서는 최대한 간단하게 작성하는 것이 좋음

 

 

 

✔if 조건문

JSX는 if문을 즉시실행함수 형태로 작성해야 함

...
export default function App() {
	const name = 'bbirong';
	return (
    	<View style={styles.container}>
        	<Text style={styles.text}>
            	  {(() => {
                	if (name === 'YK') return 'My name is YK';
                    	else if (name === 'bbirong') return 'My name is bbirong';
                    	else return 'My name is React Native';
		  })()}
                </Text>
            	<StatusBar style="auto" />
        </View>
    );
}
...

 

 

삼항 연산자

...
export default function App() {
	const name = 'bbirong';
	return (
    	<View style={styles.container}>
        	<Text style={styles.text}>
            	  My name is {name === 'bbirong' ? 'bbirong k' : 'React Native'}
                </Text>
            	<StatusBar style="auto" />
        </View>
    );
}
...

 

 

AND/OR 연산자

...
export default function App() {
	const name = 'bbirong';
	return (
    	<View style={styles.container}>
        	{name === 'bbirong' && (
        		<Text style={styles.text}>My name is bbirong</Text>
            	)}
            	{name !== 'bbirong' && (
            		<Text style={styles.text}>My name is not bbirong</Text>
		)}
            	<StatusBar style="auto" />
        </View>
    );
}
...

JSX에서 false는 렌더링되지 않음 ➡ AND 연산자 앞의 조건이 참일 때 뒤의 내용 나타나고, 거짓인 경우 나타나지 않음

OR 연산자는 AND 연산자와 반대로 앞의 조건이 참인 경우 나타나지 않고, 거짓인 경우 내용이 나타남

 

 

 

4) null과 undefined

null은 허용

undefined는 오류 발생

 

 

5) 주석

/**/ 사용

태그 안에서 주석을 사용할 때는 자바스크립트처럼 //나 /**/ 사용 가능

 

 

6) (인라인) 스타일링

JSX는 HTML과 달리 style에 문자열로 입력하는 것이 아니라 객체 형태로 입력해야 함.

background-color처럼 하이픈(-)으로 연결된 이름은 하이픈을 제거하고 카멜표기법으로 backgroundColor처럼 작성

 

 

 

 

 

 


2. 컴포넌트

 

 

  • 재사용이 가능한 조립블록으로 화면에 나타나는 UI 요소
  • 단순히 UI 역할만 하는 것이 아니라 부모로부터 받은 속성(props)이나 자신의 상태(state)에 따라 표현이 달라지고 다양한 기능을 수행
  • 데이터와 UI 요소의 집합체

 

 

1) 내장 컴포넌트(Core Components)

리액트 네이티브에서는 다양한 내장 컴포넌트 제공

https://reactnative.dev/docs/components-and-apis 

 

Core Components and APIs · React Native

React Native provides a number of built-in Core Components ready for you to use in your app. You can find them all in the left sidebar (or menu above, if you are on a narrow screen). If you're not sure where to get started, take a look at the following cat

reactnative.dev

 

View 컴포넌트Text 컴포넌트는 대표적인 내장 컴포넌트 중 하나

 

 

이번 장에서는 Button 컴포넌트를 사용해 실습

https://reactnative.dev/docs/button 

 

Button · React Native

A basic button component that should render nicely on any platform. Supports a minimal level of customization.

reactnative.dev

위의 문서를 확인해보면 설명/사용 예제/설정할 수 있는 속성들의 목록/각 속성들의 설명 확인 가능.

이렇게 컴포넌트 사용 시 문서 참고하는 것이 많이 도움 됨.

 

 

Button 컴포넌트를 사용하고 title과 onPress 속성 지정

  • title 속성은 버튼 내부에 출력되는 텍스트
  • onPress 속성에는 버튼이 눌렸을 때 호출되는 함수를 지정

 

<src/App.js>

import React from 'react';
import { Text, View, Button } from 'react-native';

const App = () => {
	return (
    	<View
        	style={{
            	flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
			}}
		>
        
           <Text style={{ fontSize: 30, marginBotton: 10 }}>Button Component</Text>
           <Button title="Button" onPress={() => alert('Click!!!') />
        </View>
	);
};

export default App;

 

<App.js>

import App from './src/App';

export default App;

 

 

안드로이드와 iOS의 Button 컴포넌트의 모습이 다름

https://reactnative.dev/docs/button#color 

 

Button · React Native

A basic button component that should render nicely on any platform. Supports a minimal level of customization.

reactnative.dev

 

Button 컴포넌트의 color 속성은, iOS에서는 텍스트 색을 나타내는 값이지만 안드로이드에서는 버튼의 바탕색을 나타내는 값

iOS와 안드로이드 모두 확인하면서 개발하는 습관 들이는 것이 중요

 

 

 

 

 

2) 커스텀 컴포넌트(Custom Component) 만들기

 

리액트 네이티브에서 제공하는 여러 컴포넌트를 조합해서 새로운 컴포넌트 제작 가능

 

앞에서 사용해본 Button 컴포넌트는 iOS와 안드로이드에서 다른 모습으로 렌더링된다는 단점

TouchableOpacity 컴포넌트 Text 컴포넌트를 이용해 Button 컴포넌트를 대체할 MyButton 컴포넌트

리액트네이티브 0.63버전에서 Pressable 컴포넌트 추가됨. 0.63버전 이상을 사용하거나 Pressable 컴포넌트를 제공하는 리액트네이티브 버전을 사용하는 Expo의 경우 TouchableOpacity 대신 Pressable 사용.

 

 

 

<src/components/MyButton.js>

//JSX는 React.createElement를 호출하는 코드로 컴파일되므로 컴포넌트를 작성할 때 반드시 아래 코드 작성해줘야 함
import React from 'react';
import { TouchableOpacity, Text } from 'react-native';

const MyButton = () => {
	return (
    	<TouchableOpacity>
        	<Text style={{ fontSize: 24 }}>My Button</Text>
        </TouchableOpacity>
	);
};

export default MyButton;

 

<src/App.js>

import React from 'react';
import { Text, View } from 'react-native';
import MyButton from './components/MyButton';

const App = () => {
	return (
    	<View
        	style={{
            	flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
			}}
		>
        
           <Text 
           	  style={{ 
                 fontSize: 30, 
                 marginBotton: 10,
               }}
            >
              My Button Component
           </Text>
           <MyButton />
        </View>
	);
};

export default App;

 

 

 

https://reactnative.dev/docs/touchableopacity 

 

TouchableOpacity · React Native

If you're looking for a more extensive and future-proof way to handle touch-based input, check out the Pressable API.

reactnative.dev

https://reactnative.dev/docs/touchablewithoutfeedback 

 

TouchableWithoutFeedback · React Native

If you're looking for a more extensive and future-proof way to handle touch-based input, check out the Pressable API.

reactnative.dev

 

리액트 네이티브 문서에서 TouchableOpacity 컴포넌트에 지정 가능한 속성을 찾아보면 onPress 없음.

하지만 TouchableOpacity 컴포넌트는 onPress 속성을 제공하는 TouchableWithoutFeedback 컴포넌트를 상속받았기 때문에 onPress 속성 사용 가능.

 

 

<src/components/MyButton.js>

...
const MyButton = () => {
	return (
    	<TouchableOpacity
        	style={{
            	backgroundColor: '#3498db',
                padding: 16,
                margin: 10,
                borderRadius: 8,
             }}
             onPress={() => alert('Click!!!')}
         >
            <Text style={{ color:'white', fontSize: 24 }}>My Button</Text>
        </TouchableOpacity>
	);
};
...

 

 

 

 

 


3. props와 state

 

 

1) props

📍읽기 전용

  • properties를 줄인 표현
  • 부모 컴포넌트로부터 전달된 속성값 혹은 상속받은 속성값
  • 부모 컴포넌트가 자식 컴포넌트의 props를 설정하면 자식 컴포넌트에서는 해당 props를 사용할 수 있지만 변경하는 것은 불가능 
  • props 변경이 필요한 경우 props를 설정 및 전달한 부모 컴포넌트에서 변경해야 함

 

 

 

2) state