2 분 소요

🔮 이전 강의 backup

수정 사항

  1. onDelete -> onRemove
  2. onClick 화살표 함수 가독성 떨어짐 -> 구현부를 따로 빼서 handleRemove 함수 구현
// DiaryItem.js
const DiaryItem = ({
  onRemove,
  author,
  content,
  created_date,
  emotion,
  id,
}) => {
  const handleRemove = () => {
    if (window.confirm(`${id}번 째 일기를 삭제하시겠습니까?`)) {
      onRemove(id);
    }
  };
  return (
    <div className="DiaryItem">
      <div className="info">
        <span>
          작성자 : {author} | 감정점수 : {emotion}
        </span>
        <br />
        <span className="date"> {new Date(created_date).toLocaleString()}</span>
      </div>
      <div className="content">{content}</div>
      <button onClick={handleRemove}>삭제하기</button>
      <button>수정하기</button>
    </div>
  );
};

export default DiaryItem;

📐 수정하기 버튼 만들기

📍 버튼 클릭하면 작동해야되는 기능

  1. 버튼 클릭 -> <button>수정하기</button>
  2. 리스트 내에서 수정 폼 생성 -> state로 생성

📍 수정폼 만들기 step 1.

import { useState } from "react";
const DiaryItem = ({
  onRemove,
  author,
  content,
  created_date,
  emotion,
  id,
}) => {
  const [isEdit, setIsEdit] = useState(false); // 🌟
  const toggleIsEdit = () => setIsEdit(!isEdit); // 🌟

  const handleRemove = () => {
    if (window.confirm(`${id}번 째 일기를 삭제하시겠습니까?`)) {
      onRemove(id);
    }
  };

  return (
    <div className="DiaryItem">
      <div className="info">
        <span>
          작성자 : {author} | 감정점수 : {emotion}
        </span>
        <br />
        <span className="date"> {new Date(created_date).toLocaleString()}</span>
      </div>
      <div className="content">{content}</div>
      <button onClick={handleRemove}>삭제하기</button>
      <button onClick={toggleIsEdit}>수정하기</button>
    </div>
  );
};

export default DiaryItem;
  • isEdit : 현재 수정중이면 true, 아니라면 false를 setState에서 반환받음
  • toggleIsEdit : 호출이 되는 순간 원래의 isEdit값을 반전시킨다.

📍 수정폼 만들기 step 2.

toggleIsEdit이 클릭되었을 때 어떻게 구현?

  • isEdit === true : 입력창
  • isEdit === false : 저장
<div className="content">
  {isEdit ? (
    <>
      <textarea
        value={localContent}
        onChange={(e) => {
          setLocalContent(e.target.value);
        }}
      />
    </>
  ) : (
    <>{content}</>
  )}
</div>
  • isEdit === true 라면 입력창(textarea)를 띄운다. -> 수정한 값을 저장하기 위해서는 어떻게,,?
  • sol. content 입력했던 방식과 동일하게, 입력받은 값을 localContent로 받아와서 setLocalContent를 통해서 리랜더링한다.

📐 수정 취소, 수정 완료 버튼

📍 수정 취소, 완료 버튼 기본 틀

isEdit에 따라 true이면 수정 취소, 수정 완료 버튼을
isEdit이 false이면 삭제하기, 수정하기 버튼을 구현

📍 수정 취소, 완료 버튼 구현

  • 삭제하기, 수정하기는 기존에 구현해놓았던 것이다.

    <button onClick={handleRemove}>삭제하기</button>
    <button onClick={toggleIsEdit}>수정하기</button>
    
  • 수정 취소 버튼 구현
    기존에 isEdit이 true니까 textarea가 떴을텐데, 취소를 눌러주었으므로 isEdit을 false로 만들면 된다

    <button onClick={toggleIsEdit}>수정 취소</button>
    

    ❗ 문제점 ❗
    근데 여기서 수정하기 버튼을 눌러 입력을 수정 취소 를 누르고 다시 수정하기 버튼을 누르면 기존에 수정하다가 취소한 내용이 그대로 있다.
    💡 해결책 💡
    기존의 content를 setLocalContent()를 통해서 기존 내용이 다시 textarea에 입력되도록 한다.

    const handleQuitEdit = () => {
      setIsEdit(false);
      setLocalContent(content);
    };
    <button onClick={handleQuitEdit}>수정 취소</button>;
    
    • setLocalContent : 수정한 내용을 저장하기 위해 만들어놓은 함수
      이 함수를 이용하여 수정 전 내용이 들어있는 content를 넣어준다.
  • 수정 완료 버튼 구현

    생각을 해보았을 때, 지금 App.js에서는 데이터를 다루고 있다.
    그렇기 때문에 데이터를 수정하기 위해서는 App.js까지 몇 번째 값이 어떤 내용으로 변경이 되어야 되는지 전달을 해주어야 되고(DiaryItem.js -> App.js : Event), App.js에서는 수정을 위한 함수를 구현하여 DiaryList를 거쳐 DiaryItem까지 와서(App.js -> DiaryList.js -> DiaryItem.js : data) 내용을 수정한 것을 출력해준다. .

    1. App.js 수정
    const onEdit = (targetId, newContent) => {
      setData(
        data.map((it) =>
          it.id === targetId ? { ...it, content: newContent } : it
        )
      );
    };
    
    <DiaryList onEdit={onEdit} diaryList={data} onRemove={onRemove} />;
    

    수정될 위치를 targetId, 수정된 내용을 newContent로 DiaryItem에서 가져왔다.
    그럼 얘 어떻게 수정해? -> 앞에서 객체별로 데이터를 넣어주기 위해서 setData()를 통해서 일기 리스트 객체에 값을 추가하거나 삭제했다. 수정도 마찬가지로 setData()를 쓰는데, 수정할 ID의 객체의 content만 newContent로 수정

  1. DiaryItem.js 수정

    const handleEdit = () => {
      if (localContent.length < 5) {
        localContentInput.current.focus();
        return;
      }
    
      if (window.confirm(`${id}번 째 일기를 수정하시겠습니까?`)) {
        onEdit(id, localContent);
        toggleIsEdit();
      }
    };
    

🌗 결과

download1
download2
download3

태그:

카테고리:

업데이트:

댓글남기기