-
Notifications
You must be signed in to change notification settings - Fork 1
먼저 할 일과 이어서 할 일을 자동완성으로 추가해보자 😌
우리 Todo 어플리케이션은 Todo간의 선후관계를 지정해 줄 수 있다.
- 사용자에게 직접 todo의 uuid를 보여주고, 복사하게 만들어 텍스트형태로 입력하게 만들었다.
- 여러 uuid를 집어넣을 땐 ,를 통해 구분하게 했었다.
- uuid를 사용해 선후관계를 추가한다는 개념 자체가 납득이 잘 안된다.
- uuid를 복사했을 때 어떤 Todo였는지 기억이 안난다.
- uuid를 직접 복사해 붙여넣는 행위가 귀찮다
- id를 사용자에게 노출하는 점이 굉장히 불쾌하다
-
,
로 구분하기 때문에 입력을 받았을 때 유효성검증 과정이 이유없이 길고 복잡하다.
이러한 문제들을 해결하기 위해서 Todo들의 제목을 입력하여 검색하고, 검색한 Todo를 추가하는 방식을 생각하게 되었다.
검색 API를 만들고, SearchBar 컴포넌트를 만들었다. 이에 마우스 이벤트와 키보드 이벤트를 적용시켜 현재 있는 Todo들의 제목을 검색하여 먼저 할 일과 나중에 할 일에 추가 할 수 있도록 하였다. 검색한 Todo 중 하나를 click하거나 enter했을 때 SearchBar를 이용하는 컴포넌트에서 내려준 props Fuction에 선택한 todo의 정보를 보내주는 식으로 구현하였다.
검색된 Todo가 5개가 넘어가면 더이상 검색리스트의 높이가 커지지않고 스크롤로 전환된다. 그때 keyboard 이벤트로 Todo를 선택할 때 현재 포커싱된 Todo에 스크롤이 가게하고 싶었다. 이때 스크롤 위치를 변환하기 위해서 두가지 DOM 조작이 생각났다.
-
getElementById
를 이용해 현재 포커싱한 Todo에 스크롤 이동 -
useRef
를 이용해 현재 포커싱한 Todo에 스크롤 이동 두가지 중에서 id를 사용하지 않는(리액트는 중복된 id를 사용할 수 있기 때문에 id를 사용하지 않는 편이 좋다.)useRef
를 사용해 구현하기로 결정하였다. 사실 React를 사용할 때는 ref도 지양하는 편이 좋지만, 스크롤을 제어하기 위해선 어쩔 수 없이 사용해야했었다.
일단 구현을 하기로 마음은 먹었는데,.. useRef의 경우에는 element 하나하나에 useRef를 달아서 구현했었기에 개수가 변화하는 리스트 엘리먼트에 어떻게 적용할지 고민했었다.
const Search = (): ReactElement => {
const liRef = useRef<LiRefList>({});
...
return (
...
{searchTodoList.map((todo) => {
return (
<li key={todo.id}
ref={(el) => {
if (el !== null) {
liRef.current[todo.id] = el;
}
}}>
</li>
);
})}
...)
}
여러 고민을 한 결과, Callback ref를 이용해 ref Object를 인자로 받아 저장해주고, 리스트가 포커싱 되었을 경우 해당 ref object의 scrollIntoView 메서드를 호출해 해당 엘리먼트가 보이도록 ul태그를 스크롤하게 하였다. 나는 id의 값으로 ref를 찾고싶어서 object로 관리해주었지만 array로 관리해도 무방하다.
첫 구현을 마치고 코드리뷰를 했을 때 가독성이 떨어진다는 피드백을 받았다. UI와 비지니스 로직이 섞여 알아보기 힘들었던 것이다. 그렇기 때문에 기존에는 SearchBar라는 컴포넌트에 UI와 로직을 통째로 넣어놓았었는데 이를 Search라는 컴포넌트의 SearchBar(검색창), SearchListContent(검색결과 리스트 내용) 컴포넌트로 분리하여 UI와 로직을 분리해주었다.
- Search에서 검색API를 호출하고 SearchListContent에는 props로 전달하여 Search에서만 비지니스 로직을 관리하게 한다.
- Click, Keyboard 등 이벤트가 발생하였을 때의 로직을 Search에서 관리하여 SearchBar와 SearchListContent는 UI 기능만 수행하도록 수정한다.
- Search에서만 로직들을 관리하게 되어서 편했다.
- SearchBar와 SearchListContent는 UI 기능만 수행하기 때문에 UI 수정이 필요할 때 빠르게 해당 부분을 찾아 수정할 수 있었다.
- todo의 제목으로 검색하기 때문에 편리하게 선후관계를 추가할 수 있었다.
- 선후관계를 추가할 때 어떻게 해야하는지 이해하기 쉬웠다.
- 못생긴 id를 보지않게되어 기쁘다.
- 입력 받은 todo들에 대한 유효성 검증 부분이 줄어들었다.
- id를 사용자에게 노출하지않아 편-안해졌다.
- OaO 환경설정 A to Z
- CRLF 너가 뭔데 날 힘들게 해?
- Github Issue 똑똑하게 사용하기
- OAO! CI CD 적용기 with release 자동화
- 매번 다른 import문
- 못생긴 상대경로에서 간zlzl존 절대경로로😎
- TodoList API 개발기
- 의존성 주입으로 DB를 바꿔보자
- 렌더링 최적화 서막: useNavigate를 추가한 순간 리렌더 범위가 확장된 건에 대하여
- 렌더링 최적화 1탄: 렌더링 범위에 대하여 (by 최적화무새)
- 렌더링 최적화 2탄: 잘못된 custom hook 사용,, 전체 리렌더링을 부르다,,
- 렌더링 최적화 3탄: Todo 상세 좀 봤다고 테이블 전체가 재렌더링 되는건을 고치기😌
- 렌더링 최적화 4탄: 다이어그램 편
- 🐁 마우스 상대위치 계산은 이상해
- React 컴포넌트에 애니메이션을 적용해보자 🏃🏻💨
- 컴포넌트 재사용성을 높여보자: Modal 분리기 🌹
- 선후관계를 자동완성으로 추가해보자 🔎