[투두리스트/ React] 수정 기능 추가

todolistPreview-ezgif.com-crop.gif
이번에 토이프로젝트로 제작했던 투두리스트.

 

투두리스트를 추가하고 삭제, 검색 기능까지 다 만들어두고 나니 뭔가 아쉬워서 좀 더 추가해봤다. 투두를 적어두고도 맞춤법 하나가 틀렸다든가 내용을 수정해야 할 때마다 지우고 새로 만드는 것보다 UI를 추가하는게 훨씬 편리하니까! 그런데 넣다보니 하나씩 뭐가 부족하고... 뭐가 이상하고... 그래서 차근차근 하나씩 추가했고, 작업 순서대로 글을 작성해봤다. 

1. Todo 수정 기능 추가하기

  • 수정 버튼을 클릭하면 "수정 모드"로 변경
  • input 필드를 활성화 해서 내용을 수정 가능하도록 변경
  • 저장 버튼을 따로 만들지 않고, 같은 버튼을 다시 누르면 저장 & 수정 모드 종료
// react
// App.jsx -> List.jsx -> TodoItem.jsx 로 전달한다.
// 수정중이라면 true, 아니라면 false를 써서 토글 전환 되도록 함. 

// App.jsx --------------------------------------
  const onEdit = (targetId, newContent) => {
    setTodos(
      todos.map((todo) =>
        todo.id === targetId ? { ...todo, content: newContent } : todo
      )
    );
  };
  
 // return에서 List에 onEdit={onEdit}으로 전달


// TodoItem.jsx-----------------------------------
const [isEditing, setIsEditing] = useState(false);
const [editContent, setEditContent] = useState(content);

  const onChangeEditContent = (e) => {
    setEditContent(e.target.value);
  };

const onToggleEdit = () => {
  if (isEditing && editContent.trim() !== "") {
    onEdit(id, editContent); //저장기능 
  }
  setIsEditing(!isEditing);
};


//---아래는 리턴해주는 내용
{isEditing ? (
  <input
    value={editContent}
    onChange={onChangeEditContent}
  />
) : (
  <span>{content}</span>
)}

<button onClick={onToggleEdit}>
  <FontAwesomeIcon icon={isEditing ? faSave : faPen} />
</button>

 

위의 과정을 통해 버튼 하나로 수정 & 저장을 동시에 할 수 있게 되었으나, 다른 문제가 있었다.


2. 수정할 때 자동으로 input에 포커스 주기

📌 문제점

  • 수정 버튼을 눌러도 입력창에 자동으로 포커스가 가지 않음.
  • 사용자가 직접 클릭해야 입력할 수 있어 불편함.

💡  해결 방법

  • useRef를 사용해 input 태그를 참조하고, 수정 모드 진입 시 자동 포커스 적용
  • useEffect를 사용해 isEditingtrue가 될 때마다 실행
const inputRef = useRef(null);

useEffect(() => {
  if (isEditing) {
    inputRef.current.focus();
  }
}, [isEditing]);


{isEditing ? (
  <input
    ref={inputRef}
    value={editContent}
    onChange={onChangeEditContent}
  />
) : (
  <span>{content}</span>
)}

여기서 또, 편의성에 관련한 다른 문제점을 발견할 수 있었다.


2. 엔터 버튼 누르기 or 포커스 해제 시에도 자동 저장

📌 문제점

  • 입력창을 클릭한 후 다른 곳을 클릭하면 여전히 수정 중으로 남아 있음.
  • 저장 버튼을 꼭 눌러야만 수정이 완료됨.

💡  해결 방법

  • onKeyDown 을 활용해 엔터를 눌러도 자동 저장하도록 설정
  • onBlur 이벤트를 활용해 포커스를 잃으면 자동 저장하도록 설정
  • 단, 빈 값이면 원래 값으로 유지
const onKeyDown = (e) => {
  if (e.keyCode === 13) {
    onToggleEdit();
  }
};

const onBlur = () => {
  if (isEditing) {
    onToggleEdit(); // 자동 저장
  }
};

{isEditing ? (
  <input
    ref={inputRef}
    value={editContent}
    onChange={onChangeEditContent}
    onKeyDown={onKeyDown}
    onBlur={onBlur}
  />
) : (
  <span>{content}</span>
)}

📝 정리

문제 해결 방법 적용 코드
Todo 수정 기능 추가 isEditing 상태 사용, 버튼 클릭 시 수정 가능 onToggleEdit()
수정 시 자동 포커스 useRef + useEffect 활용 inputRef.current.focus()
Enter 키 입력 시 저장 onKeyDown 이벤트 추가  onKeyDown={onKeyDown}
포커스 해제 시 저장 onBlur 이벤트 추가 onBlur={onBlur}

결과적으로,

  • 수정 버튼을 누르면 자동으로 input이 활성화
  • 버튼/Enter 키/ 다른 곳 클릭 모두 수정 처리
  • UI가 깔끔해지고 사용자가 직관적으로 수정할 수 있게 개선

등의 결과를 얻을 수 있게 되었다. 역시 이런 사소한 것들 하나하나 모여서 좋은 UX를 만드는 게 아닐까?