인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

HK님의 프로필 이미지
HK

작성한 질문수

[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

8.6) Update - 투두 수정하기

투두리스트 content 수정 기능 추가 문의

해결된 질문

작성

·

45

·

수정됨

0

투두리스트를 만들고 있는데

여기서 만약 삭제버튼 옆에 수정버튼을 추가하여

todo list에 입력한 content 내용을 수정할 수 있는 기능을 추가하려면

todolist 내용 요소를 div요소에서 input text 요소로 바꾸고
보이기는 input value사용하고,

수정은 OnChange 이벤트를 사용하면 될까요?

 

답변 2

1

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

안녕하세요 이정환입니다.

네 맞습니다. 그렇게 처리하시면 됩니다.

더 업그레이드하자면 isEditNow State를 추가로 생성하셔서 사용자가 수정 버튼을 클릭하기 전 까지는 <div> 요소를 통해 내용을 보여주다가, 수정 버튼을 클릭하면 <input> 요소를 통해 내용을 보여주어 수정할 수 있도록 만드셔도 됩니다.

HK님의 프로필 이미지
HK
질문자

답변 감사합니다. 알려주신대로 코드를 작성해보았습니다.

 


import React, { useRef, useState } from "react";
import "./TodoItem.css";
const TodoItem = ({ content, id, isDone, date, onUpdate, onDelete }) => {
  const editInputRef = useRef(null);
  const [isEdit, setIsEdit] = useState();
  const [upContent, setUpcontent] = useState(content);
  const onChangeCheckbox = () => {
    onUpdate(id); // checkbox event, id는 number
  };

  const onClickDeleteButton = () => {
    onDelete(id);
  };

  const onClickUpdateButton = () => {
    onUpdate("_", upContent); // content text updated
    setIsEdit(!isEdit);
  };

  const onChangeUpdate = (e) => {
    setUpcontent(e.target.value);
  };

  return (
    <div className="TodoItem">
      <input onChange={onChangeCheckbox} type="checkbox" readOnly checked={isDone} />
      {isEdit ? (
        <input type="text" value={upContent} ref={editInputRef} onChange={onChangeUpdate} />
      ) : (
        <div className="content">{upContent}</div>
      )}
      <div className="date">{new Date(date).toLocaleDateString()}</div>
      <button onClick={onClickDeleteButton}>삭제</button>
      <button onClick={onClickUpdateButton}>수정</button>
    </div>
  );
};

export default TodoItem;


// ================================


  const onUpdate = (targetId, upContent) => {
    if (!isNaN(targetId)) { // id가 number일때 isDone 실행하고, id가 string일때 content text 업데이트
      setTodos(todos.map((todo) => (todo.id === targetId ? { ...todo, isDone: !todo.isDone } : todo)));
    } else {
      setTodos(todos.map((todo) => (todo.id === targetId ? { ...todo, content: upContent } : todo)));
    }
  };

0

안녕하세요, 인프런 AI 인턴입니다.

HK님, 투두리스트에 수정 기능을 추가하는 방법에 대해 질문해 주셨네요. 수정 기능을 구현할 때는 보통 input 요소를 사용하여 현재 상태를 반영하고, onChange 이벤트 핸들러를 통해 사용자 입력을 실시간으로 state에 저장할 수 있도록 합니다. 아래는 기본적인 구현 방법에 대한 설명입니다.

  1. State로 관리하기: 먼저 수정 모드를 관리할 수 있도록 state를 사용합니다. 예를 들어, isEdit 상태를 추가하여 수정 중인지 여부를 결정합니다.

  2. Input 요소: isEdit 상태에 따라서 div에서 input으로 전환합니다. 수정 모드일 때는 input 요소가 나타나고, 그렇지 않으면 div 요소로 표시합니다.

  3. onChange 이벤트: input 요소에는 onChange 이벤트 핸들러를 등록하여 사용자가 입력한 값을 state에 저장합니다. 이를 위해 useState 훅을 사용하여 값을 관리하면 좋습니다.

  4. 수정 완료 저장: 수정이 완료됐을 때 변경된 내용을 저장하는 함수(handleEdit)를 구현하여 입력한 내용을 저장하고 수정 모드를 종료합니다.

아래는 간단한 예시 코드입니다:

import { useState } from "react";

const TodoItem = ({ todo, onEdit }) => {
  const [isEdit, setIsEdit] = useState(false);
  const [newContent, setNewContent] = useState(todo.content);

  const handleEdit = () => {
    onEdit(todo.id, newContent);
    setIsEdit(false);
  };

  return (
    <div>
      {isEdit ? (
        <input
          type="text"
          value={newContent}
          onChange={(e) => setNewContent(e.target.value)}
        />
      ) : (
        <div>{todo.content}</div>
      )}
      <button onClick={() => setIsEdit(!isEdit)}>수정</button>
      <button onClick={handleEdit}>완료</button>
    </div>
  );
};

export default TodoItem;

이 코드에서 TodoItem 컴포넌트는 isEdit 상태에 따라 input 또는 div를 렌더링합니다. 수정 버튼을 클릭하면 isEdit 상태가 변경되고, 완료 버튼을 누르면 변경된 내용을 부모 컴포넌트로 전달하는 방식입니다.

비슷한 내용을 다룬 기존 질문이 아래 링크에 있습니다:
- DiaryItem에서 수정 기능 구현 질문

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

HK님의 프로필 이미지
HK

작성한 질문수

질문하기