[처음부터 배우는 리액트 네이티브]스타일링

최다연·2025년 11월 13일

ReactNative

목록 보기
2/8

스타일링

스타일링

인라인 스타일링

컴포넌트에 직접 스타일을 입력하는 방식이다

    <View
      style={{
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
      }}
      

어떤 스타일이 적용되는지 잘 보이지만 비슷한 역할을 하는 컴포넌트에 동일한 코드가 반복되고 어떤 스타일인지 명확하게 이해하기 힘들다.

클래스 스타일링

스타일시트에 정의된 스타일을 사용하는 방법이다.

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;

여러개의 스타일 적용

<Text style={[styles.text, { color: 'green' }]}>
<Text style={[styles.text, styles.error]}>Inline Styling - Error</Text>

외부 스타일 이용하기

import React from 'react';
import { View, Text } from 'react-native';
import { viewStyles, textStyles } from './styles';

const App = () => {
  return (
    <View style={viewStyles.container}>
      <Text style={[textStyles.text, { color: 'green' }]}>
        Inline Styling - Text
      </Text>
      <Text style={[textStyles.text, textStyles.error]}>
        Inline Styling - Error
      </Text>
    </View>
  );
};

export default App;

리액트 네이티브 스타일

flex와 범위

다양한 크기의 기기에 대응하기 위해 이용한다. flex는 0을 받으면 설정된 width나 height값에 따라 크기가 결정되고 양수인 경우 flex에 비례하여 크기가 조정된다.

정렬

  • flexDirextion
    • column: 세로 방향 정렬
    • column-reverse: 세로 방향 역순 정렬
    • row: 가로 방향 정렬
    • row-reverse: 가로 방향 역순 정렬
  • justifyContent: flexDirextion에서 결정한 방향과 동일한 방향으로 정렬
    • flex-start : 시작점에서부터 정렬 (기본값)
    • flex-end : 끝에서부터 정렬
    • center : 중앙 정렬
    • space-between : 컴포넌트 사이의 공간을 동일하게 만들어서 정렬
    • space-around : 컴포넌트 각각의 주변 공간을 동일하게 만들어서 정렬
    • space-evenly : 컴포넌트 사이와 양 끝에 동일한 공간을 만들어서 정렬
  • alignItems: flexDirextion에서 결정한 방향과 수직이 되는 방향
    • flex-start: 시작점에서부터 정렬
    • flex-end: 끝에서부터 정렬
    • center: 중앙 정렬
    • stretch: alignItems방향으로 컴포넌트

그림자

iOS에서는 shadowColor, shadowOffset, shadowOpacity, shadowRadius 를 사용하여 그림자를 표현하고, 안드로이드에서는 elevation이라는 속성을 사용한다. 따라서 플랫폼마다 다른 코드를 작성해야 한다. Platform 모듈을 이용한다.

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,
      },
    }),
  },
});

스타일드 컴포넌트

styled.컴포넌트 이름 형태 뒤에 백틱 ' 을 사용하여 만든 문자열을 붙이고 그 안에 스타일을 지정한다. 태그드 탬플릿 리터럴이라고 한다. 완성된 컴포넌트를 상속받아 이용하는 경우도 있다.

const StyledText = styled.Text`
  color: #000;
  font-size: 20px;
  margin: 10px;
  padding: 10px;
`;

const ErrorText = styled(StyledText)`
  font-weight: 600;
  color: red;
`;

스타일 적용하기

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;
*/
import React from 'react';
import styled from 'styled-components/native';
import Button from './components/Button';

const Container = styled.View`
  flex: 1;
  background-color: #ffffff;
  align-items: center;
  justify-content: center;
`;

const App = () => {
  return (
      <Container>
        <Button title="Hanbit" />
        <Button title="React Native" />
      </Container>
  );
};

export default App;

props 사용하기

스타일이 props값에 따라 바뀌는 경우, 기존 방식으로는 스타일 시트 안에서 props에 접근할 수 있는 방법이 없다. 스타일 컴포넌트에서는 스타일을 작성하는 백틱 안에서 props에 접근할 수 있다.

const ButtonContainer = styled.TouchableOpacity`
  background-color: ${props =>
    props.title === 'Hanbit' ? props.theme.blue : props.theme.purple};
  border-radius: 15px;
  padding: 15px 40px;
  margin: 10px 0px;
  justify-content: center;
`;
const Title = styled.Text`
  font-size: 20px;
  font-weight: 600;
  color: ${props => props.theme.text};
`;

const Button = props => {
  return (
    <ButtonContainer title={props.title}>
      <Title>{props.title}</Title>
    </ButtonContainer>
  );
};

export default Button;

attrs사용하기

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;
  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>

ThemeProvider

스타일 컴포넌트의 Context API를 활용해 애플리케이션 전체에서 스타일 컴포넌트를 이용할 때 미리 정의한 값들을 사용할 수 있도록 props로 전달한다.

export const theme = {
  purple: '#9b59b6',
  blue: '#3498db',
};
import React, { useState } from 'react';
import { Switch } from 'react-native';
import styled, { ThemeProvider } from 'styled-components/native';
import Button from './components/Button';
import Input from './components/Input';
import { theme } from './theme';

...

const App = () => {
  return (
    <ThemeProvider theme={theme}>
...
      </Container>
    </ThemeProvider>
  );
};

export default App;
const ButtonContainer = styled.TouchableOpacity`
  background-color: ${props =>
    props.title === 'Hanbit' ? props.theme.blue : props.theme.purple};

0개의 댓글