어제에 이어서 Custom Component를 만드는 실습을 진행하였다.
5. AutoComplete
input박스에 단어를 입력할 때 자동완성기능이 DropDown으로 나오도록 구현하였다.
AutoComplete 컴포넌트에는 세가지 상태가 있다.
hasText 상태는 input창에 단어가 있는지를 나타낸다.
inputValue 상태는 현재 input창에 적혀있는 단어 상태를 나타낸다.
options 상태는 단어에 따라 자동완성 리스트를 보여주는 배열을 나타낸다. 기본값은 임의로 만들어둔 배열을 넣는다.
input box 구현
input 요소에 입력값에 따라 inputValue상태와 연동이 되도록 value값에 inputValue를 지정하고 onChange이벤트에 이벤트 핸들러 handleInputChange를 등록했다. handleInputChange함수는 inputValue의 상태를 변경해주는 함수이다.
input창 오른쪽 끝의 x 버튼을 누르면 inputValue가 빈문자열이 되면서 없어지도록 onClick 이벤트에 이벤트핸들러 handleDeleteButtonClick을 등록했다.
inputValue가 빈문자열이되면 자동으로 hasText가 false가 되도록 useEffect 함수를 사용할 수 있다.
options 상태 구현
options 상태에는 배열이 들어가는데, input창에 있는 각 글자와 일치하는 단어를 deSelectedOptions라는 배열에서 찾아서 새로운 배열을 만든 후 setOptions 함수로 option을 필터링된 배열로 변경해주면 된다.
위에서 구현한 handleInputChange함수에 추가로 코드를 작성하여 input창에서 글자가 입력될 때 마다 필터링을 하여 options의 상태를 변경해준다.
DropDown 구현
먼저 hasText 상태에 따라 DropDown이 나타났다 없어졌다 하도록 구현한다.
hasText 가 false이면 DropDown이 나타나지 않고, true이면 나타나도록 조건부 렌더링을 한다.
DropDown 컴포넌트는 options 배열과 handleDropDownClick 함수를 props로 전달받아서 map함수를 사용하여 렌더링 한다.
handleDropDownClick함수는 dropdown에 나오는 단어를 클릭했을 때 input창에 있는 단어를 클릭한 단어로 변경해주는 함수이다.
여기까지 완성본
Advanced
DropDown에서 방향키를 사용하여 이동할 수 있게 하고, 방향키로 이동 후 엔터를 누르면 input창에 해당 단어가 입력이되도록 하는 기능을 만들어보았다.
처음에는 li 태그를 focus 해야하는줄 알고 useRef를 사용하려고 각각의 li태그에 useRef를 지정해주다가 잘 안됬다.
그러고나서 생각해보니 실제로 focus를 하는것이 아니고 focus가 된 것 처럼 style을 지정해주면 되겠다는 생각이 들어 방향키를 입력하면 해당 li 태그에 클래스를 추가하여 다른 style을 지정하도록 해주었다.
일단 focus된 상태를 만들고 초기값은 0을 지정해주었다. 이 focus 상태는 현재 focus된 li 태그의 index를 나타낸다.
input 태그의 onKeyUp 이벤트로 handleFocusDrop이라는 함수를 등록하고 함수를 구현한다.
위 아래 방향키를 입력하면 focusOn의 상태가 바뀌도록 조건문을 추가한다.
마지막 요소에서 아래 방향키를 입력하면 더 내려가면 안되기 때문에 focusOn 범위도 지정해준다.
다음으로 엔터키를 누르면 해당 li 태그의 단어가 input창에 추가되도록 만든다.
inputValue를 현재 focus된 li태그의 단어로 바꾸어주고 해당 단어에 맞게 DropDown이 생성이 되도록 options 배열도 필터링하여 바꿔준다. 그리고 focusOn은 0으로 되돌린다.
focus된 li태그에 class를 추가해줘야 하기 때문에 DropDown 컴포넌트에 focusOn 상태를 props로 내려주고 조건부 렌더링을 해준다.
focus된 li태그는 focused 라는 style을 추가로 받아서 focus된 것 처럼 보이게 된다.
별거 없어 보이는 자동완성 기능에 엄청 긴 코드가 들어간다는 것을 깨달았다....
6. ClickToEdit
엄청난놈(?)을 끝내고 와서 그런지 쉽게 느껴졌다..
기본적으로는 입력이 불가능 하지만 단어를 클릭하면 입력이 가능하게 바뀌도록하고, 입력을 다 한 후 다른곳을 클릭하면 다시 입력이 불가능하게 바뀌고 밑에있는 본문이 입력한 내용으로 바뀌도록 하는 과제였다.
inEditMode 상태는 edit가 가능한지 여부를 나타내는 상태이고 newValue 상태는 입력한 값을 나타내는 상태이다.
input 태그를 useRef로 선택하여 inEditMode 상태가 true가 되면 focus하도록 useEffect가 설정되어있다.
isEditMode가 true일 때는 inputEdit 컴포넌트를 렌더링하고, false이면 일반적인 span 태그를 렌더링한다.
span 태그에 onClick 이벤트로 isEditMode를 true로 만들어주는 이벤트핸들러 handleClick을 등록해준다. span태그를 클릭하면 edit할 수 있게 된다.
inputEdit 컴포넌트는 value로 newValue를 지정하여 newValue 상태와 연동이 되도록 하고 onChange 이벤트로 handleInputChange 이벤트핸들러를 등록하여 입력한 값이 실시간으로 newValue에 담도록 했다.
onBlur 이벤트는 focus를 잃을때 발생하는 이벤트인데 input창에 입력 후 다른곳을 클릭하면 발동된다.
이벤트핸들러로 handleBlur를 등록한다. 이 함수는 handleValueChange 함수를 실행하고 editMode를 false로 바꾼다.
handleValueChange함수는 상위 컴포넌트에 있는 함수로 인자로 받은 값을 본문에 표시하기위해 사용하는 함수이다.
뭔가 되게 복잡한거 같은데 정리를하면
span 태그를 클릭하면 edit를 할수 있게 input창이 렌더링된다.
input창에 단어를 입력하면 실시간으로 newValue 상태가 바뀐다.
화면의 다른 부분을 클릭하면 input창이 없어지고 다시 span태그에 입력한 단어가 입력된 채로 렌더링된다.
그리고 밑에있는 본문이 입력한 내용으로 바뀌게 된다.
'코드스테이츠' 카테고리의 다른 글
2/24 일일정리 Redux (0) | 2023.02.24 |
---|---|
2/23 일일정리 상태관리 실습 (0) | 2023.02.23 |
2/21 일일정리 Custom Component 실습 (0) | 2023.02.21 |
2/20 일일정리 Custom Component (0) | 2023.02.20 |
2/17 일일정리 Figma 실습 (0) | 2023.02.17 |
댓글