본문 바로가기
Frontend/Frontend 프로젝트

React App 만들기 - 메모 기능 구현하기

by 천우산__ 2023. 6. 20.

구현이 필요한 기능들

구현한 적 있는 기능

  1. 현재 시간 알려주는 기능 (시계)
  2. 날씨 정보를 반환하는 기능 (API)
  3. 할 일을 등록할 수 있는 기능 (Form)
  4. 할 일 리스트를 보여주는 영역 (Todo-list)
  5. 할 일을 지울 수 있는 기능

새롭게 구현해 보고 싶은 기능

  1. 만다라트 생성
  2. 날씨 현황에 따른 배경화면 이펙트

두 번 째 기능 구현을 하기 전, 시계 기능을 하는 코드들을 별도 컴포넌트로 이동시켰다.

기능 별로 분리해서 관리하는 것이, 다른 페이지 구현 때 재사용하기에도 편리하고, 기능 수정 할 때 코드 찾는 것도 수월하기 때문이다.

// App.jsx

import './App.css';
import { useState } from 'react';
import Todos from './Todos.jsx' // 오늘 할 것
import Clock from './Clock.jsx' // 별도로 구현

function App() {
  return (
    <div className="App">
      <Clock/> // 시계 기능
      <h3 className='wheaterInfo'> wheater infomation will here</h3>
      <Todos/> // 오늘 할 것
    </div>
  );
}

export default App;
// Clock.jsx

import { useState } from 'react';

function Clock() {
    const nowTime = () => {
        const now = new Date();
        const hour = String(now.getHours()).padStart(2, "0");
        const minute = String(now.getMinutes()).padStart(2, "0");
        const second = String(now.getSeconds()).padStart(2, "0");
        
        return `${hour} : ${minute} : ${second}`
    }
    
    const [clock, setclock] = useState(nowTime);
    setInterval(() => setclock(nowTime), 1000);
    
    return (
        <h1 className='clockInfo'> { clock } </h1>
    )

}

export default Clock;

다음으로, 메모 기능을 넣기 위해 아래 사항들을 고려했다.

  1. 메모를 등록하는 공간과 기능이 필요
  2. 등록된 메모들을 볼 수 있는 공간이 필요
  3. 신규 메모 등록 시, 기존 메모 삭제 x

기초 공사로 아래와 같이 코드를 작성했다.

// Todos.jsx

import { useState } from 'react';

function Todos() {
    const [todoList, setTodoList] = useState([]);

    return (
        <div>
            <div className='todoListArea'> todo-list will here</div>
            
            <form> 
                <input type='text' name='todo' placeholder='write your todoList'/>
            </form>
        </div>
    )
}
export default Todos;

form 영역 내 input 데이터를 받는다고 가정하고, 제출 시, todoList 에 추가할 목적으로 useState를 이용하여

두 변수를 생성하였다. 이제 form 영역 안의 input 데이터를 받아 todoList로 저장하는 기능을 구현한다.

// Todos.jsx

import { useState } from 'react';

function Todos() {
    const [todoList, setTodoList] = useState([]);
    
    //form 제출 시 동작 실행 함수
    const submitFunction = (event) => {

        const todo = event.target.todo.value; // input data 값 읽어오기
        setTodoList([todo, ...todoList ]); // todoList에 추가하기

    }

    return (
        <div>
            <div className='todoListArea'> todo-list will here</div>
            {todoList}
            <form onSubmit={submitFunction}>  // form 제출 시 동작 실행
                <input type='text' name='todo' placeholder='write your todoList'/>
            </form>
        </div>
    )
}
export default Todos;

input 태그의 value를 읽기 위해서 input 태그의 name (여기서는 'todo') 값을 참조하였고, 이 데이터를 todoList에 추가해주는데,

이미 todoList 데이터 형식이 배열이므로, 배열 상태에서 그대로 추가하는 경우 (ex. [todo, todoList] )  배열의 차원이 계속해서

깊어질 것으로 예상되기 때문에, 배열 값에 추가 할 때, 기존의 todoList 데이터를 구조분해 할당([...todoList]) 하여 새로운 데이터와

합쳐주는 과정이 필요하다.

이 과정까지 진행한 후 테스트를 해보니, form 제출로 인해 페이지 새로고침이 발생하였고, 페이지 새로고침으로 인해

todoList가 초기값인 빈 배열로 돌아가, 데이터를 제대로 표기할 수 없었다.

form 태그가 아닌, button으로 데이터를 등록하는 방법도 있지만, 엔터로 데이터를 입력하는 방식을 유지하고 싶었기 때문에

코드를 아래와 같이 수정했다.

import { useState } from 'react';

function Todos() {
    const [todoList, setTodoList] = useState([]);
    const submitFunction = (event) => {
        event.preventDefault(); // 새로고침 방지
        
        const todo = event.target.todo.value;
        setTodoList([todo, ...todoList ]);

        event.target.todo.value = ''; // input 태그 값 초기화
    }

    return (
        <div>
            <div className='todoListArea'> todo-list will here</div>
            {todoList}
            <form onSubmit={submitFunction}> 
                <input type='text' name='todo' placeholder='write your todoList'/>
            </form>
        </div>
    )
}
export default Todos;

event.preventDefault(); 를 통해, form 제출로 인해 기본적으로 일어나는 새로고침을 방지하고,

데이터 입력이 완료된 후, input 태그의 값을 비워주기 위해 event.target.todo.value = ''; 를 사용했다.

멋은 없어도 기능 구현은 확인되었다.

아직 추가적으로 구현해야할 기능들이 있다. 위 이미지는 2개의 메모를 등록한 상황인데, 두 메모가 붙여서 표기된다.

리스트들은 구별하기 쉽게 나눠줘야 할 필요가 있으며, 추후 구현해야할 메모 삭제 기능을 대비해서 삭제할 수 있는 버튼을 등록해야 한다.