• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 Next.js 게시판 s3 업로드시 useState에 담긴 파일을 사용하면 400에러가 옵니다

s3 업로드시 useState에 담긴 파일을 사용하면 400에러가 옵니다

5 글 보임 - 1 에서 5 까지 (총 5 중에서)
  • 글쓴이
  • #112675

    채명수
    참가자
    등록하기 버튼을 눌렀을때 s3에 이미지를 저장하는 코드를 만들고있는데 강의와 같이 e.target.files[0]를 담은 변수를 바로 사용할 수 있는 경우에는 이상없이 업로드가 잘 됩니다.
    
    그런데 똑같은 코드를 등록하기 버튼이 눌렀을때 실행 되야하는 함수에 넣고 useState에 담겨진 똑같은 파일을 사용하면 에러코드 400이 옵니다.
    
    handleImageUpload()
    ```
    const [updateFile, setUpdateFile] = useState<File | null>(); 
    const [updateFileName, setUpdateFileName] = useState("");
    </pre>
    <pre>const handleImageUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files !== null) {
    const file = e.target.files[0];
    setUpdateFileName(file.name);
    setUpdateFile(file);</pre>
    <pre>const fileName = encodeURIComponent(file.name);
    const res = await fetch(`/api/post/image?file=${fileName}`)
    .then((res) => {
    return res.json();
    })
    .then((res) => {
    console.log(res);
    return res;
    });</pre>
    <pre>// const presignedUrl = await getS3PresignedURL(file.name);</pre>
    <pre>//S3 업로드
    const formData = new FormData();
    Object.entries({ ...res.fields, file }).forEach(([key, value]) => {
    formData.append(key, String(value));
    });
    let 업로드결과 = await fetch(res.url, {
    method: "POST",
    body: formData,
    });
    console.log(업로드결과);</pre>
    <pre>```
    getS3PresignedURL() 함수의 인자도 마찬가지로 file.name을 넣고 업로드를하면 잘 되는데 updateFileName를 넣으면 업로드가 되지 않습니다.
    
    postApi()
    ```
    </pre>
    <pre>const postApi = async () => {
    try {
    if (updateFile) {
    </pre>
    <pre>const fileName = encodeURIComponent(updateFileName);
    const res = await fetch(`/api/post/image?file=${fileName}`)
    .then((res) => {
    return res.json();
    })
    .then((res) => {
    console.log(res);
    return res;
    });</pre>
    <pre>//S3 업로드
    const formData = new FormData();
    Object.entries({ ...res.fields, updateFile }).forEach(([key, value]) => {
    formData.append(key, String(value));
    });
    let 업로드결과 = await fetch(res.url, {
    method: "POST",
    body: formData,
    });
    console.log(업로드결과);
    ```
    조건문으로 updateFile이 있을때 실행되게 했습니다.
    그리고 getS3PresignedURL()에 updateFileName을 넣어도 file.name으로 직접 넣어줘도 Presigned URL은 잘 오는것으로 확인했습니다.
    
    도와주십시요 센세 ㅠㅠ
    #112692

    codingapple
    키 마스터
    원래 state변경함수는 가장 늦게 처리되고 그거 밑에 있는 코드들이 먼저 실행되어서 그럴 뿐입니다
    #112707

    채명수
    참가자
    선생님 그러면 파일을 어떻게 저장해줘야 할까요?? 파일 흐름이 미리보기 이미지를 눌러야지만 state에 저장이 되고 또 등록하기 버튼을 눌렀을때 조건문도 추가해서 걸러줬다고 생각하거든요 ㅠㅠ 
    
    힌트좀 주시면 정말 감사하겠습니다!
    #112727

    codingapple
    키 마스터
    업로드할 땐 state쓰지말고 e.target.files[0] 그대로 업로드하면 됩니다
    #112740

    채명수
    참가자
    선생님 해결 됬습니다!! 
    ```
    const handlePost = () => {
    if (updateFile) {
    postApi(updateFile);
    }
    };
    ```
    위와 같이 handlePost()를 만들어서 updateFile을 확인하는 로직을 옮겼는데 해결 됬습니다. 
    찾아보니까 제가 최초에 postApi가 실행되었을때 조건문으로 state에 저장한 updateFile의 유무를 판별했는데 이와같은 상황은 선생님 말씀처럼 업데이트가 늦어져서 최신 state를 받아올 수 없다고 하네요.
    그래서 handlePost() 만들어 조건문으로 확인을 하게되면 최신의 상태를 업데이트 받아서 postApi의 인자로 넣어주기 때문에 되는것 같습니다. 갑사합니다!!
5 글 보임 - 1 에서 5 까지 (총 5 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