🐈오늘 공부한 것
✔️React Custom Components Advanced
오늘도 어제에 이어 리액트 UI 컴포넌트 제작 실습을 했다. 구현한 내용은 자동완성 컴포넌트와 inline edit 컴포넌트. 특히 어려웠던 부분은 1. 자동완성에서 현재 hover 위치에서부터 키보드 이벤트 시작 2. inline edit 의 전체 플로우를 잘 이해하지 못함. edit 컴포넌트는 라이브세션 전까지 거의 이해를 못해서 반쯤 포기했다가 생각보다 쉬워서 허탈했다. 오늘도 어제와 마찬가지로 전체적인 구현 방법과 새롭게 알게된 내용 위주로 기록.
1. 자동완성
- 요구 조건 : 입력시 미리 지정된 자동완성 옵션을 드롭다운으로 보여주고, 클릭 혹은 키보드로 선택시 그 값을 input창에 띄워주어야 함. x 버튼 클릭시 현재 input 값과 드롭다운 옵션을 숨긴다.
- 3가지 상태를 사용했다. 인풋의 유무를 확인하는 boolean 값, 현재 inputValue 와 자동완성 옵션 목록인 options 배열
- input창에 입력된 값을 inputValue에 계속 업데이트 하면서 해당 값에 맞게 options 배열을 필터링하고, 그 필터링된 내용으로 드롭다운 li들을 생성한다. 값이 있을 경우 hasText 상태는 true, 없을 경우 false가 되도록 관리한다.
- 키보드 이벤트 : 드롭다운 메뉴를 Arrow 키로 이동하고, Enter를 눌러 input 값으로 띄워주는 부분이 어려웠다.
- 일단 onKeyUp 이벤트리스너를 어디에 달아줘야할지 모호했다. 레퍼런스 코드를 보고 전체, 어차피 index 값을 변경해서 options 에서 해당 인덱스로 찾기만 하면 되기 때문에 자동완성 전체 컴포넌트에 달아주어도 상관이 없다는 것을 깨달음. 처음에는 드롭다운 메뉴 컴포넌트에 달아서 이동을 해야하나 했는데 이벤트를 감지하는 주체가 모호해서 제대로 동작하지 않는듯 하였다.
- 두 번째는 keyUp 이벤트 핸들러에서 key에 따라 코드를 분기하는 것을 떠올리지 못했다. 일단 keyUp 이벤트로 index를 +1 혹은 -1 하여 그 인덱스로 options 에 접근한다는 생각자체를 하지 못했고, 그게 key의 값에 따라 동작이 바뀌어야 한다는 생각으로 이어지지 못한 것 같다. 접근을 어떻게 해야할지 잘 모르겠을 때는 어떤 동작을 했을 때 어떤 일이 일어나야하는지 더 명확하게 하는게 좋을 것 같다.
- 세 번째는 눌린 key 를 잘못 접근하고 있었다. event 객체를 받아온다면 event.key 혹은 event.code 로 접근해야 하는데 event.target.key 로 접근을 해서 동작을 하지 않았음. 참고로 event.key와 event.code의 차이점은 아래와 같다. 같은 키를 눌러도 code는 타입과 키보드 위치까지 표시해준다...
- 네 번째... 네이버 자동완성 검색창을 보면 마우스를 올렸을 때 hover 효과가 발생하고, 해당 효과 발생 지점부터 키보드를 움직이면 거기서부터 시작하는 것을 알 수 있음. 그 것을 구현하기 위해 고민을 했는데, 처음에는 useRef 로 접근을 했다가 현재 위치를 파악하기 모호한 것 같아 mouseOver 이벤트 리스너를 달아 idx 값을 넘겨주었다.
- 해결하기 위해서 여러가지 상태를 props로 전달해 주었는데, 조금만 많아져도 금방 꼬이고 정리가 안되는 것 같아 어질어질했다...
// 화살표 키 입력시 선택된 옵션으로 입력값 변경함수
const handleKeyUp = event => {
if (event.key === 'ArrowDown' && options.length - 1 > selected) {
setSelected(selected + 1);
}
if (event.key === 'ArrowUp' && selected >= 0) {
setSelected(selected - 1);
}
if (event.key === 'Enter' && selected >= 0) {
handleDropDownClick(options[selected]);
setSelected(-1);
}
};
// 이 함수를 전체 컴포넌트 keyUp 이벤트 리스너에 전달해준다.
2. inline edit 컴포넌트
- 이 컴포넌트를 뭐라고 부르는지 검색을 해보니 "inline editor" 가 가장 정확한 것 같아 이렇게 표기함.
- 요구 조건 : 고정된 값을 클릭하면 input이 등장하며 그 값을 수정할 수 있게 하고, input 바깥쪽을 클릭해 focus가 사라지면 값이 다시 고정되는 컴포넌트이다.
- 이 인라인 에디터의 전체 흐름을 쉽게 이해하지 못했다. 과제에는 코드가 이미 약간 구현되어 있는 상태였는데, props 전달 부분이 설명을 들어도 살짝 이해하기 어려워서 다시 그림을 그려봤다.
- 일단 전체 구조가 ClickToEdit 이라는 큰 컴포넌트 안에 내용을 수정할 수 있는 MyInput 이라는 input 컴포넌트 두개가 있다.
- MyInput 안에는 수정 가능한 InputEdit ~ input 컴포넌트와 고정된 값이 표시되는 span 태그가 있는데, 이 두 엘리먼트를 조건부로 렌더링 한다. 수정 가능한 여부를 체크하는 state를 만들어서 추적한 뒤에, 각각 경우에 맞게 onClick과 onBlur 이벤트를 달아서 state를 업데이트 시켜줄 수 있다.
- MyInput은 handleValueChange라는 고정될 value 값을 업데이트 하는 함수와, inputValue를 관리하는 newValue라는 상태가 있다. input에서 onChange로 newValue를 현재 입력값(e.target.value)로 업데이트 하면, onBlur 이벤트가 발생했을 때 handleValueChange(newValue)를 실행시킴으로써 MyInput의 상위컴포넌트 즉 ClickToEdit 컴포넌트의 상태를 변경할 수 있게 된다. 이렇게 해서 고정된 값을 만들 수 있다.
🐈더 공부할 것
1. 리액트 훅 : useReducer, useMemo 개념
2. TodoList : styled-components 로 리팩토링
🐈오늘의 느낀 점
1. 페어가 없으니 좀 더 어려운 과제를 할 때 확실히 늘어지게 된다. 이해가 안되는 부분을 질문하고 싶어도 어떻게 질문을 해야할지 잘 정리가 안되고, 결국 라이브 세션 시간에 해설을 보고 상당부분 이해하게 되었는데 시간을 허비한 것 같아 좀 아쉬웠다 ㅜ.ㅜ 그래도 프론트엔드다운 과제라고 생각해 풀이 과정과 새롭게 알게된 내용을 최대한 자세하게 복기해 보았다. 정보성 글은 아니라 가독성이 좋지는 않은데 다음부턴 개선해야겠다.
'TIL' 카테고리의 다른 글
[Day 51] 2022-0901 : 리액트 상태관리, Redux (0) | 2022.09.01 |
---|---|
[Day 50] 2022-0831 : Props drilling 체험(?), 미디어쿼리, 알고리즘 (0) | 2022.08.31 |
[Day 48] 2022-0829 : Custom Components, useEffect 복습, Git 협업 Flow (0) | 2022.08.29 |
[Day 46] 2022-0826 : CDD, CSS IN JS, SASS (0) | 2022.08.27 |
[Day 45] 2022-0825 : UI / UX 분석 (0) | 2022.08.25 |