프로필(바이오) 이미지 표시 기능
어떤 SNS든지 각 계정마다 프사가 존재하고, X역시 마찬가지입니다.
X친소표를 만든다면 프사(바이오)역시 꼭 들어가야 하기에, 이미지를 받아올 수 있는 기능이 필요합니다.
Bio 컴포넌트
// src/app/page.js
const [bio, setBio] = useState(null);
우선 Home 컴포넌트(Next.js app router 기준)에, 프사 이미지를 담을 bio state를 생성합니다.
초기값은 null로 지정합니다.
그리고 Bio 이미지를 받아오고, 미리보기 이미지를 출력할 컴포넌트를 제작합니다.
// src/components/Bio.js
import { FormText } from "@/styles/Texts";
import { useState, useRef, useEffect } from "react";
import {
AddPhotoBox,
AddPhotoInput,
WatchPhotoBox,
PhotoImage,
} from "@/styles/BioBox";
const Bio = (props) => {
const { imageUpload, onUpload, placeholder = "프로필 사진 첨부하기" } = props;
const [previewUrl, setPreviewUrl] = useState(null);
const fileRef = useRef(null);
const handleClick = () => {
fileRef?.current?.click();
};
useEffect(() => {
if (imageUpload) {
setPreviewUrl(imageUpload);
return () => URL.revokeObjectURL(imageUpload);
}
}, [imageUpload]);
return (
<AddPhotoBox onClick={handleClick}>
<AddPhotoInput ref={fileRef} type="file" onChange={onUpload} />
{!imageUpload ? (
<FormText>{placeholder}</FormText>
) : (
<WatchPhotoBox>
<PhotoImage src={previewUrl} alt="미리보기 이미지" />
</WatchPhotoBox>
)}
</AddPhotoBox>
);
};
export default Bio;
props 설정
const { imageUpload, onUpload, placeholder = "프로필 사진 첨부하기" } = props;
부모 컴포넌트로부터 3가지 props를 전달받습니다.
imageUpload : 업로드된 이미지 파일이 담긴 State입니다. 아까 생성한 bio State를 받습니다.
onUpload : '파일 업로드' 이벤트를 처리하는 함수입니다.
placeholder : 업로드된 이미지가 없을 때 표시할 텍스트로, 기본값은 "프로필 사진 첨부하기"입니다.
state와 ref 설정
const [previewUrl, setPreviewUrl] = useState(null);
const fileRef = useRef(null);
previewUrl : 미리보기에 사용할 이미지 파일 경로를 담습니다.
fileRef : <input type="file" /> 요소에 직접 접근하기 위해 useRef를 사용합니다. 이를 통해, 파일 업로드 창을 열 수 있습니다.
handleClick() : 파일 선택창 열기
const handleClick = () => {
fileRef?.current?.click();
};
사용자가 '프로필 사진 첨부하기' 컴포넌트를 누르면, fileRef가 가리키는 <input> 요소의 click() 메서드를 호출합니다. 이를 통해, 파일 선택창을 엽니다.
useEffect로 미리보기 이미지 업데이트
useEffect(() => {
if (imageUpload) {
setPreviewUrl(imageUpload);
return () => URL.revokeObjectURL(imageUpload);
}
}, [imageUpload]);
의존성 배열에 imageUpload를 지정합니다. imageUpload prop이 변경될 때마다(이미지 파일이 새로 업로드 될 때마다) 실행됩니다.
previewUrl에 imageUpload의 경로를 저장.
컴포넌트가 언마운트되거나 imageUpload가 바뀔 때, URL.revokeObjectURL을 호출해 메모리에서 URL 객체를 해제합니다. (메모리 누수 방지)
JSX 분석
return (
<AddPhotoBox onClick={handleClick}>
<AddPhotoInput ref={fileRef} type="file" onChange={onUpload} />
{!imageUpload ? (
<FormText>{placeholder}</FormText>
) : (
<WatchPhotoBox>
<PhotoImage src={previewUrl} alt="미리보기 이미지" />
</WatchPhotoBox>
)}
</AddPhotoBox>
);
AddPhotoBox : 업로드 창을 열기 위한 클릭 영역입니다. 클릭 시 handleClick() 함수를 호출해서 파일 업로드 창을 엽니다.
AddPhotoInput: <input type="file" />입니다. 파일 선택 시 부모로부터 전달받은 onUpload 함수가 호출됩니다.
Preview or Placeholder : imageUpload가 없으면 placeholder를 표시, imageUpload가 있으면 업로드된 이미지의 미리보기를 표시합니다.
AddPhotoBox, AddPhotoInput, WatchPhotoBox, PhotoImage 모두 특별한 기능이 추가된 컴포넌트가 아니라, styled-components로 스타일만 입힌 컴포넌트입니다.
스타일 컴포넌트의 코드 전문을 보고 싶으면, 접은 글을 펼치세요.
import styled from "styled-components";
const AddPhotoBox = styled.div`
display: flex;
align-items: center;
justify-content: center;
height: 250px;
width: 250px;
background-color: #d9d9d9;
border-radius: 180px;
overflow: hidden;
margin-bottom: 40px;
`;
const AddPhotoInput = styled.input`
display: none;
`;
const WatchPhotoBox = styled.div`
height: 100%;
width: 100%;
`;
const PhotoImage = styled.img`
width: 100%;
height: 100%;
object-fit: cover;
`;
작동 구조
'프로필 사진 첨부하기' 영역을 터치하면
이미지를 업로드할 수 있는 파일 선택기가 켜집니다.
이미지 파일을 선택하면,
이미지가 웹앱에 업로드되고, 미리보기 이미지가 출력됩니다.
업로드를 하면, X친소표의 프사 구역에 이미지가 적용됩니다.
'개발일지 > 트친소 생성기 사이트' 카테고리의 다른 글
[원신 X친소표 사이트 제작기] 5. 다중 체크 리스트픽 만들기 #React (1) | 2024.12.09 |
---|---|
[원신 X친소표 사이트 제작기] 4. Dropdown 리스트픽 만들기 #React (0) | 2024.12.04 |
[원신 X친소표 사이트 제작기] 3. 한 줄/여러 줄 TextInput 만들기 #React (0) | 2024.11.30 |
[원신 X친소표 사이트 제작기] 1. 제작한 이유와 반응 살펴보기 (1) | 2024.11.27 |
원신 트친소 생성기 제작 및 이용방법 (2) | 2024.10.19 |