자바스크립트를 이용해서 스타일링
Html 인라인처럼 직접 입력. 문자열 형태가 아니라 객체형태로 전달해야한다.
<View
style={{
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text
style={{
padding: 10,
fontSize: 26,
fontWeight: '600',
color: 'black',
}}
>
Inline Styling - Text
</Text>
<Text
style={{
padding: 10,
fontSize: 26,
fontWeight: '400',
color: 'red',
}}
>
Inline Styling - Error
</Text>
</View>
태그에 직접 입력하는 방식이 아니라 스타일시트에 정의된 스타일을 사용하는 방법
css클래스를 이용하는 방법과 유사하다.
const App = () => {
return (
<View style={styles.container}>
<Text style={styles.text}>
Inline Styling - Text
</Text>
<Text style={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: {
padding: 10,
fontSize: 26,
fontWeight: '400',
color: 'red',
}
})
물론 한번에 여러개의 스타일을 적용시킬 수 있다. 중복코드를 제거하고, 여러 개의 스타일을 배열을 이용해서 적용 가능.
error: {
/*padding: 10,
fontSize: 26,*/ // text스타일과 중복
fontWeight: '400',
color: 'red',
}
error의 스타일을 styles.text, styles.error을 둘 다 적용. 뒤에 오는 스타일이 앞에 있는 스타일을 덮는다.
아래 inline styling과 같이 클래스 스타일과 인라인 스타일 혼용 가능
<Text style={[styles.text, {color: 'green'}]}>
Inline Styling - Text
</Text>
<Text style={[styles.text, styles.error]}>
Inline Styling - Error
</Text>
외부 파일에 스타일을 작성하고 컴포넌트에서 외부 파일에 정의된 스타일을 이용하는 방법
styles.js
import { StyleSheet } from 'react-native';
export const viewStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export const textStyles = StyleSheet.create({
text: {
padding: 10,
fontSize: 26,
fontWeight: '600',
color: 'black',
},
error: {
fontWeight: '400',
color: 'red',
},
});
src/App.js에 import { viewStyles, textStyles} from './styles'; 를 import 해주면 원래 사용했던 styles.text가 아니라, textStyles.text, styles.container이 아니라 viewStyles.container사용 가능.
header 80, contents ..., footer 80인 레이아웃을 만들것임.
고정값 사용하는 경우 : 화면비에 따라서 보이거나 안보이거나... 서로 다른 모습으로 나타난다. 이때 flex를 사용. 비율로 크기가 설정.
flex = 0일 경우, 설정된 width, height에 따라 크기가 결정되고 양수일 경우 flex값에 비례해서 크기가 조정됨. 예를 들어 flex가 1로 설정되어있으면 차지가능한 영역 전체를 차지.
export const Header = () => {
return (
<View style={[styles.container, styles.header]}>
<Text style={styles.text}>Header</Text>
</View>
);
};
{/*container은 height가 80으로 설정되어있고, header은 백그라운드 색깔만 바뀜*/}
export const Contents = () => {
return (
<View style={[styles.container, styles.contents]}>
<Text style={styles.text}>Contents</Text>
</View>
);
};
{/*container은 height가 80으로 설정되어있고, contents는 flex가 1로 설정되어있어서 container style을 덮어쓰니까 걍 사용할 수 있는 화면 전체를 다 가져감. */}
flex direction: 자식 컴포넌트가 쌓이는 방향 위→아래, 왼→오
jusstifyContent: flexDirection에서 결정된 방향과 동일한 방향으로 정렬하는 속성
alignItems: 수직인 방향으로 정렬하는 속성
baseline: 컴포넌트 내부 텍스트 베이스라인 기준
shadowColor, offset(width, height값을 지정해서 그림자 거리 설정), opacity, radius(흐림반경)으로 그림자 표현하기는 ios에만 적용되는 속성이다. 안드로이드는 elevation이라는 속성을 이용해야한다.
스타일드 컴포넌트 = 자바스크립트 파일 안에 스타일을 작성하는 css-in-js라이브러리이며 스타일이 적용된 컴포넌트...
import styled from 'styled-components/native';
const MyTextComponent = styled.Text`color: #fff`;
styled.[컴포넌트 이름] + 백틱(`)을 사용해서 만든 문자열을 붙이고 그 안에 스타일 지정. 이러한 문법을 tagged template literals라고 한다. styled 뒤에 작성하는 컴포넌트의 이름은 반드시 존재하는 컴포넌트를 지정해야하한다. css를 이용하여 재사용 가능한 코드를 관리할 수 있다.
ex)
import styled, { css } from 'styled-components/native';
const whiteText = css`
color: #fff;
font-size: 14px;
`;
const MyBoldTextComponent = styled.Text`
${whiteText}
font-weight: 600;
`;
혹은 완성되 컴포넌트를 상속받아 이용하는 방법이 있다.
import styled from 'styled-components/native';
const StyledText = styled.Text`
color: #000;
`;
const ErrorText = styled(StyledText)`
font-weightL 600;
`;
button.js
import React from 'react';
import { StyleSheet, TouchableOpacity, Text } from 'react-native';
const styles = StyleSheet.create({
container: {
backgroundColor: '#9b59b6',
borderRadius: 15,
paddingVertical: 15,
paddingHorizontal: 40,
marginVertical: 10,
justifyContent: 'center',
},
title: {
fontSize: 20,
fontWeight: '600',
color: '#fff',
},
});
const Button = props => {
return (
<TouchableOpacity
style={[
styles.container,
{ backgroundColor: props.title === 'Hanbit' ? '#3498db' : '#9b59b6' },
]}
>
<Text style={styles.title}>{props.title}</Text>
</TouchableOpacity>
);
};
export default Button;
return (
<Container>
<Button title="Hanbit" />
<Button title="React Native" />
</Container>
);
카멜 표기법 중요.
리액트 네이티브에서 PaddingVertical은 paddingTop과 paddingBottom을 모두 설정. 마찬가지로 PaddingHorizontal은 paddingRight와 paddingLeft 모두를 설정. margin역시동일한 방식으로 작동한다.
const ButtonContainer = styled.TouchableOpacity`
background-color: ${props =>
props.title === 'Hanbit' ? '#3498db' : '#9b59b6'};
...
`;
...
const Button = props => {
return (
<ButtonContainer title={props.title}>
<Title>{props.title}</Title>
</ButtonContainer>
);
이부분이 props로 전달되는 title의 값이 hanbit일 경우 바탕색을 다르게 접근 할 수 있는 방법.. .
ButtonContainer 컴포넌트에 title을 props로 전달하뎌 배경색을 설정하는 곳에서 title의 값에 따라 다른 색이 지정된다.
스타일을 작성하는 곳에서 컴포넌트 속성도 설정할 수 있다. props를 속성을 설정할 때도 이용할 수 있으므로 props값에 따라 속성을 변경할 수 있다.
const StyledInput = styled.TextInput`
...
`;
const Input = () => {
return <StyledInput placeholder="Enter a text ..." placeholderTextColor="#3498db" />;
};
위 코드를 attrs를 활용하면 : app컴포넌트에서 input 컴포넌트를 사용하면서 borderColor값을 전달하도록 수정한다.
const StyledInput = styled.TextInput.attrs(props => ({
placeholder: 'Enter a text ...',
placeholderTextColor: props.borderColor,
}))`
...
border-color: ${props => props.borderColor};
`;
const Input = props => {
return <StyledInput borderColor={props.borderColor}/>;
};
attrs를 이용하면 스타ㅣㄹ을 설정하는 곳에서 props의 값에 따라 컴포넌트의 속성을 다르게 적용할 수 도 있고 항상 일정한 속성을 미리 정의할 수도 있다.
스타일드 컴포넌트의 ThemeProvider은 context api를 활용해 애플리케이션 전체에서 스타일드 컴포넌트를 이용할 때 미리 정의한 값들을 사용할 수 있도록 props로 전달한다.
유지보수에서 많은 이점이 있다.
theme.js
export const lightTheme = {
background: '#ffffff',
text: '#ffffff',
purple: '#9b59b6',
blue: '#3498db',
};