본문 바로가기
대외활동/Draconist-프론트

REACT NATIVE 스터디. 1주차 4단원 스타일 DRACONIST

by 피스타0204 2025. 1. 16.

1. 스타일링

1) 인라인 스타일

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

const App = () => {
  return (
    <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>
  );
};

export default App;

 

2) 클래스 스타일

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

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

export default App;

 

여러개의 스타일을 적용하고 싶다면

배역을 이용하여 style 속성에 여러 개의 스타일을 적용할 수 있습니다.

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

3) 외부 파일에서 스타일 가져오기

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

 

2. 리액트 네이티브 스타일 속성

1) flex와 범위

화면의 범위를 나타내는 속성헤는 width와 height이 있습니다. 

비율이 안 맞아...!

 

자동으로 비율을 맞추어주는 flex속성이 있습니다.

//...중략
const styles = StyleSheet.create({
  container: {
    width: '100%',
    alignItems: 'center',
    justifyContent: 'center',
    height: 80,
  },
  header: {
    flex:1,
    backgroundColor: '#f1c40f',
  },
  contents: {
    flex:2,
    backgroundColor: '#1abc9c',
    height: 640,
  },
  footer: {
    flex:1,
    backgroundColor: '#3498db',
  },
  text: {
    fontSize: 26,
  },
});

2) 정렬

-flexDirection

flexDirection 속성은 자식 컴포넌트들이 쌓이는 방향을 결정합니다. 기본값은 column (세로방향)입니다. flexDirection에 설정할 수 있는 값은 다음과 같습니다:

  • column: 세로 방향으로 정렬 (기본값)
  • column-reverse: 세로 방향 역순 정렬
  • row: 가로 방향으로 정렬
  • row-reverse: 가로 방향 역순 정렬

-justifyContent

justifyContent는 flexDirection에서 결정한 주 축(main axis) 방향으로 컴포넌트를 정렬하는 데 사용됩니다. 설정할 수 있는 값은 다음과 같습니다:

  • flex-start: 시작점에서 정렬 (기본값)
  • flex-end: 끝에서 정렬
  • center: 중앙 정렬
  • space-between: 컴포넌트 사이의 공간을 동일하게 배분
  • space-around: 컴포넌트의 주변 공간을 동일하게 배분
  • space-evenly: 컴포넌트 사이와 양 끝에 동일한 공간을 배분

-alignItems

alignItems는 flexDirection에서 결정한 교차 축(cross axis) 방향으로 컴포넌트를 정렬하는 데 사용됩니다. 설정할 수 있는 값은 다음과 같습니다:

  • flex-start: 교차 축의 시작점에서 정렬
  • flex-end: 교차 축의 끝에서 정렬
  • center: 교차 축의 중앙에서 정렬
  • stretch: 가능한 한 모든 컴포넌트를 확장
  • baseline: 텍스트의 기준선을 기준으로 정렬

3)  그림자 

플랫폼마다 다르게 적용되는 스타일 속성입니다. 

iOS에서 그림자를 설정하려면, 네 가지 스타일 속성을 사용할 수 있습니다:

  • shadowColor: 그림자 색상 설정
  • shadowOffset: 그림자의 x, y 방향 거리 설정
  • shadowOpacity: 그림자의 불투명도 설정
  • shadowRadius: 그림자의 흐림 정도 설정

안드로이드에서는 elevation 속성을 사용하여 그림자 효과를 주게 됩니다.

 

플랫폼별 스타일 적용 방법

리액트 네이티브에서 플랫폼에 따라 다른 스타일을 적용할 수 있는 방법은 Platform.select를 사용하는 것입니다. 이 방법을 통해 iOS와 안드로이드 각각에 맞는 스타일을 설정할 수 있습니다.

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를 사용하여 플랫폼별 스타일 적용
    ...Platform.select({
      ios: {
        shadowColor: '#000',
        shadowOffset: { width: 10, height: 10 },
        shadowOpacity: 0.5,
        shadowRadius: 10,
      },
      android: {
        elevation: 20, // 안드로이드에서는 elevation으로 그림자 설정
      },
    }),
  },
});
import React from 'react';
import { View, StyleSheet } from 'react-native';
import ShadowBox from './components/ShadowBox';

const App = () => {
  return (
    <View style={styles.container}>
      <ShadowBox />
    </View>
  );
};

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

