티스토리 뷰

반응형

갓난애기도 배울 수 있는 React Native 가이드 ⏹️ 마무리 편 – 실전 To-Do 앱 확장 프로젝트

지금까지 우리는 React Native의 기초부터 화면 전환, 상태관리, 리스트 처리, 배포까지 모두 경험해봤습니다.
이제는 모든 내용을 하나로 통합해, 기능 완성도 높은 To-Do 앱을 실전으로 완성해볼 시간입니다.

이번 마무리 프로젝트에서는 다음 기능을 구현합니다:


✅ 최종 앱 기능 목록

기능 설명

할 일 입력 TextInput으로 텍스트 입력
추가 버튼으로 리스트에 추가
삭제 각 항목 옆에 삭제 버튼
완료 체크 체크박스로 완료 상태 표시
화면 전환 상세 보기 화면 구현
상태 유지 useState 기반으로 관리

✅ 1. 전체 디렉토리 구조

/screens
  ├── HomeScreen.js
  ├── DetailScreen.js
App.js

✅ 2. App.js – Stack Navigator 설정

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './screens/HomeScreen';
import DetailScreen from './screens/DetailScreen';

const Stack = createNativeStackNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} options={{ title: '나의 할 일' }} />
        <Stack.Screen name="Detail" component={DetailScreen} options={{ title: '할 일 상세' }} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

✅ 3. HomeScreen.js – 할 일 추가/삭제/체크 + 이동

반응형
import React, { useState } from 'react';
import {
  View, Text, TextInput, FlatList, Button,
  TouchableOpacity, StyleSheet, Pressable
} from 'react-native';

export default function HomeScreen({ navigation }) {
  const [text, setText] = useState('');
  const [todos, setTodos] = useState([]);

  const addTodo = () => {
    if (!text.trim()) return;
    const newTodo = {
      id: Date.now().toString(),
      title: text,
      done: false,
    };
    setTodos([newTodo, ...todos]);
    setText('');
  };

  const toggleDone = (id) => {
    setTodos(todos.map(todo => todo.id === id
      ? { ...todo, done: !todo.done }
      : todo));
  };

  const deleteTodo = (id) => {
    setTodos(todos.filter(todo => todo.id !== id));
  };

  return (
    <View style={styles.container}>
      <TextInput
        placeholder="할 일을 입력하세요"
        value={text}
        onChangeText={setText}
        style={styles.input}
      />
      <Button title="추가하기" onPress={addTodo} />

      <FlatList
        data={todos}
        keyExtractor={(item) => item.id}
        renderItem={({ item }) => (
          <Pressable
            style={styles.todoItem}
            onPress={() => navigation.navigate('Detail', { todo: item })}
          >
            <Text style={[styles.todoText, item.done && styles.done]}>
              {item.done ? '✅' : '⬜️'} {item.title}
            </Text>
            <View style={styles.actions}>
              <Button title={item.done ? '취소' : '완료'} onPress={() => toggleDone(item.id)} />
              <Button title="삭제" color="red" onPress={() => deleteTodo(item.id)} />
            </View>
          </Pressable>
        )}
        ListEmptyComponent={<Text style={{ marginTop: 20 }}>할 일이 없습니다.</Text>}
        style={{ marginTop: 20 }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, paddingTop: 60 },
  input: {
    borderWidth: 1,
    borderColor: '#aaa',
    padding: 10,
    marginBottom: 10,
    borderRadius: 6,
  },
  todoItem: {
    padding: 12,
    borderBottomWidth: 1,
    borderColor: '#eee',
  },
  todoText: { fontSize: 18 },
  done: { textDecorationLine: 'line-through', color: '#999' },
  actions: { flexDirection: 'row', gap: 10, marginTop: 8 },
});

✅ 4. DetailScreen.js – 상세 화면 구현

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

export default function DetailScreen({ route }) {
  const { todo } = route.params;

  return (
    <View style={styles.container}>
      <Text style={styles.label}>할 일 제목</Text>
      <Text style={styles.value}>{todo.title}</Text>

      <Text style={styles.label}>완료 여부</Text>
      <Text style={styles.value}>{todo.done ? '✅ 완료됨' : '❌ 아직'}</Text>

      <Text style={styles.label}>ID</Text>
      <Text style={styles.value}>{todo.id}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 24 },
  label: { fontSize: 18, color: '#888', marginTop: 20 },
  value: { fontSize: 22, fontWeight: 'bold' },
});

✅ 5. 추가 확장 아이디어 (자유 과제 🎓)

기능 설명

로컬 저장 AsyncStorage 이용한 데이터 저장
날짜 입력 DatePicker 연동
중요도 표시 색상, 우선순위 등 추가
다크모드 대응 useColorScheme 사용

✅ 6. 최종 마무리 정리

배운 기술 적용 위치

JSX & 컴포넌트 App 구조 전반
useState 입력, 완료 상태 관리
FlatList 리스트 반복 처리
Stack Navigation 화면 전환 및 params 전달
스타일링 StyleSheet 사용

🎉 여러분은 이제 React Native로 앱을 직접 만들 수 있습니다!

  • 기본 구조를 이해했고
  • 실전 앱을 직접 설계했고
  • 빌드와 배포까지 경험했으며
  • 확장도 가능해졌습니다

이제 여러분만의 앱을 만들어보세요.
갓난애기에서... 앱개발자 됐습니다 👶→👨‍💻✨


 

React Native ToDo 앱 완성,React Native 실전 프로젝트,React Native 앱 상태관리,React Native 완료 체크,React Native 상세 화면 이동,React Native 삭제 기능 구현,React Native 실습 정리,React Native 마무리 프로젝트,React Native 앱 구조 예제,React Native 통합 실전 앱

 

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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
글 보관함
반응형