2022.11.2 TIL

김석재·2022년 11월 1일
1

오늘은 드디어 이미지를 전송하는데 성공했다. 여태까지 실패한 이유로

- 전제조건 : 이미지 파일과 string형태의 데이터를 동시에 formData에 담아서 보내는 것을 목표로 했을 때

  1. FE와 BE의 데이터 타입이 일치하지 않았다.
  2. key값이 중복되는 데이터가 많아서 폼데이터로 전송하더라도 담긴 값을 찾아내기가 쉽지 않다.
  3. FE에서 전달하려는 형태와 BE에서 받으려는 형태가 명확하게 약속되지 않았다.

이런 피드백들을 토대로 formData 부분을 아예 갈아엎고 동작하는 부분을 새로 작성하기로 했다.

  1. img를 먼저 formData로 담아 서버에 보낸다.
  2. 서버에서 S3를 통해 이미지에 대한 id, url, name 등의 정보를 FE에 반환한다.
  3. strore에 저장된 해당 이미지 정보들을 useSelector로 가져와서 이미지 미리보기 컴포넌트를 만들어 보여준다.
  4. 나머지 string형태의 값들이 입력되고 onSubmit이 발동되었을 때 img의 id값도 같이 string 형태로 서버에 보낸다.
//이미지를 폼데이터에 담아 dispatch

const mediaChangeHandler = (e) => {
    const file = new FormData();
    file.append("file", e.target.files[0]);
    dispatch(__imgPost(file));
  };
//미들웨어 Thunk를 사용해 서버에 Axios로 통신. headers에 content-type을 지정

export const __imgPost = createAsyncThunk(
  "IMG_POST",
  async (payload, thunkAPI) => {
    console.log(payload);
    try {
      const imgPost = await axios({
        method: "post",
        url: 서버 url주소,
        data: payload,
        headers: {
          "Content-Type": "multipart/form-data",
        },
      });
      return thunkAPI.fulfillWithValue(imgPost.data);
    } catch (error) {
      console.log("글 작성 post요청 에러");
    }
  }
);
// sliceReducer의 extraReducers 부분. 
// imgPost가 fulfilled 되었을때 값을 store에 저장

extraReducers: {
    [__imgPost.fulfilled]: (state, action) => {
      console.log(action.payload);
      state.list = [state.list, action.payload.data];
    },
// 저장한 값을 useSelector로 사용할 수 있게 만들어줌

const imgGet = useSelector((state) => state.postReducer.list[1]);
// 삼항연산자를 사용해 imgGet이 undefined가 아닐때 미리보기를 시켜줌

{imgGet !== undefined
                  ? imgGet.mediaUrl && (
                      <img
                        className="prevImage"
                        src={imgGet.mediaUrl}
                        alt="preview-img"
                      />
                    )
                  : null}
//sellSubmitHandler가 발동되었을 때 imgGet_id와 나머지 데이터를 string 형태로 dispatch로 서버에 보냄

  const sellSubmitHandler = (e) => {
    e.preventDefault();
    dispatch(
      __writePost({
        img_id: imgGet.id,
        title,
        category,
        local,
        state,
        trade,
        price,
        content,
        tag,
        amount,
      })
    );
  };

이러한 방식으로 이미지를 포함한 게시글 작성에 성공했다. 저번주차부터 실패했던 이미지 업로드를 성공해서 너무 뿌듯했고 우리팀에서 가장 먼저, 유일하게 성공한 조라는 점이 더욱 뿌듯하게 만들었다.

** 앞으로 남은 일
-이미지 상세보기 페이지 UI 제작
-메인페이지, 상세보기 페이지에서 Get요청으로 작성한 포스트의 값을 읽어오기
-상세보기 페이지에서 Update, Delete작업하기
크게보면 프론트 단에서는 이 세가지가 남았고 꾸준히 작업하고 있는 것은 서버와의 연결을 지속적으로 시도해나가면서 진행중이다. 저번주차처럼 촉박하게 연결했다가는 배포에 실패하기 때문에 미리미리 서버와 연결해서 배포에 바로 성공할 수 있도록 해야겠다.

0개의 댓글