시작하며...
Next.js 에서 React Quill 에디터 라이브러리를 사용하여 이미지를 모달로 받고 업로드하는 것을 구현하였는데 이에 대해 자세히 글을 작성해보려고 한다.
이미지 핸들러
1. 이미지 핸들러 등록
에디터에 있는 이미지 아이콘을 클릭하여 이미지를 업로드하는 대신, 직접 이미지 업로드 과정을 구현하기 위해서는 이미지 핸들러를 추가해야 한다.
Quill 에디터에 있는 이미지를 클릭하였을 때 사용자 정의 동작을 할 수 있도록 image 를 클릭했을 때 handleClickImage
함수가 호출되도록 핸들러로 지정해 준다.
2. 이미지 등록 모달 열기
이미지 핸들러인handleClickImage
에 모달을 open 하는 함수를 넣는다.
이미지 모달 구현
이미지를 입력받음 → 유효성 검사 → 이미지 미리 보기 기능 구현 → 삽입하기 버튼을 눌러 백엔드에 이미지를 보내 URL 받음
1. 이미지 입력받기
input 태그에서 type 을 file 로 설정하여 이미지를 받을 수 있다. 그러나 디자인이 안 예쁘다! 그래서 input 태그를 화면에 숨기고 직접 커스텀한 이미지 인풋을 화면에 보여줘야 한다.
그래서 input 태그는 숨기고, label 을 사용하여 input 요소와 연결을 하여, label 클릭 시 input 요소가 활성화되도록 하였다.
2. 유효성 검사
해당 프로젝트에서 사용 중인 백엔드에서는 파일명이 한글로 되면 에러가 발생하여, 프론트 측에서 미리 파일명 형식이 맞지 않을 경우 토스트창을 띄워 경고 메시지를 줄 것이다. 그 밖에도 무조건 이미지여야 하기 때문에 확장자명을 확인하고, 파일 크기도 5MB 이하인 것만 받을 수 있도록 유효성 검사를 해야 한다.
상수 만들기
유효성 검사에 필요한 상수들을 만들어 줬다.
삽입할 이미지 유효성 검사
위에서 만든 상수를 사용하여 이미지를 입력받았을 때 유효성 검사를 수행하였다.
유효성 검사를 통해 유효하지 않으면 에러 메시지를 설정하여 토스트창을 통해 에러 메시지를 보여주고, 이미지와 이미지 미리 보기를 초기화하였다.
반면 유효하면 image 에 입력받은 이미지 파일을 설정하였다. 그리고 마지막에 e.target.value = '';
를 하였는데 파일 입력 값을 초기화하여 같은 파일을 다시 받을 수 있도록 하였다.
3. 이미지 미리 보기 기능 구현
위에서 이미지가 유효하면 image 에 입력받은 이미지 파일을 설정하였다.
클린업 함수를 사용하여 입력받은 이미지 파일의 미리 보기 URL 을 만들었다.
4. 백엔드에 파일 보내 URL 얻기
삽입하기 버튼을 클릭하여 handleInsertImage
함수를 호출한다.
try-catch 문을 사용하여 이미지가 있을 경우 이미지를 객체로 생성하고 getImageUrl
함수를 호출하여 백엔드에 이미지를 업로드한다. 그러면 업로드된 이미지의 URL 을 포함한 응답을 handleImageUrl
함수를 호출하여 받은 이미지 URL 을 처리한다.
만약 오류가 발생할 경우 토스트창으로 오류 메시지를 보여주고 모든 동작을 마친 후에 이미지와 이미지 미리 보기 URL 을 초기화하였다.
참고로 getImageUrl
함수는 다음과 같이 생겼다.
이미지 에디터 삽입
"4. 백엔드에 파일 보내 URL 얻기"에서 응답으로 받은 이미지 URL 을 handleImageUrl
함수를 호출하여 처리하였는데, 에디터가 있는 컴포넌트에서 handleImageUrl
함수에서 받은 url 로 handleInsertImage
함수를 호출하였다.
handleInsertImage 함수
- Quill 에디터 컴포넌트를 useRef 훅을 사용하여 참조한 QuillRef 를 사용하여 실제 DOM 요소에 접근하여
getEditor
메서드로 Quill 에디터 인스턴스를 가져옴 - 이미지를 삽입하기 위해 에디터에 focus
- 삽입할 위치를 지정하기 위해
getSelection
메서드를 사용해 현재 커서 위치를 가져옴 insertEmbed
메서드로 현재 커서 위치에 'image' 에 입력받은 url 을 삽입- 사용자 경험성을 위해 줄바꿈을 추가하고 커서를 이동
- 모달 닫음
추가적인 코드
모바일에서 이미지 모달을 열였을 때 에디터에 포커스가 되어 있어서 키보드가 나타나는 현상이 있었다.
그래서 이미지 모달을 열었을 때 Quill 에디터 인스턴스를 useRef 로 가져온 후 blur
메서드를 사용하여 포커스를 해제하였다.
'💜 프로젝트 구현' 카테고리의 다른 글
[GitHub Action / Chromatic] 스토리북 PR 미리보기 배포 (feat. yarn) (0) | 2024.08.08 |
---|---|
DropDown 컴파운드 패턴으로 공통 컴포넌트 구현하기 (0) | 2024.07.29 |
[Next.js / Zustand] 로그인 확인 및 로그아웃 구현 (0) | 2024.07.15 |
프로젝트 초기 세팅 (with 템플릿, eslint, prettier, commitLint, tailwind) (1) | 2024.07.10 |
메뉴바(드롭다운) 외부 바깥 영역 클릭 시 닫히기 (feat. useRef) (1) | 2024.07.08 |
FE 개발자가 되고 싶은 짱잼이
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!