[Team Project] 2차 프로젝트(KIWI MARKET) - 2

하태현·2021년 1월 10일
0

Project

목록 보기
4/5
post-thumbnail
const PostItem = ({ navigation, route }) => {
  {...}
  // 판매글 업로드 시 필요한 이미지 state
  const [image, setImage] = useState([]);

  // 판매글 업로드 시 필요한 body에 담길 내용
  const [body, setBody] = useState({
    order_status: "판매중",
    category: "",
    title: "",
    price: "",
    description: "",
    access_range: 1,
  });

  const updateImage = (image) => {
    setImage(image);
  };

  // 기능 별로 나눈 Component에 setBody를 넘겨주기 위한 함수
  const updateData = (data) => {
    setBody({ ...body, [data.type]: data.value });
  };

  // 이미지 전송을 위해 FormData 작성 함수
  const createFormData = (images, body) => {
    const data = new FormData();

    images.forEach((el) => {
      data.append("product_image", {
        uri: el.uri.replace("file://", ""),
        type: `${el.type}/${el.uri.split(".").pop()}`,
      });
    });

    Object.keys(body).forEach((key) => data.append(key, body[key]));

    return data;
  };
   
  {...}
  
};

export default PostItem;

form-data ?

PostItem은 판매글을 업로드 하는 페이지이다.

여기서 어려웠던 것은 이미지 파일(URL이 아님..)을 백엔드로 보내는 것 이었는데,

그 동안은 이미지를 주고 받을 때, url을 주고 받으며 통신 했지만 이번엔 실제 이미지

파일을 전송해야 해서 FormData라는 새로운 타입을 공부해야 했다.

Request를 어떤식으로 작성해서 보내줘야 하는지 몰라서 초반에 고민을 많이 했었다.

수 많은 검색을 통해 form-data를 작성하는 방법은 알게 되었지만,

결국 멘토님의 리뷰를 통해 가장 좋은 형태를 띈 form-data가 완성되었다!!

createFormData() 를 통해 생성된 data를 출력해보니

아래와 같은 형태(터미널에선 좀더 지저분한 형태로 보여서 보기 좋게 수정...)로 출력.

{
  "_parts": [
    [
      "product_image",
      {
        "type": "image/png",
        "name": "파일명.png",
        "uri": "파일URI.png"
      }
    ],
    [
      "product_image",
      {
        "type": "image/jpg",
        "name": "파일명.png",
        "uri": "파일URI.jpg"
      }
    ],
    ["order_status", "판매중"],
    ["category", "게임/취미"],
    ["title", "지갑 팝니다."],
    ["price", "99999999"],
    ["description", "사고 3번정도 밖에 들고 다니지 않았던 최상품 입니다."],
    ["access_range", 1]
  ]
}

form-data 만들기

  const createFormData = (images, body, category) => {
    const data = new FormData();

    images.forEach((el) => {
      data.append("image", {
        type: `${el.type}/${el.uri.split(".").pop()}`,
        name: el.uri.split("/").pop(),
        uri: el.uri.replace("file://", ""),
      });
    });
    Object.keys(body).forEach((key) => data.append(key, body[key]));
    data.append("product_category", category);

    return data;
  };

fom-data를 백엔드에서 받을수 있게 하려면?

백엔드에서 이미지를 받으려면 file, image 두가지 형태로 보낼수 있는것 같다.

data.append("image",{}) 꼭 이렇게 해야만 백엔드에서 읽을 수 있는건지 모르겠는데. (이 부분은 좀더 공부를 해봐야 할것 같다.)

그래서 아래와 같이 form-data를 작성한다. (type, name, uri 3가지를 보내줘야 한다.)

꼭 3가지를 다 보내야 하는지는 모르겠는데, 일단 이번 프로젝트에서는 3가지 모두 보내줘야지 백엔드에서 읽을수 있었다.

 data.append("image", {
        type: `${el.type}/${el.uri.split(".").pop()}`,
        name: el.uri.split("/").pop(),
        uri: el.uri.replace("file://", ""),
      });
fetch(`${ITEM_LIST_API}?address_id=${addressId}`, {
        method: "POST",
        headers: {
          Accept: "application/json",
          "Content-Type": "multipart/form-data;",
          Authorization: AsyncStorage.getItem("token"),
        },
        body: createFormData(image, body, postCategory),
      })
        .then((response) => response.json())
        .then((result) => {
          if (result.message === "SUCCESS") dispatch(initCategory());
          else Alert.alert("알림", "글쓰기 실패", [{ text: "닫기" }]);
        });

이미지 타입

expo-image-picker 라이브러리를 이용하면

앨범에서 이미지를 가져오면 uri가 이런 이상한 모양으로 나온다.ㅋㅋㅋㅋ
그리고 type은 image 밖에 안온다....ㅋㅋㅋㅋㅋ

"file:///var/mobile/Containers/Data/Application/738480BE-5686-477A-BAC7-F8FBD9273708/Library/Caches/ExponentExperienceData/%2540kingth_man%252FKiwiMarket/ImagePicker/2EE95964-0CFD-4A8C-9D74-1BCED984DA05.jpg"

form-data에서 사용할 형태로 파싱을 해보자!

ios에서는 "file://" 요런 녀석이 앞에 붙어서 떼어내준다.
type은 "image/jpg" 모양으로 만들어 줘야 했다.ㅋㅋㅋ

type: `${el.type}/${el.uri.split(".").pop()}`,
name: el.uri.split("/").pop(),
uri: el.uri.replace("file://", ""),
Object {
        "type": "image/jpg",
        "uri": "/var/mobile/Containers/Data/Application/738480BE-5686-477A-BAC7-F8FBD9273708/Library/Caches/ExponentExperienceData/%2540kingth_man%252FKiwiMarket/ImagePicker/A2AE17D5-AE65-49CC-9B44-12626B0C013C.jpg",
      },

원하는 형태로 잘 만들어 졌다.

Object.keys() 뭐하는 녀석?

여기서 재밌었던 부분은 기존의 fetch방식에서 사용했던 body를 생각해서

이름 지은 state(body) 객체를 해체하고 를 각각의 키마다 [ key, value ] 배열을

하나씩 FormData.append() 해줘야 했다.

Object.keys() 어디선가 본 기억은 있는데...

그 당시엔 이걸 어디써? 라고 생각했는데..ㅋㅋㅋ

Object.keys(body)는 body의 키들로 이루어진 배열을 반환한다.

[
  'title',
  'price',
  'description',
  'access_range'
]

이렇게 javascript 문법이 중요하단걸 또 한번 느끼게 되었다!!

profile
왜?를 생각하며 개발하기, 다양한 프로젝트를 경험하는 것 또한 중요하지만 내가 사용하는 기술이 어떤 배경과 이유에서 만들어진 건지, 코드를 작성할 때에도 이게 최선의 방법인지를 끊임없이 질문하고 고민하자. 이 과정은 앞으로 개발자로 커리어를 쌓아 나갈 때 중요한 발판이 될 것이다.

0개의 댓글