#8 메모 수정 기능 구현

2026. 6. 13. 15:09·Project/Memo Evolution

 

이번 단계에서는 메모장 CRUD 기능 중 Update, 즉 수정 기능을 구현했다.

이전까지는 다음 기능이 가능했다.

  • 메모 추가
  • 메모 목록 출력
  • 메모 삭제
  • localStorage 저장 및 불러오기

하지만 작성한 메모를 수정할 수는 없었다.

이번에는 메모 카드에 수정 버튼을 추가하고, 사용자가 기존 제목과 내용을 바꿀 수 있도록 만들었다.

 

수정 버튼 추가하기

기존에는 메모 카드 안에 삭제 버튼만 있었다.

memoCard.innerHTML = `
    <h3>${memo.title}</h3>
    <p>${memo.content}</p>
    <button type="button">삭제</button>
`;

수정 기능을 만들기 위해 버튼을 하나 더 추가했다.

memoCard.innerHTML = `
    <h3>${memo.title}</h3>
    <p>${memo.content}</p>
    <button class="edit-button" type="button">수정</button>
    <button class="delete-button" type="button">삭제</button>
`;

버튼이 두 개가 되었기 때문에 각각 구분할 수 있도록 class를 붙였다.

<button class="edit-button" type="button">수정</button>
<button class="delete-button" type="button">삭제</button>

그리고 JavaScript에서 각각의 버튼을 따로 가져왔다.

const editButton = memoCard.querySelector('.edit-button');
const deleteButton = memoCard.querySelector('.delete-button');

기존처럼 memoCard.querySelector('button')만 사용하면 첫 번째 버튼 하나만 찾게 된다.
그래서 수정 버튼과 삭제 버튼을 명확히 구분하기 위해 각각 다른 클래스를 사용했다.

 

수정 버튼 이벤트 등록하기

수정 버튼을 클릭하면 기존 제목과 내용을 수정할 수 있어야 한다.

수정 버튼은 각 메모 카드가 만들어질 때 함께 생성된다.
그래서 수정 버튼 이벤트도 renderMemos() 안에서 메모 카드를 만들 때 같이 등록했다.

editButton.addEventListener('click', function () {
    // 수정 처리
});

이 이벤트 함수는 사용자가 해당 메모 카드의 수정 버튼을 눌렀을 때 실행된다.

 

기존 값을 보여주고 새 값 입력받기

수정할 값을 입력받기 위해 prompt()를 사용했다.

const newTitle = prompt("새 제목을 입력하세요", memo.title);
const newContent = prompt("새 내용을 입력하세요", memo.content);

prompt()의 두 번째 인자는 기본값이다.

prompt("새 제목을 입력하세요", memo.title);

이렇게 작성하면 prompt 창이 열릴 때 기존 제목이 입력창에 미리 들어가 있다.
내용도 마찬가지로 기존 내용을 기본값으로 보여준다.

prompt("새 내용을 입력하세요", memo.content);

즉, 수정 버튼을 누르면 기존 제목과 기존 내용이 먼저 보이고, 사용자는 그 값을 바꿔서 입력할 수 있다.

 

취소 처리하기

사용자가 prompt에서 취소를 누를 수도 있다.

prompt에서 취소를 누르면 결과값은 null이다.
그래서 다음 조건을 추가했다.

if (newTitle === null || newContent === null) {
    return;
}

이 코드는 사용자가 제목이나 내용 입력 중 하나라도 취소하면 수정 작업을 중단한다.

여기서 return은 현재 클릭 이벤트 함수를 끝내는 역할을 한다.

취소 누름
→ 수정하지 않음
→ 저장하지 않음
→ 화면 다시 그리지 않음

 

빈 값 방지하기

수정할 때 제목이나 내용을 빈 값으로 두는 것도 막았다.

if (newTitle === '' || newContent === '') {
    alert("제목과 내용을 모두 입력하세요.");
    return;
}

제목이나 내용 중 하나라도 빈 문자열이면 alert를 띄우고 수정 작업을 중단한다.

현재는 완전히 빈 문자열만 막는다.
나중에는 trim()을 사용해서 공백만 입력한 경우도 막을 수 있다.

if (newTitle.trim() === '' || newContent.trim() === '') {
    alert("제목과 내용을 모두 입력하세요.");
    return;
}

 

map으로 해당 메모 수정하기

이번 수정 기능의 핵심은 memos.map()이다.

memos = memos.map(function (item) {
    if (item.id === memo.id) {
        return {
            id: item.id,
            title: newTitle,
            content: newContent
        };
    }

    return item;
});

처음에는 이 부분이 헷갈렸다.

수정 버튼은 메모 하나의 버튼인데, 왜 배열 전체를 도는지 의문이 생겼다.

이유는 현재 메모의 원본 데이터가 memos 배열이기 때문이다.

let memos = [];

화면에 보이는 메모 카드는 원본이 아니라, memos 배열을 보고 그린 결과다.
따라서 메모를 수정하려면 화면의 글자만 바꾸는 것이 아니라 memos 배열 안의 해당 메모 데이터를 바꿔야 한다.

