일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 정리
- 리액트 네이티브 시작하기
- React Native
- 리액트 네이티브 프로젝트 생성
- 딥러닝
- 스터디
- 모두의 네트워크
- 깃허브 로그인
- 깃 연동
- 자바
- SQL
- 지네릭스
- 모두를 위한 딥러닝
- 데베
- 머신러닝
- 팀플회고
- 백준 4949번
- HTTP
- 네트워크
- 모두의네트워크
- 깃허브 토큰 인증
- 문자열
- 모두를위한딥러닝
- 백준
- 백준 4358번
- 리액트 네이티브
- 데이터베이스
- 백준 5525번
- 백준 4358 자바
- 깃 터미널 연동
- Today
- Total
솜이의 데브로그
[React Native] 스타일링 본문
Reference : 처음배우는 리액트 네이티브
리액트 네이티브에서의 스타일링은 CSS와 약간의 차이가 있다.
CSS와는 달리 카멜 표기법으로 작성해야한다.
스타일링
인라인 스타일링
- 인라인 스타일링은 어떤 스타일이 적용되는지 잘 보인다는 장점이 있다.
- 그러나 비슷한 역할의 컴포넌트에 동일한 코드가 반복된다는 점과, 어떤 이유로 스타일이 적용되었는지 코드만으로 이해하기 어렵다는 단점이 있다.
클래스 스타일링
- 컴포넌트의 태그에 직접 입력하는 방식이 아니라 스타일 시트에 정의된 스타일을 사용하는 방법이다.
- 스타일 시트에 스타일을 정의, 컴포넌트에서는 정의된 스타일의 이름으로 적용. (CSS 클래스 이용법과 유사)
- 프로젝트를 생성하면 함께 생성되는 App.js 파일에서 클래스 스타일링이 적용된다.
- 스타일의 의도를 파악하기 쉽고(ex : 빨간글씨에는 error), 전체적인 스타일 관리에 용이하다.
여러개의 스타일 적용
- 여러 개의 스타일을 적용해야 할 경우 배열을 이용하여 style 속성에 여러 개의 스타일을 적용한다.
- 배열 사용 시, 적용하는 스타일의 순서에 주의해야한다.
- 뒤에 오는 스타일이 앞에 있는 스타일을 덮는다.
- 상황에 따라 인라인 스타일과 클래스 스타일 방식을 혼용해서 사용할 수 있다.
-
import React from 'react'; import { StyleSheet, View, Text } from 'react-native'; const App = () => { return( <View style ={styles.container}> <Text style={[styles.text, {color: 'green'}]}>Inline Styling - Text</Text> <Text style={[styles.text, styles.error]}>Inline Styling - Error</Text> </View> ); }; const styles = StyleSheet.create({ container: { flex:1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, text: { padding: 10, fontSize: 26, fontWeight: '600', color: 'black', }, error: { fontWeight: '400', color: 'red', }, }); export default App;
외부 스타일 이용하기
- 외부 파일에 스타일을 정의하고 여러 개의 파일에서 스타일을 공통으로 사용하는 경우
- 외부에 StyleSheet 정의하는 파일 작성 후, App.js 에서 import 후 사용한다.
리액트 네이티브 스타일
flex와 범위
- 각 컴포넌트의 width와 height을 설정
- src>components>Layout.js
-
import React from 'react'; import { StyleSheet, View, Text } from 'react-native'; export const Header = () => { return( <View style={[styles.container, styles.header]}> <Text style={styles.text}>Header</Text> </View> ); }; export const Contents = () => { return( <View style={[styles.container, styles.contents]}> <Text style={styles.text}>Contents</Text> </View> ); }; export const Footer = () => { return( <View style={[styles.container, styles.footer]}> <Text style={styles.text}>Footer</Text> </View> ); }; const styles = StyleSheet.create({ container:{ width : '100%', alignItems: 'center', justifyContent: 'center', height: 80, }, header: { backgroundColor: '#f1c40f', }, contents: { backgroundColor: '#1abc9c', height: 640, }, footer: { backgroundColor: '#3498db', }, text: { fontSize: 26, }, });
- 위처럼 코드 컴포넌트 생성 시 크기와 스타일을 지정하고, 해당 컴포넌트들을 app 에서 생성한다.
- 위의 코드는 아이폰 11기준으로 진행했고 내 폰이 11이기 때문에 잘 나오지만, 이처럼 고정값을 이용하면 기기마다 화면의 크기 차이 때문에 서로 다른 모습으로 나타난다.
- 따라서 flex를 이용해 항상 비율 크기로 설정되도록 한다.
- flex는 값을 숫자로 받으며, 0일때는 설정된 width와 height 값에 따라 크기 결정
- 양수인 경우 값에 비례하여 크기 조정. ex) 1:2:1 로 나눌 경우 원하는 비율만큼 컴포넌트의 flex값을 1,2,1로 설정.
왼쪽은 height 값을 각각 지정했을 때의 결과, 오른쪽은 flex로 1:2:1 비율 조정한 결과.
한 컴포넌트의 크기만 고정하고 싶은 경우, 해당 컴포넌트의 높이를 고정하고 나머지 부분들을 각 차지하도록 한다.
정렬
flexDirection
컴포넌트가 쌓이는 방식을 변경할 수 있다. 자기 자신이 쌓이는 방향이 아닌 자식 컴포넌트가 쌓이는 방향.
- column : 세로 방향으로 정렬 (기본값)
- column-reverse : 세로 방향 역순 정렬
- row : 가로 방향으로 정렬
- row-reverse : 가로 방향 역순 정렬
justifyContent, alignItems
컴포넌트를 배치할 방향을 결정한 후 방향에 따라 정렬하는 방식을 결정하는 속성이 justifyContent와 alignItems 이다.
- justifyContent : flexDirection에서 결정한 방향과 동일한 방향으로 정렬하는 속성
- alignItems : flexDirection에서 결정한 방향과 수직인 방향으로 정렬하는 속성
justifyContent값 설정
- flex-start : 시작점에서부터 정렬(기본값)
- flex-end : 끝에서부터 정렬
- center : 중앙정렬
- space-between : 컴포넌트 사이의 공간을 동일하게 만들어서 정렬
- space-around : 컴포넌트 각각의 주변 공간을 동일하게 만들어서 정렬
- space-evenly : 컴포넌트 사이와 양 끝에 동일한 공간을 만들어서 정렬
alignItems 값 설정
- flex-start : 시작점에서부터 정렬(기본값)
- flex-end : 끝에서부터 정렬
- center : 중앙정렬
- stretch : alignItems의 방향으로 컴포넌트 확장
- baseline : 컴포넌트 내부의 텍스트 베이스라인을 기준으로 정렬
그림자
리액트 네이티브 플랫폼마다 다르게 적용되는 스타일 속성
- shadowColor : 그림자 색 설정
- shadowOffset : width와 height 값을 지정하여 그림자 거리 설정
- shadowOpacity : 그림자의 불투명도 설정
- shadowRadius : 그림자의 흐림 반경 설정
위의 속성들은 iOS에만 적용. 안드로이드에서 표현하려면 elevation 이라는 속성을 사용해야 한다.
각 플랫폼마다 적용여부가 다른 속성은 Platform 모듈을 이용해 각 플랫폼마다 다른 코드가 적용되도록 코드를 작성할 수 있다.
https://reactnative.dev/docs/platform-specific-code#platform-module
import React from 'react';
import { StyleSheet, View, Platform } from 'react-native';
export default () => {
return <View style={styles.shadow}></View>;
};
const styles = StyleSheet.create({
shadow: {
backgroundColor: '#fff',
width: 200,
height: 200,
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: {
width: 10,
height: 10,
},
shadowOpacity: 0.5,
shadowRadius: 10,
},
android: {
elevation: 20,
},
}),
},
});
스타일드 컴포넌트
리액트 네이티브의 스타일에서 웹 프로그래밍과의 차이
- 카멜 표기법으로 작성해야 한다.
- CSS 속성과 이름이 같지만 타입이 다르거나 단위가 생략되는 경우가 있음
- width, height 과 같이 입력되는 값에 맞춰 타입이 달라지는 경우가 있다.
→ 스타일드 컴포넌트로 해소할 수 있다.
스타일드 컴포넌트는 자바스크립트 파일 안에 스타일을 작성하는 CSS-in-JS 라이브러리이다. (스타일이 적용되는 컴포넌트라고 생각)
다음 명령어를 통해 스타일드 컴포넌트를 설치한다.
npm install styled-components
- "styled.[컴포넌트 이름]" 형태 뒤에 백틱(`) 을 사용하여 만든 문자열을 붙이고 그 안에 스타일을 지정한다.
이 문법을 태그드 템플릿 리터럴 이라고 한다. - styled 뒤에 작성하는 컴포넌트 이름은 반드시 존재하는 컴포넌트를 지정해야 한다.
- 스타일드 컴포넌트에서는 css를 이용하여 재사용 가능한 코드를 관리할 수 있다.
- styled(컴포넌트 이름) 형식으로 이미 작성된 스타일을 상속받아 새로운 스타일드 컴포넌트를 만들 수 있다.
import React from "react";
import styled from 'styled-components/native';
const ButtonContainer = styled.TouchableOpacity`
background-color: #9b59b6;
border-radius: 15px;
padding: 15px 40px;
margin: 10px 0px;
justify-content: center;
`;
const Title = styled.Text`
font-size: 20px;
font-weight: 600;
color: #fff;
`;
const Button = props => {
return(
<ButtonContainer>
<Title>{props.title}</Title>
</ButtonContainer>
);
};
export default Button;
- TouchableOpacity 컴포넌트에 스타일이 적용된 ButtonContainer 라는 이름의 컴포넌트 생성
- Text 컴포넌트에 스타일이 적용된 Title 컴포넌트 생성
- 스타일드 컴포넌트로 만들어진 컴포넌트 이용해서 Button 컴포넌트 생성
스타일드 컴포넌트를 이용하면 PaddingVertical 이나 PaddingHorizontal 처럼 익숙하지 않은 속성보다 조금 더 익숙한 이름과 적용방법으로 값을 설정할 수 있다.
props 사용하기
- 스타일드 컴포넌트에서는 스타일을 작성하는 백틱 안에서 props 에 접근할 수 있다.
- 따라서 스타일을 작성하는 곳에서 조건에 따라 스타일을 변경할 수 있다.
const ButtonContainer = styled.TouchableOpacity`
background-color: ${props =>
props.title === 'Hanbit' ? '#3498db':'#9b59b6'};
border-radius: 15px;
padding: 15px 40px;
margin: 10px 0px;
justify-content: center;
`;
attrs 사용하기
- 스타일드 컴포넌트를 이용하면 스타일을 작성하는 곳에서 컴포넌트의 속성도 설정할 수 있다.
- 속성 설정 시 전달된 props를 이용할 수 있으므로 props의 값에 따라 속성을 변경할 수 있다.
src/components/Input.js
import React from "react";
import styled from "styled-components/native";
const StyledInput = styled.TextInput.attrs(props => ({
placeholder: 'Enter a text...',
placeholderTextColor: props.borderColor
}))`
width: 200px;
height: 60px;
margin: 5px;
padding: 10px;
border-radius: 10px;
border: 2px;
border-color: ${props => props.borderColor};
font-size: 24px;
`;
const Input = props => {
return <StyledInput borderColor={props.borderColor} />;
};
export default Input;
- TextInput 컴포넌트를 이용해 StyledInput 컴포넌트 생성
- placeholder와 placeholderTextColor 속성을 설정한다.
- attrs를 이용해 스타일을 설정하는 곳에서 props의 값에 따라 컴포넌트의 속성을 다르게 적용 가능. 또는 항상 일정한 속성을 미리 정의할 수 있다.
ThemeProvider
- ThemeProvider는 Context API를 활용해 애플리케이션 전체에서 스타일드 컴포넌트를 이용할 때 미리 정의한 값들을 사용할 수 있도록 props로 전달한다.
src/theme.js
export const theme = {
purple: '#9b59b6',
blue: '#3498db',
};
- 모든 컴포넌트를 감싸는 최상위 컴포넌트로 ThemeProvider 컴포넌트를 사용한다.
- ThemeProvider 컴포넌트의 자식 컴포넌트에서는 스타일드 컴포넌트를 이용할 때 props로 theme을 전달받아 미리 정의된 색을 이용할 수 있다.
- 즉, 하나의 파일에서 미리 정의해둔 색을 하위 컴포넌트에서 사용할 수 있다. -> 유지보수에서 이점
ThemeProvider를 활용해 애플리케이션의 색 테마를 변경할 수 있다.
src/theme.js
export const lightTheme = {
background: '#ffffff',
text: '#ffffff',
purple: '#9b59b6',
blue: '#3498db',
};
export const darkTheme = {
background: '#34495e',
text: '#34495e',
purple: '#9b59b6',
blue: '#3498db',
};
const Container = styled.View`
flex: 1;
background-color: ${props => props.theme.background};
align-items: center;
justify-content : center;
`;
const App = () => {
const [isDark, setIsDark] = useState(false);
const _toggleSwitch = () => setIsDark(!isDark);
return(
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
<Container>
<Switch value={isDark} onValueChange={_toggleSwitch} />
<Button title="Hanbit" />
<Button title="React Native" />
<Input borderColor="#3498db" />
<Input borderColor="#9b59b6" />
</Container>
</ThemeProvider>
);
};
- useState를 이용해 테마의 상태를 관리할 isDark와 상태를 변경할 setIsDark 함수 생성
- Switch 컴포넌트를 활용해 isDark 상태 변경
- ThemeProvider 컴포넌트의 theme 속성에는 isDark 상태에 따라 theme.js 파일에 정의된 테마 적용
- App 컴포넌트의 Container 컴포넌트 스타일 정의하는 곳에서 props로 전달된 theme 이용해 배경색 설정
결과
Prettier
코드 스타일 정리 도구.
들여쓰기, 줄바꿈, 세미콜론 등을 일관성 있게 자동 변환해준다.
-> 협업에 용이
느낀점
뭐.. 웹 프로그래밍에 익숙한 방법으로 할 수 있도록 배웠는데 나는 아무것도 몰라서(^^) 이러나 저러나 낯설다ㅎ
아직까진 재밌다! 직관적인게 정말 큰 장점인 것 같다.
'dev > React native' 카테고리의 다른 글
[React Native] 할 일 관리 애플리케이션(2) (0) | 2021.11.06 |
---|---|
[React Native] 할 일 관리 애플리케이션(1) (0) | 2021.11.05 |
[React Native] 컴포넌트 (0) | 2021.10.10 |
[React Native] JSX (0) | 2021.10.10 |
[React Native] 리액트 네이티브 프로젝트 만들기 (윈도우) (0) | 2021.10.08 |