export default App;

 

4. 스타일드 컴포넌트

스타일드 컴포넌트는 자바스크립트 파일 안에 스타일을 작성하는 CSS-in-JS 라이브러리이로 이미 스타일이 적용된 컴포넌트라고 생각하면 편합니다. 기본적으로 React Native에서 제공하는 내장 컴포넌트들 (Text, View, Image, ScrollView 등)에 스타일을 추가하는 데 사용됩니다.

아래 코드를 터미널에 치면서 의존성 문제를 무시하고 스타일드 컴포넌트를 설치할 수 있습니다.

npm install styled-components --legacy-peer-deps

 

styled.[라이브러리 내장 컴포넌트이름] ` 스타일 상세 내용 `

이렇게 사용합니다.

컴포넌트 자체에 css를 적용하므로 코드를 쉽게 재사용할 수 있다는 장점이 있습니다.

import styled, { css } from 'styled-components/native';

const whiteText = css`
  color: #fff;
  font-size: 14px;
`;

const MyBoldTextComponent = styled.Text`
  ${whiteText}
  font-weight: 600;
`;

 

스타일드 컴포넌트에서 이미 작성된 스타일을 상속받아 사용할 수 있습니다.

스타일드 컴포넌트를 상속받아 새로운 스타일드 컴포넌트를 만들 때는 styled.[라이브러리 내장 컴포넌트이름] ` 스타일 상세 내용 `가 아니라 styled.(라이브러리 내장 컴포넌트이름) ` 스타일 상세 내용 ` 이렇게 소괄호를 사용해야 합니다.

import styled from 'styled-components/native';

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

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

3) 직접 해보기

npm install postcss
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;
// 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}>
      <Text style={styles.title}>{props.title}</Text>
    </TouchableOpacity>
  );
};

export default Button;

3. props 사용하기

스타일에서도 props를 사용할 수 있습니다.

import React from 'react';
import styled from 'styled-components/native'; // styled-components import
import { Text } from 'react-native';

// Styled-components로 스타일 정의
const ButtonContainer = styled.TouchableOpacity`
  background-color: ${props => (props.title === 'Hanbit' ? '#3498db' : '#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>{props.title}</Title>
    </ButtonContainer>
  );
};

export default Button;

 

4.attrs 사용하기

attrs를 사용하면 스타일드 컴포넌트의 속성을 설정할 수 있습니다. attrs는 컴포넌트를 생성할 때 기본적으로 적용할 속성 값을 지정하는 데 유용하며, 이를 통해 컴포넌트의 속성을 동적으로 설정할 수 있습니다

import React from 'react';
import styled from 'styled-components/native';
import Button from './components/Button';
import Input from './components/Input';

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" />
      <Input />
    </Container>
  );
};

export default App;
import React from 'react';
import styled from 'styled-components/native';

// StyledInput에 attrs로 기본 속성 설정
const StyledInput = styled.TextInput.attrs(props => ({
  placeholder: 'Enter a text...',
  placeholderTextColor: props.borderColor,
}))`
  width: 280px;
  height: 60px;
  margin: 5px;
  padding: 10px;
  border-radius: 10px;
  border: 2px solid ${props => props.borderColor};
  font-size: 24px;
`;

const Input = props => {
  return <StyledInput borderColor={props.borderColor} />;
};

export default Input;

 

5. ThemeProvider

ThemeProvider를 사용하면 하위에 있는 태그들에게 모두 스타일이 미치게되어 전역적으로 스타일링을 합니다. 스타일드 컴포넌 트의 ThemeProvider는 Context API를 활용해 애플리케이션 전체에서 스타일드 컴포넌트 를 이용할 때 미리 정의한 값들을 사용할 수 있도록 props로 전달합니다.

import React, { useState } from 'react';
import { Switch } from 'react-native';
import styled, { ThemeProvider } from 'styled-components/native';
import { lightTheme, darkTheme } from './components/Theme'

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} />
      </Container>
    </ThemeProvider>
  );
};

export default App;
export const lightTheme = { 
    background: '#ffffff',
    text: '#34495e',
    purple: '#9b59b6',
    blue: '#3498db',
  };
  
  export const darkTheme = { 
    background: '#34495e',
    text: '#ffffff',
    purple: '#9b59b6',
    blue: '#3498db',
  };