Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 지네릭스
- 머신러닝
- 리액트 네이티브 시작하기
- 백준
- 백준 4358번
- 백준 4358 자바
- 데베
- 백준 4949번
- 깃허브 토큰 인증
- 백준 5525번
- 딥러닝
- 정리
- HTTP
- 스터디
- 모두를 위한 딥러닝
- 문자열
- 네트워크
- 리액트 네이티브 프로젝트 생성
- SQL
- 모두를위한딥러닝
- 팀플회고
- React Native
- 리액트 네이티브
- 자바
- 깃허브 로그인
- 깃 터미널 연동
- 모두의네트워크
- 모두의 네트워크
- 깃 연동
- 데이터베이스
Archives
- Today
- Total
솜이의 데브로그
[React Native] 할 일 관리 애플리케이션(1) 본문
Reference : 처음 배우는 리액트 네이티브 (김범준)
할 일 관리 애플리케이션
- 등록 : 할 일 항목 추가
- 수정 : 완료되지 않은 할 일 항목 수정
- 삭제 : 할 일 항목을 삭제
- 완료 : 할 일 항목의 완료 상태 관리
위의 기능들을 포함한 애플리케이션을 만들어보자.
먼저 expo 프로젝트 생성후, 스타일 컴포넌트 라이브러리와 prop-types 라이브러리 설치한다.
src/theme.js 생성 후 프로젝트에서 사용할 색 정의하기
export const theme={
background: '#101010',
itemBackground: '#313131',
main: '#778bdd',
text: '#cfcfcf',
done: '#616161',
};
src/App.js
import React from 'react';
import styled, { ThemeProvider } from 'styled-components/native';
import { theme } from './theme';
const Container = styled.View`
flex: 1;
background-color: ${({ theme}) => theme.background};
align-items: center;
justify-content: center;
`;
export default function App(){
return(
<ThemeProvider theme={theme}>
<Container></Container>
</ThemeProvider>
);
};
스타일드 컴포넌트의 ThemeProvider를 이용해 theme 지정하고, 미리 정의한 색을 사용한다.
또 src 내의 App.js가 메인 파일이 되도록 루트 디렉토리의 App.js를 수정한다. (수정 코드는 생략)
타이틀 생성
- 화면 상단에 TODO List 문구가 렌더링되도록 스타일드 컴포넌트를 이용해 Title 컴포넌트를 만들어보자.
src/App.js
import React from 'react';
import { StatusBar } from 'react-native';
import styled, { ThemeProvider } from 'styled-components/native';
import { theme } from './theme';
const Container= styled.SafeAreaView`
flex: 1;
background-color: ${({ theme }) => theme.background};
align-items: center;
justify-content: flex-start;
`;
const Title = styled.Text`
font-size: 40px;
font-weight: 600;
color: ${({ theme }) => theme.main};
align-self: flex-start;
margin: 20px;
`;
export default function App(){
return(
<ThemeProvider theme={theme}>
<Container>
<StatusBar
barStyle="light-content"
backgroundColor={theme.background}
/>
<Title>TODO List</Title>
</Container>
</ThemeProvider>
);
};
- 앞으로 추가되는 항목들이 위에서부터 정렬되도록 justify-content의 값을 flex-start로 한다.
- 아이폰처럼 노치 디자인이 있는 기기는 자동으로 padding 값을 적용해 컴포넌트가 가려지지 않도록한다.
- SafeAreaView 컴포넌트 : https://reactnative.dev/docs/safeareaview
- 배경을 어두운 색으로 설정했기 때문에 상태바의 내용 색상을 밝게 변경한다.
- StatusBar 컴포넌트 : https://reactnative.dev/docs/statusbar
Input 컴포넌트 생성
다음으로, TextInput 컴포넌트를 이용해 Input 컴포넌트를 생성해보자.
먼저 Input 컴포넌트를 만든다.
src/components/Input.js
import React from "react";
import styled from "styled-components/native";
import { useWindowDimensions } from 'react-native';
const StyledInput = styled.TextInput`
width: ${({ width }) => width - 40}px;
height: 60px;
margin: 3px 0;
padding: 15px 20px;
border-radius: 10px;
background-color: ${({ theme }) => theme.itemBackground};
font-size: 25px;
color: ${({ theme}) => theme.text};
`;
const Input = () => {
const width = useWindowDimensions().width;
return <StyledInput width={width} />;
};
export default Input;
Dimensions
- 리액트 네이티브에서는 크기가 다양한 모바일 기기에 대응하기 위해 두가지 방법을 제공한다.
- Dimensions : https://reactnative.dev/docs/dimensions
- useWindowDimensions : https://reactnative.dev/docs/usewindowdimensions
- 현재 기기 화면의 크기를 알 수 있고, 다양한 크기의 기기에 동일한 모습으로 적용 될 수 있도록 한다.
- Dimensions 는 처음 받아왔을 때의 크기로 고정하므로 event listener를 등록하여 크기 변화에 대응한다.
- useWindowDimensions 는 리액트 네이티브에서 제공하는 Hooks 중 하나로, 화면의 크기가 변경되면 자동으로 업데이트한다.
Input Component
- placeholder에 적용할 문자열을 props로 받아 설정하고, 입력 가능한 글자의 수를 제한한다.
- Input 컴포넌트에서 props로 전달받은 값을 이용한다.
- TextInput 컴포넌트에서 제공하는 속성을 이용해 키보드 설정을 변경
- autoCapitalize 속성을 none으로 변경해 자동 대문자 전환을 동작하지 않도록 한다.
- autoCorrect 속성을 false 로 설정하여 자동 수정 기능을 사용하지 않는다.
- returnKeyType을 done으로 변경해 키보드의 완료 버튼을 설정한다.
- TextInput 컴포넌트의 속성들 중에는 특정 플랫폼에만 적용되는 속성이나 값도 있다. (ex: iOS에만 적용되는 keyboardAppearance) → 키보드 색상을 어둡게 설정
이벤트
- useState를 이용하여 newTask 상태 변수와 세터함수 생성
- Input 컴포넌트에서 값이 변할 때마다 newTask에 저장한다.
- 완료 버튼을 누르면 입력된 내용을 확인(alert)하고 Input 컴포넌트를 초기화한다.
- Input 컴포넌트에서 props로 전달된 값들을 설정하고, 전달되는 값들의 타입과 필수 여부를 지정한다.
src/App.js
export default function App(){
const [newTask, setNewTask] = useState('');
const _addTask = () => {
alert(`Add: ${newTask}`);
setNewTask('');
};
const _handleTextChange = text => {
setNewTask(text);
};
return(
<ThemeProvider theme={theme}>
<Container>
<StatusBar
barStyle="light-content"
backgroundColor={theme.background}
/>
<Title>TODO List</Title>
<Input
placeholder="+ Add a Task"
value={newTask}
onChangeText={_handleTextChange}
onSubmitEditing={_addTask}
/>
</Container>
</ThemeProvider>
);
}
src/components/Input.js
import React from "react";
import styled from "styled-components/native";
import { Dimensions, useWindowDimensions } from 'react-native';
import PropTypes from 'prop-types';
const StyledInput = styled.TextInput.attrs(({ theme }) => ({
placeholderTextColor: theme.main,
}))`
width: ${({ width }) => width - 40}px;
height: 60px;
margin: 3px 0;
padding: 15px 20px;
border-radius: 10px;
background-color: ${({ theme }) => theme.itemBackground};
font-size: 25px;
color: ${({ theme }) => theme.text};
`;
const Input = ({ placeholder, value, onChangeText, onSubmitEditing }) => {
const width = Dimensions.get('window').width;
// const width = useWindowDimensions().width;
return (
<StyledInput
width={width}
placeholder={placeholder}
maxLength={50}
autoCapitalize="none"
autoCorrect={false}
returnKeyType="done"
keyboardAppearance="dark"
value={value}
onChangeText={onChangeText}
onSubmitEditing={onSubmitEditing}
/>
);
};
Input.propTypes = {
placeholder: PropTypes.string,
value: PropTypes.string.isRequired,
onChangeText: PropTypes.func.isRequired,
onSubmitEditing: PropTypes.func.isRequired,
};
export default Input;
할 일 목록 만들기
Input 컴포넌트를 통해 입력받은 내용을 목록으로 출력해보자
- IconButton 컴포넌트 : 완료, 수정, 삭제 버튼
- Task 컴포넌트 : 목록의 각 항목
https://fonts.google.com/icons
Google Material Design 에서 아이콘 이미지를 다운받아 준비한다.
IconButton 컴포넌트
아이콘 이미지를 관리할 images.js 폴더 생성
src/images.js
import CheckBoxOutline from '../assets/icons/check_box_outline.png';
import CheckBox from '../assets/icons/check_box.png';
import DeleteForever from '../assets/icons/delete.png';
import Edit from '../assets/icons/edit.png';
export const images = {
uncompleted: CheckBoxOutline,
completed: CheckBox,
delete: DeleteForever,
update: Edit,
};
src/components/IconButton.js
import React from "react";
import { TouchableOpacity } from "react-native";
import styled from "styled-components/native";
import PropTypes from 'prop-types';
import { images } from '../images';
const Icon = styled.Image`
tint-color: ${({ theme }) => theme.text};
width: 30px;
height: 30px;
margin: 10px;
`;
const IconButton = ({ type, onPressOut }) => {
return(
<TouchableOpacity onPressOut={onPressOut}>
<Icon source={type} />
</TouchableOpacity>
);
};
IconButton.propTypes = {
type: PropTypes.oneOf(Object.values(images)).isRequired,
onPressOut: PropTypes.func,
};
export default IconButton;
- IconButton 컴포넌트 호출 시 원하는 이미지의 종류를 props에 type으로 전달
- 아이콘의 색은 입력되는 텍스트와 동일한 색 적용
Task 컴포넌트
완료 여부 확인 버튼, 입력된 할 일 내용, 항목 삭제, 수정 버튼으로 구성
src/components/Task.js
import React from "react";
import styled from "styled-components/native";
import PropTypes from 'prop-types';
import IconButton from "./IconButton";
import { images } from '../images';
const Container = styled.View`
flex-direction: row;
align-items: center;
background-color: ${({ theme }) => theme.itemBackground};
border-radius: 10px;
padding: 5px;
margin: 3px 0px;
`;
const Contents = styled.Text`
flex: 1;
font-size: 24px;
color: ${({ theme }) => theme.text};
`;
const Task = ({ text }) => {
return(
<Container>
<IconButton type={images.uncompleted} />
<Contents>{text}</Contents>
<IconButton type={images.update} />
<IconButton type={images.delete} />
</Container>
);
};
Task.propTypes = {
text: PropTypes.string.isRequired,
};
export default Task;
- 할 일 내용은 props로 전달받은 값을 입력하며, 각 아이콘을 입력한다.
- App.js에 Task 컴포넌트 목록을 만든다
- 리액트 네이티브에서 제공하는 ScrollView 컴포넌트 이용. (화면을 넘어가도 스크롤 이용)
- 양쪽의 공백을 동일하게 하기 위해 Dimensions로 화면 너비 구한 후 스타일에 사용
결과
'dev > React native' 카테고리의 다른 글
[React Native] Hooks (0) | 2021.11.12 |
---|---|
[React Native] 할 일 관리 애플리케이션(2) (0) | 2021.11.06 |
[React Native] 스타일링 (0) | 2021.10.16 |
[React Native] 컴포넌트 (0) | 2021.10.10 |
[React Native] JSX (0) | 2021.10.10 |