본문 바로가기
PROJECT/Toy Project

[React] To Do List 만들기 - 2

by 히컵 2024. 9. 30.

 

리액트로 To Do List 만들기

📖 사용 기술

Editor : VScode

Language

  • html
  • css
  • React.js

배포: Github.io 클릭

 

📂 컴포넌트 구조

 📂 src
 ├── 📂 components
 │   ├── 📄 AddTodo.js    # 할 일 추가 컴포넌트
 │   ├── 📄 Container.js  # 레이아웃을 담당하는 컨테이너 컴포넌트
 │   ├── 📄 Title.js      # 타이틀 컴포넌트
 │   ├── 📄 TodoList.js   # 할 일 목록 컴포넌트
 └── 📄 App.js            # 메인 애플리케이션 컴포넌트

 

📖 기능

  • 할 일 추가
  • 할 일 삭제
  • 할 일 수정
  • 할 일 완료 여부 체크
  • 할 일 목록 표시
  • 로컬 스토리지 활용 : 페이지를 새로고침하거나 브라우저 닫아도 데이트가 유지된다.

 

📖 업데이트

  • 컴포넌트 분할 : 코드를 모듈화하기 위해 여러 개의 컴포넌트로 분리해 보았다.
  • styled-components 사용 : 각 컴포넌트에 스타일을 적용하기 위해 css 대신 styled-components를 사용해서 컴포넌트 내부에서 스타일을 관리할 수 있도록 했다.
  • 수정 기능 추가 : 기존 버전에서는 할 일 항목을 수정할 수 없었지만, 이번 업데이트에서 사용자가 항목을 수정하고 저장할 수 있는 기능을 추가했다.

 

📖 기능 구현

할 일 수정

const [editIndex, setEditIndex] = useState(null);  // 수정 중인 항목의 인덱스
const [editText, setEditText] = useState('');      // 수정 중인 텍스트

- 수정 중인 항목을 찾기 위해서 useState를 사용해서 수정 중인 항목의 인덱스와 텍스트를 상태로 관리한다.

- editIndex : 현재 수정 중인 할 일 항목의 인덱스를 저장, 수정 모드가 아닐 경우 null로 설정되어 있다.

- editText : 사용자가 수정할 내용을 입력하는 필드의 값을 저장

 

function handleEdit(index) {
    setEditIndex(index);  // 수정할 항목의 인덱스 설정
    setEditText(list[index].text);  // 해당 항목의 텍스트를 editText에 설정
}

- 사용자가 수정 버튼을 누르면 해당 항목이 수정 모드로 전환된다. 수정하려는 항목의 인덱스를 editIndex에 저장하고, 해당 항목의 텍스트를 editText로 저장해 수정 가능한 상태로 만든다.

 

function saveEdit(index) {
    let updateList = list.map((item, i) => {
        if (i === index) {
            return { ...item, text: editText };  // 텍스트 업데이트
        }
        return item;
    });
    setList(updateList);  // 리스트 업데이트
    setEditIndex(null);   // 수정 모드 종료
}

- 수정된 내용을 저장하려면 저장 버튼을 클릭하여 수정된 텍스트를 리스트에 반영해야 한다. 수정 중인 항목의 인덱스에 해당하는 데이터를 editText로 업데이트하고 editInex를 다시 null로 만들어 수정 모드를 종료한다.

- 수정된 텍스트는 editText에 저장된 값으로 덮어씌워지고 리스트 전체가 업데이트 된다.

 

{
    editIndex === i
    ? <Btn onClick={() => saveEdit(i)}>저장</Btn>
    : <Btn onClick={() => handleEdit(i)}>수정</Btn>
}

- 수정 버튼 : editIndex와 현재 항목의 인덱스가 일치하지 않는 경우에 활성화되며, 클릭 시 수정 모드로 바뀐다.

- 삭제 버튼 : 수정 중인 항목에만 나타나며, 클릭하면 수정된 내용을 저장하고 수정 모드를 종료한다.

 

{
    editIndex === i 
    ? <EditInput value={editText} onChange={(e) => setEditText(e.target.value)} autoFocus />
    : <Text style={{ textDecoration: item.completed ? 'line-through' : 'none' }}>{item.text}</Text>
}

- 수정 모드일 때와 아닐 때의 UI를 다르게 만들었다.

- editInex와 현재 항목의 인덱스가 일치하면 input을 사용해 텍스트를 편집할 수 있도록 하고, 그렇지 않은 경우네는 텍스트가 그대로 표시된다.

 


🌱 후기

백지 상태에서 다시 만들어 보니 또 새로운 느낌... 술술 풀리는 부분이 있었다면 또 막히는 부분도 있었다. 그래도 처음 만드는 게 아니어서 금방 해결하기는 했다. 버전 2는 버전 1과 다르게 UI 디자인도 넣고, 위에 적지는 않았지만 추가 버튼을 클릭하지 않아도 엔터를 치면 할 일이 추가 되도록 했고, 또 수정 기능도 구현했다.

그냥 CSS를 이용해도 됐지만 배운 것을 활용해 보고 싶어서 styled-components를 이용해서 스타일을 입혔다. css 파일을 따로 열지 않아도 되는 편리함이 있기는 했는데, 오히려 js 파일이 더 길어져서 더 복잡해 보인다. 일반 컴포넌트랑 구별이 잘 안 돼서 헷갈리기도 하고.. 그래도 사용해 본 것에 의의를 두고 다음번에는 css파일을 모듈화해서 사용해 봐야겠다.

그리고 수정 기능을 구현하는 게 생각보다 어려웠다. 어떻게 해야 하는지 알겠는데? 어떻게 해야 할지 모르겠어.. 진짜 이게 무슨 말인가 싶지만 처음 시작할 때 느낌이 딱 그랬다. 수정할 항목의 인덱스로 수정 모드와 아닌 경우를 구분할 생각을 처음에 못 했어서 더 막막하게 느꼈던 것 같다. 비슷한 프로젝트를 계속 만들어 보면 이런 흐름도 빠르게 떠올릴 수 있겠지...