
투두리스트를 추가하고 삭제, 검색 기능까지 다 만들어두고 나니 뭔가 아쉬워서 좀 더 추가해봤다. 투두를 적어두고도 맞춤법 하나가 틀렸다든가 내용을 수정해야 할 때마다 지우고 새로 만드는 것보다 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를 사용해 isEditing이 true가 될 때마다 실행
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를 만드는 게 아닐까?