react s3로 이미지 업로드
업데이트:
카테고리: react
/태그: bucket, image upload, s3
1. 버튼 만들기
<input type="file">
로 이미지를 업로드 할 수 있는 버튼 생성
accept='image/*'
속성으로 이미지 파일 유형만 업로드 할 수 있도록 한다.
2. useRef 사용하기
input 요소의 display:none
으로 없애고 onClick 이벤트 핸들러에서 참조하고 있는 input 요소를 호출
const SettingUserThumbnail = () => {
// 속성을 없애주고
const inputRef = useRef<HTMLInputElement | null>(null);
// 이미지를 업로드 하면 업로드한 이미지의 이름을 출력
const onUploadImage = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
if (!e.target.files) {
return;
}
console.log(e.target.files[0].name);
}, []);
// 라벨 클릭시 이미지 업로드
const onUploadImageButtonClick = useCallback(() => {
if (!inputRef.current) {
return;
}
inputRef.current.click();
}, []);
// 이미지 데이터는 formdata로 넘겨준다.
const formData = new FormData();
formData.append('image', e.target.files[0]);
axios({
baseURL: API_HOST,
url: '/images/:username/thumbnail',
method: 'POST',
data: formData,
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
}, []);
return (
<input type="file" accept="image/*" ref={inputRef} onChange={onUploadImage} />
<Button label="이미지 업로드" onClick={onUploadImageButtonClick} />
);
}
3. s3를 이용하여 이미지 업로드
-
s3 설정 및 IAM 사용자 설정
[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "GET", "PUT", "POST", "HEAD" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [ "x-amz-server-side-encryption", "x-amz-request-id", "x-amz-id-2" ], "MaxAgeSeconds": 3000 } ]
버킷 설정은 액세스를 퍼블릭으로 풀고 생성한 다음에 생성된 버킷에 CORS 설정에 해당 코드를 넣어준다.
IAM에서 사용자를 추가해 SECRET 키와 ACCESS 를
.env
파일에 넣어준다. npm install react-aws-s3
-
사진 넣어서 하기
// src/hooks/s3Config.tsx // s3config에 필요한 값을 환경변수로 설정 export const s3Config= { bucketName: process.env.REACT_APP_BUCKET_NAME as string, // dirName: 'directory-name', /* Optional */ region: process.env.REACT_APP_REGION as string, accessKeyId: process.env.REACT_APP_ACCESS as string, secretAccessKey: process.env.REACT_APP_SECRET as string, // s3Url: 'https:/your-aws-s3-bucket-url/' /* Optional */ }
import ReactS3Client from 'react-aws-s3-typescript' import { s3Config } from '../hooks/s3Config' const s3 = new ReactS3Client(s3Config); const uploadS3Files = (S3files: File[]) => { // 사진 데이터 s3에 저장하기 const arr:string[] = [] // for문을 돌려 upload 후 리턴된 경로를 info에 저장한다. if (S3files.length == 0) { return } else { for (let i=0; i < S3files.length; i++) { s3.uploadFile(S3files[i], S3files[i].name).then((data) => { // 잘들어가는 것을 확인 console.log('데이터 위치',data.location) arr.push(data.location) // BE로 보낼 데이터에 url형태로 넘긴다. setInfo((prev) => { let newInfo = {...prev}; newInfo['picture'] = arr return newInfo }); }).catch(err => console.error(err)) } return } }