본문 바로가기
개발/React

[react] html 카메라 갤러리 이미지 불러오기 보여주기 DB 보내기

by 코딩하는 갓디노 2022. 3. 18.

[react] html 카메라 갤러리 이미지 불러오기 보여주기

 

react에서
web API를 이용해
html 갤러리 이미지 불러오기
보여주기 기능입니다. 

 

구현영상

 

web api 이미지 불러오기 보여주기 기능 코드

이미지 파일 불러오기

<input type="file" accept="파일 확장자|audio/*|video/*|image/*|미디어 타입">
  • input type="file" 로 파일 업로드 기능 
  • input 태그의  accept 속성은 서버로 업로드 할 수 있는 파일의 타입을 명시
  • accept 속성은 input 요소의 type이 file인 경우에만 사용 가능

 

보여주기 함수

  • onChange 이벤트를 걸어 아래의 함수를 실행
const onAddThumbnail = (e) => {
        let reader = new FileReader() // FileReader API로 이미지 인식   
        reader.readAsDataURL(e.target.files[0]) //reader에게 file을 먼저 읽힘
        reader.onload = (e) => { // 사진 올리고 나서 처리하는 이벤트
            setLoadedFoodImage(e.target.result) //e.target.result는 파일을 비트맵 데이터를 리턴해줌
            //데이터를 img src 넣어 이미지 미리보기 가능
            e.target.value = '' //같은 파일을 올리면 인지못해서 초기화 안할경우 이미지 아래로 누적
        }
}

 

DB 보내기 - post 

여기서 e.target.files[0]를 콘솔로 찍어보면 아래와 같이 File 안에 객체 형식으로 data가 들어가 있습니다.

 

하지만 axios.post로 e.target.files[0]를 그대로 보냈을 경우,
network를 확인해보면 data가 없는 {} 빈 값으로 나오게 됩니다. 

내용물만 보내려고 {...e.target.files[0].File} 을 시도하니 undefinded 에러가 나왔습니다. 

 

DB 보내기 - post  코드

  • const config = { headers: { "content-type": "multipart/form-data" } } 헤더를 파일 전송 형태로 하여 매개변수 보내기
  • const formdata = new FormData() 로 새 객체를 생성 활용 - ajax에서 파일 보낼때와 동일
  • params.files.forEach((file) => formdata.append("files", file) forEach를 이용해 파일 데이터를 읽어와 객체에 {files : "xxx"}ff로 담아줌
  • 그 외의 다른 필요한 데이트 역시 formdata.apped("filename" : "xxx") 이런 형식으로 보내줌
export const sendPhoto = async () => { 
	let params = {files: [e.target.files[0]]} //배열 형식으로 보낼때
    const config = { headers: { "content-type": "multipart/form-data" } }
    const formdata = new FormData()
    params.files.forEach((file) => formdata.append("files", file))
    await api.post(`url 주소`, formdata, config)
})

 

모든 코드

import React, { useState } from 'react';

const RequestToPhoto = () => {
  const [photo, setPhoto] = useState([]) //받은 이미지 자체, 백엔드로 보내기 위함
  const [loadedFoodImage, setLoadedFoodImage] = useState(null) //미리보기 위함

    const onAddThumbnail = (e) => { //이미지 파일 올리기, 보여주기
        let reader = new FileReader() // FileReader API로 이미지 인식   
        reader.readAsDataURL(e.target.files[0]) //reader에게 file을 먼저 읽힘
        setPhoto([e.target.files[0]]) //state에 이미지 저장
        reader.onload = (e) => { // 사진 올리고 나서 처리하는 이벤트
            setLoadedFoodImage(e.target.result)
            e.target.value = '' //같은 파일을 올리면 인지못해서 초기화, 안할경우 이미지 아래로 쌓임
        }
    }
    
    const onSavePhoto = async () => { 
	let params = {files: [e.target.files[0]]} //배열 형식으로 보낼때
    const config = { headers: { "content-type": "multipart/form-data" } }
    const formdata = new FormData()
    params.files.forEach((file) => formdata.append("files", file))
    await api.post(`url 주소`, formdata, config)
})

    return (
        <>
            <input name='camera' type='file' id='camera-image' accept='image/*' 
            onChange={(e) => onAddThumbnail(e)} className='hidden' />
            <label htmlFor='camera-image'>
                <span>
                    <img src={'/images/mobile/meal/camera.svg'} alt='카메라 아이콘' />
                </span>
            </label>

            {loadedFoodImage && <div id="image_container">
                <img src={loadedFoodImage} alt='이미지' />
            </div>}
             <div onClick={onSavePhoto} />저장</div>
        </>
    );
};

export default RequestToPhoto;

 

formData()

  • FormData() 생성자(Constructor)는 새로운 FormData객체를 만듭니다.
  • formdata.append()를 이용하여 key, value 추가
  • 인코딩 타입이 "multipart/form-data"일 경우, form에서 사용하는 것과 동일하 포맷 사용해야 함

 

formData() 문법

var formData = new FormData(form)

 

https://developer.mozilla.org/ko/docs/Web/API/FormData/FormData

 

FormData() - Web API | MDN

FormData() 생성자(Constructor)는 새로운 FormData객체를 만듭니다.

developer.mozilla.org

 

 

반응형

댓글