React

Recoil 첫 사용, 썸네일 등록기능 구현

변기원 2022. 8. 26. 17:47

입점업체의 썸네일을 등록하는 기능을 구현하는데

이미지를 formdata로 보내는 게 전부라고 생각했는데 요구사항을 구현하는데 꽤 복잡했다.

 

기획 요구사항

1. 기존에 썸네일이 이미 등록되어 있는 경우에는 미리보기를 띄워준다.

2. 이미지 파일을 추가하거나(Input type file) 전에 올렸던 상품 사진 중에 사용하고 싶은 썸네일을 고를 수 있다.

3. 파일을 선택할지, 상품 이미지에서 선택할지, 중간중간 섞을지, 순서는 유저의 마음대로다.

4. 유저가 원한 순서 그대로 저장하고 미리보기도 그 순서와 일치할 것, 나중에 불러올 때도 그 순서대로 보장될 것.

5. 최대 5장까지 선택가능

 

 

요구사항을 구현하다 보니 컴포넌트가 생각보다 깊고 데이터 흐름이 복잡하다.

그래서 props로 넘기는 데이터들이 점점 많아졌다.(많다 보니 텍스트도 많아져서 더 복잡해 보임)

이 문제를 해결하고자 간편하게 전역 상태를 만들 수 있는 리코일을 도입했다.

 

가장 어려웠던 점은 썸네일 등록에 총 세 가지 케이스가 있으며 유저는 순서를 마음대로 사용할 수 있으며

그 유저가 등록한 썸네일 순서를 보장해야 하는 점이다.

여러 난관이 있었지만 결국 잘 해결했다.

 

고심해서 계획 먼저 세우고 구현했었는데 중간에 사소한 기획 요구사항이 있었다.

사소한 요구사항이라 금방 가능하다고 말씀을 드렸는데, 구현을 하다 보니 데이터 흐름을 완전히 뒤집어야 하는 상황이 되었다.

결국 다시 처음으로 돌아가서 위와 같이 계획을 세웠는데,

그림과 달리 아이디어는 심플하다.

 

유저가 어떤 방식으로 썸네일을 등록하든 previewImageFiles라는 전역 상태에 차곡차곡 쌓는다.

파일이든, 이미지 path든 상관없이 그냥 쌓는다. 

그리고 map을 돌려주며 이미지를 출력할 때 source의 형태에 따라 알맞은 path를 리턴하는 함수를 만들어 넣는다.

(파일이었으면 blob이 되겠지..)

그리고 서버에 post를 보내기 전에는 selector를 통해 데이터를 가져오는데

그 이유는 순서를 보장해야 하기 때문이다.

selector를 사용해서 파생된 상태를 만들어 서버에 보낼 데이터를 준비한다.

giveSortNumberReference는 referenceImageArr(atom)와 previewImageFiles(atom)와 상태가 연동된다.

즉, 쟤네가 변함에 따라 giveSortNumberReference도 파생된 상태가 변화한다.

 

미리보기에 있는 파일(previewImageFiles)과 기존에 사용했던 상품 이미지를 담은 배열(referenceImageArr)

을 가져와서 내가 보내려는 파일이 미리보기의 몇 번째 index에 있는지 찾은 후에 

sortNumber를 부여해서 백엔드에 보낼 데이터를 return 하는 selector이다.

 

백엔드에서는 내가 보낸 sortNumber와 id를 가지고 줄을 세워서 db에 저장해준다.

나중에 get 해서 유저에게 보여줄 때는 줄 세워진 sortNumber를 가지고 순서대로 보여주면 된다.

 

 

 

8.29 수정

쉬면서 생각해보니 훨씬 심플하게 생각이 들었다.

결국 미리보기 하는 객체가 핵심인데, 그 객체를 따로 만들어서 여러 상태를 관리하지 말고

unModifiedImageSource라는 상태를 만들어서 굳이 형태를 바꾸지 않고 순서만 맞춰서 집어넣는다.

그리고 서버에 보내기 전에 selector를 통해 이 객체에서 원하는 형태로 가공해서 뽑아 보내고

브라우저에 미리 보기 보여줄 땐 이 객체에서 형태에 따라 path키에서 뽑아 보여 줄지, createObjectURL을 만들어줄지 3항식 만들어주면

굳이 여러 상태를 복잡하게 유지할 필요도 없겠다.