[Next js] 갤러리 구현1 - 이미지 업로드

임보라·2024년 10월 29일

Next.js

목록 보기
16/23
post-thumbnail

supabase에서 앨범 전체 불러오기

// fatchAlbumList.ts
export const fetchAlbum = async () => {
  const { data, error } = await browserClient.from('album').select('*');

  if (error) {
    console.error('가져오기 오류4:', error.message);
  }
  console.log('data', data);
  return data;
};

앨범목록 useQuery로 data담기

//AlbumList.tsx
import { fetchAlbum } from '@/apis/fetchAlbumList';

const {
    data: albumListData,
    isLoading,
    isError
  } = useQuery({
    queryKey: ['photo'],
    queryFn: fetchAlbum
  });

탭기능 구현 (전체보기 | 지역별)

//AlbumList.tsx
const AlbumList = () => {
  const [imgSrc, setImgSrc] = useState<string>('/images/default-image.png'); //이미지url
  const [activeTab, setActiveTab] = useState('allTab'); //탭상태

  //탭엑션
  const onClickTab = (tab: string) => {
    setActiveTab(tab);
  };

  //유저가 등록한 지역이름들(중복_지역이름제거)
  const filterRigionTitle = albumListData ? [...new Set(albumListData?.map((item) => item.region))] : [];
  //유저가 등록한 지역의 포토들
  const filterRigionPhoto = filterRigionTitle.map(
    (title) => albumListData?.filter((item) => item.region === title) || []
  );

  return (
    <div>
      {/* 전체보기-지역별 탭버튼 */}
      <ul>
        <li
          className={`albumTab ${activeTab === 'allTab' ? 'active' : ''}`}
          onClick={() => onClickTab('allTab')}
        >전체보기</li>
        <li
          className={`albumTab ${activeTab === 'rigionTab' ? 'active' : ''}`}
          onClick={() => onClickTab('rigionTab')}
        >지역별</li>
      </ul>
      {/* 전체보기 */}
      {activeTab === 'allTab' && (
        <ul>
          <AddPhotoBtn setImgSrc={setImgSrc} AlbumAddMutation={AlbumAddMutation} />
         ...
        </ul>
      )}
      {/* 지역별 */}
      {activeTab === 'rigionTab' && (
        <section>
          <div>
          ...
          </div>
        </section>
      )}
    </div>
  );
};

파일 1개 업로드

파일에서 이미지 가져오기

  • accept="image/*" : 파일 중에서 이미지 파일만 입력
const [imgSrc, setImgSrc] = useState(''); 
//AddPhotoBtn.tsx
return (
    <li>
      <input id="fileInput" className="hidden" type="file" accept="image/*" onChange={OnChangePhoto} />
      <label htmlFor="fileInput" >+</label>
    </li>
  );

업로드 이벤트

1.이미지선택 후
2.모달열기

//CategoryModal.tsx
  const OnChangePhoto = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];//클릭한대상의 이미지를 저장
    if (!file) return;
    const fileReader = new FileReader();//파일읽기용 객체
    fileReader.readAsDataURL(file);//파일읽기용에 file값 저장
    fileReader.onload = (e) => {
      if (typeof e.target?.result === 'string') {
        setImgSrc(e.target.result);//상태저장
        SetIsRigionModal(true);//모달열기
      }
    };
  };

모달에서 카테고리 선택후 업로드 버튼 클릭시

3.모달에서 카테고리 선택 후 버튼클릭시 데이터 추가하기

//AddPhotoBtn.tsx
const onHandleUpload = () => {
    if (imgSrc.length > 0) {
      AlbumAddMutation.mutate({ imgSrc, regionCate }); //데이터추가뮤테이션 호출
      alert('앨범이 추가되었습니다.');
      SetIsRigionModal(false); // 모달 닫기
    }
  };

레퍼런스
이미지 입력받기
이미지 트러블슈팅1
이미지 트러블슈팅2

0개의 댓글