React Native

React Native - Styled Component 활용, Theme Provider

joy_lee 2021. 12. 13. 18:52

Props

Props를 이용해 스타일에 데이터를 전달해 그 값에 따라 스타일을 다르게 적용할 수 있다.

삼항연산자 사용가능

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
// input.js
import React, { useState } from 'react';
import styled from "styled-components/native";
 
const StyledInput = styled.TextInput`
    padding: 10px;
    font-size: 20px;
    border: 1px solid ${({ text }) => (text ? "red" : "black")};
`;
 
const Input = ({placeholder}) => {
    const [text, setText] = useState('');
    return <StyledInput onChangeText={text => setText(text)} text={text}/>
}
 
export default Input;
 
 
// App.js에서 사용
import Input from './input';
 
export default function App() {
  return (
    <Container>
      <StatusBar style="auto" />
      <Input />
    </Container>
  );
}
cs

StyledInput은 onChangeText를 통해 입력받은 문자열 값에 변화가 생기면 text(state)가 변화한다.

그 값은 style에 전달되며, text의 유무에 따라 border 색이 바뀐다.

 

 

 

속성(attrs)

컴포넌트의 속성들은 사용하는 곳에서 설정하는 것이 일반적이지만, styled-component를 사용하면 스타일 내에서 속성 설정 가능하다.

styled.컴포넌트.attrs({ 속성 설정 })`스타일 코드`
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// input.js
const StyledInput = styled.TextInput.attrs(({placeholder}) => ({
    placeholder: placeholder || "Enter a message...",
    placeholderTextColor: "#111111"
}))``;
 
const Input = ({placeholder}) => {
    // const [text, setText] = useState('');
    return <StyledInput placeholder={placeholder}/>
}
 
 
// App.js에서 사용
export default function App() {
  return (
    <Container>
      // <StatusBar style="auto" />
      <Input placeholder="Type a message..."/>
      <Input />
    </Container>
  );
}
cs

 

App.js에서 placeholder를 전달받은 경우와, placeholder가 없는 경우를 비교해 볼 수 있다.

 

props를 전달 받아 속성 설정을 변경할 수도 있다.

styled.컴포넌트.attrs(props => {
	return {속성 설정};
})`스타일 코드`

props.이름으로 사용할 수 있다.

 

 

ThemeProvider

Styled-component에서 제공하는 기능이며, 미리 정의된 값들을 지정해 해당 값을 사용할 수 있도록 한다.

 

ThemeProvider의 자식 컴포넌트로 있는 styled component에 전달할 수 있다. styled component의 props에 theme이 자동으로 들어간다.(theme.속성명 사용가능)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import styled, { ThemeProvider } from "styled-components/native";
 
// Theme를 위한 색 설정
const lightTheme = {
  inputColor: "#111111"// black
  inputBoarder: "#111111",
  bgColor: "#e3e3e3" // gray
}
 
const darkTheme = {
  inputColor: "#e3e3e3",
  inputBoarder: "#e3e3e3",
  bgColor: "#111111"
}
 
export default function App() {
  return (
    <ThemeProvider theme={lightTheme}>
      // ...
     <Input />
    </ThemeProvider>
  );
}
cs

ThemeProvider를 사용하기 위해 import하고, 미리 사용할 색을 설정해준다.

ThemeProvider를 적용할 컴포넌트들의 상위에 둔다.

 

1
2
3
4
5
6
7
// input.js
 
const StyledInput = styled.TextInput.attrs(({theme}) => ({
    placeholderTextColor: theme.inputColor
}))`
    border: 1px solid ${({ theme }) => theme.inputBorder};
`;
cs

Input Component의 style을 설정할 때 theme를 사용할 수 있다. theme.inputColor, theme.inputBorder를 사용해준다.

현재 ThemeProvider에서 theme={lightTheme}이므로, lightTheme의 inputColor, inputBorder를 사용하게 된다.

 

Theme 변경을 위한 스위치를 만들어 lightTheme/darkTheme를 바꿀 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// App.js
import React, { useState } from "react";
import { Switch } from "react-native";
 
export default function App() {
  const [isLight, toggleTheme] = useState(true);
  return (
    <ThemeProvider theme={isLight ? lightTheme : darkTheme}>
      // <Container>
        // <StatusBar style="auto" />
           <Switch value={isLight} onValueChange={isLight => toggleTheme(isLight)}/>
           <Input />
      // </Container>
    </ThemeProvider>
  );
}
cs

 

switch는 value로 true/false값을 가진다.

위에서는 value={isLight}를 통해 isLight가 true/false의 값을 가지게 되고, isLight가 true면 ThemeProvider에서 lightTheme를 사용하게 된다.

 

 

 

참고한 페이지

https://reactnative.dev/docs/switch

 

Switch · React Native

Renders a boolean input.

reactnative.dev

 

'React Native' 카테고리의 다른 글

React Native - SafeAreaView  (0) 2021.12.15
React Native - Todo App 만들기  (0) 2021.12.14
React Native - styled component  (0) 2021.12.07
React Native - 그림자 속성과 Platform  (0) 2021.12.07
React Native - flex와 정렬  (0) 2021.12.07