map()은 배열을 돌면서 새로운 배열을 만드는 메서드다.

이번 코드에서는 다음처럼 동작한다.

1. memos 배열을 하나씩 확인한다.
2. 현재 item의 id가 수정하려는 memo.id와 같으면 새 제목/내용을 가진 객체를 반환한다.
3. id가 다르면 기존 item을 그대로 반환한다.
4. 그 결과로 새 배열을 만들고 다시 memos에 넣는다.

예를 들어 현재 배열이 이렇게 있다고 하자.

memos = [
    { id: 1, title: 'A', content: '내용 A' },
    { id: 2, title: 'B', content: '내용 B' },
    { id: 3, title: 'C', content: '내용 C' }
];

id가 2인 메모를 수정한다면 다음처럼 처리된다.

id 1 → 수정 대상 아님 → 그대로 반환
id 2 → 수정 대상 맞음 → 새 제목/내용으로 바꾼 객체 반환
id 3 → 수정 대상 아님 → 그대로 반환

결과적으로 배열은 이렇게 바뀐다.

memos = [
    { id: 1, title: 'A', content: '내용 A' },
    { id: 2, title: '새 제목', content: '새 내용' },
    { id: 3, title: 'C', content: '내용 C' }
];

전체 배열을 돌지만 실제로 바뀌는 것은 id가 같은 메모 하나뿐이다.

 

수정 후 저장하고 다시 그리기

배열에서 메모를 수정한 뒤에는 두 가지 작업이 필요하다.

saveMemos();
renderMemos();

먼저 수정된 memos 배열을 localStorage에 저장한다.

saveMemos();

그래야 새로고침 후에도 수정된 내용이 유지된다.

그다음 화면을 다시 그린다.

renderMemos();

현재 화면은 이전 메모 내용을 보여주고 있기 때문에, 수정된 memos 배열을 기준으로 다시 렌더링해야 한다.

이 프로젝트의 기본 흐름은 계속 동일하다.

데이터 변경
→ saveMemos()
→ renderMemos()

추가할 때도 같은 흐름이다.

memos.push(newMemo);
saveMemos();
renderMemos();

삭제할 때도 같은 흐름이다.

memos = memos.filter(...);
saveMemos();
renderMemos();

수정할 때도 같은 흐름이다.

memos = memos.map(...);
saveMemos();
renderMemos();

즉, 추가, 삭제, 수정 모두 같은 구조를 가진다.

 

수정 이벤트 전체 코드

수정 버튼 이벤트 코드는 다음과 같다.

editButton.addEventListener('click', function () {
    const newTitle = prompt("새 제목을 입력하세요", memo.title);
    const newContent = prompt("새 내용을 입력하세요", memo.content);

    if (newTitle === null || newContent === null) {
        return;
    }

    if (newTitle === '' || newContent === '') {
        alert("제목과 내용을 모두 입력하세요.");
        return;
    }

    memos = memos.map(function (item) {
        if (item.id === memo.id) {
            return {
                id: item.id,
                title: newTitle,
                content: newContent
            };
        }

        return item;
    });

    saveMemos();
    renderMemos();
});

 

'Project > Memo Evolution' 카테고리의 다른 글

#10 React로 넘어가기 전에 컴포넌트 이해하기  (0) 2026.06.15
#9 JavaScript 코드 구조 정리하기  (0) 2026.06.15
#7 localStorage로 메모 저장하기  (0) 2026.06.13
#6 메모 내용 줄바꿈 처리하기  (0) 2026.06.11
#5 메모데이터를 배열로 관리  (0) 2026.06.11
'Project/Memo Evolution' 카테고리의 다른 글
  • #10 React로 넘어가기 전에 컴포넌트 이해하기
  • #9 JavaScript 코드 구조 정리하기
  • #7 localStorage로 메모 저장하기
  • #6 메모 내용 줄바꿈 처리하기
sqaxe1
sqaxe1
woojoo-devlog 님의 블로그 입니다.
  • sqaxe1
    Woojoo's Devlog
    sqaxe1
  • 전체
    오늘
    어제
    • 분류 전체보기 (148)
      • Backend (9)
        • Servlet (7)
        • Spring (2)
      • Frontend (1)
      • CS (0)
      • Book (33)
        • 자바 웹 프로그래밍 Next Step (30)
        • 테스트 주도 개발: 고품질 쾌속개발을 위한 TDD.. (1)
        • 성공과 실패를 결정하는 1%의 네트워크 원리 (2)
      • Engineering (0)
        • Testing (0)
      • Infra (6)
        • AWS (6)
      • Java (4)
      • Network (1)
      • 김영한 (28)
        • 자바 입문 (8)
        • 실전 자바 - 기본편 (6)
        • 실전 자바 - 중급편 (10)
        • 실전 자바 - 고급편 (4)
      • Web (39)
        • Web Basics (39)
      • Project (24)
        • NeoSquare (0)
        • Memo Evolution (24)
      • 정보처리기사 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    java
    aws
    개발서적
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
sqaxe1
#8 메모 수정 기능 구현
상단으로

티스토리툴바