React ] 다사다난했던 회원가입 기능 구현..🔥

히징·2022년 7월 7일
0
post-thumbnail

회원가입기능 + 프로필설정 트러블 슈팅

회원가입 기능을 구현하면서 겪었던 여러가지 이슈들을 기록해보고자 한다.
정말 다사다난 했던 회원가입과 프로필설정 기능.. 💦
많은 에러들 중 가장 나를 힘들게 했던 에러들을 꼽자면,

1. 미리보기와 서버에 통신하는 파일 형식이 달라서 발생하는 문제점.

회원가입 기능 중 프로필설정 부분에서 이미지 아이콘을 누르면 이미지가 업로드되고, 미리보기가 가능한 기능을 구현하기위해 FileReader를 사용하였다.

문제점 :

화면상으로는 파일이 잘 바뀌었지만, 서버와 통신하는 과정에서 화면에 출력하기위해서 주소로 변환해주는 reader.readAsDataURL()때문에 이미지의 주소값이 API에서 요청하는 파일형식이아닌, base64 형식으로 들어가서 계속 이미지응답이 빈값으로 들어왔다.

해결 :

화면에 프로필 사진이 표시되는 저 위에 주석 코드를 전부 없애주고
서버 통신용 이미지 파일의 상태관리를 서버전송용과 view용으로 2개 나누어 관리해주었다.
파일을 업로드 할 때 setImg(서버통신용 파일형식)와 showImg(미리보기용 파일형식)으로 나누어 저장해주고, 화면에 랜더링 되는 부분은 전부 showImg 형식으로 바꾸어 문제를 해결했다.

2. 이미지 파일 전환 함수 실행 이슈

개요 :

우선, 회원가입 기능은 이메일로 회원가입과 프로필설정이 모두 이루어져 6가지 항목을 전부 입력해야 회원가입이 가능하다.

그렇기 때문에 시작하기 버튼을 눌러 6가지 항목이 저장된 userData를 전송하기전, image파일을 명세에서 요구하는 형식으로 변환해주는 함수(postImgData)를 먼저 실행해서 res값을 userData의 image에 넣어 준 후 회원가입 통신(postData)이 실행되어야 한다.

문제점 :

이과정에서 나는 먼저 프로필 이미지가 변경되었을때 바로 이미지변환함수가 실행되어 파일형식이 변환되었으면 했다. 그래서 프로필 이미지에 onChange 함수를 사용하고 싶었는데 이미 onChange 함수가 사용되어서 파일이 업로드되었을때 setImg에 저장되는 함수가 실행되고있었다.

그래서 냅다 코드 맨밑에 이미지변환함수(postImgData)를 넣었더니 빈값이 출력되었다.
useState의 경우 부모함수를 벗어난 다음에 값이 저장되는데 onChange함수안에 postImgData가 들어있어 여전히 setImg에 값이 저장되지 않아 빈값이 출력된 것이다.

그리고 onChange로 이미지가 변경될 때마다 변환함수를 실행하게 된다면, 유저가 프로필 이미지를 고민하느라 여러번 이미지를 바꾸게 된다면 불필요한 통신이 발생하기 때문에 이 방법 보다 회원가입통신을 하기 직전 바로 이미지를 변환함수가 실행된 후 회원가입이 되게 구현하는 것이 더 낫다고 판단하였다.

postImgData와 postData를 모두 시작하기 버튼이 눌러졌을때 순차적으로 실행되게 해야했는데,
통신코드를 주석으로 닫고 콘솔로그만 찍었을 경우에는 userData의 image에 postImgData의 res값이 잘 반영되다가도 통신코드를 실행하면 순서가 꼬였고 postData가 postImgData의 res값을 제대로 받아오지 못해 이미지가 빈값으로 전송되었다.

해결 :

1. 찝찝한 해결...

우리는 uerData의 img값만 받아오면 통신문제는 해결되었기 때문에 postImgData의 res값을 바로 postData의 매개변수로 받아오는 방법으로 임시적으로 해결했다.

그러나 이렇게 할 경우 프로필 이미지 업로드 함수를 재사용하는데 어려움이 있고 postData가 갑자기 뜬금없이 file만 받아오기 때문에 코드 가독성에서 문제가 있다.

2. 위 1번 해결의 문제점 해결방안

userData를 부모함수에 선언하고, image에 postImgData의 리턴값을 저장한 후 postData에서 매개변수로 userData를 불러온다.
이렇게 되면 postData가 userData를 받아오기 때문에 코드 가독성에도 문제가 없다.

3. 최종 코드

postData와 postImgData를 합쳐 SignUp함수를 만들었다.
실질적으로 이 모든 함수의 기능은 결국 회원가입에 도달하기 때문에 함수명을 좀 더 직관적으로 변경하였으며 postImgData는 ImgUpload 함수로 바꾸고, 재사용을 위해 코드를 따로 분리해 export 하였다. 위 2번을 참고하여 userData를 통신함수의 부모함수에 선언하였고
Signup함수에서 ImgUploade함수를 실행하여 이미지를 받아오고, 회원가입 통신까지 모두 이루어지게 구현하였다.
ImgUploade 함수의 리턴값을 받아올때 promiss로 받아오는 문제점과, imgUpload함수를 먼저 실행되게 해야하는 문제점을 해결하기 위하여 async await을 사용하여

async function signUp() {
    const imgUploadData = await ImgUpload(userImg)
    //유저데이터 변수의 이미지에 저장 
    userData.user.image = imgUploadData
    //회원가입 최종 전송
    axios.post(url + '/user', userData,
      { headers: { "Content-type": "application/json" } })
      .then((res) => console.log('회원가입', res))
  }

imgUpload함수를 먼저 실행한후, return 값을 imgUploadData에 저장되게 하였으며
userData 내에 user.img에 해당 값을 넣어주었다.
따라서 최종적으로 시작하기 버튼을 클릭했을 때 signUp함수가 실행되면 img파일명 변환함수가 실행된 후 해당 리턴값이 signUp에서 받아와 정상적으로 img파일명 변환 또한 잘 반영된 채로 회원가입 통신이 이루어 진 것을 볼 수 있다.

느낀점

꼬박 2~3일을 아침 9시부터 새벽까지 불태우며 아주 많은 삽질을 했지만 그래도 이렇게 여러 에러사항들을 마주치고 해결하다보니 useState와 axios에 대해 더욱 잘 이해할 수 있게 된 것 같다!!
특히 useState의 경우 값이 저장되기 위해서는 함수가 다 실행되고 난 후 값이 저장되기때문에 이 특징을 잘 고려해가며 코드를 작성해야 할 것 같다.
이렇게하면 돌아갈 것 같은데? 라는 생각으로 내가 구현하는 코드의 특징을 잘 파악하지 않고 무작정 구현했던 것이 시간이 오래걸린데 한 몫 한 것 같다.
그래도 여러번의 삽질이 힘은 들었지만 기억에도 오래남고, 얻는게 많아서 마냥 아까운 시간만은 아니었다. 앞으로 남은 기능들도 구현하기위해 열심히 공부해야겠다.

profile
FE DEVELOPER 👩🏻‍💻🤍

0개의 댓글