본문 바로가기
🍀오늘도 삽질 중🍀/React.js

fetch 메소드로 백엔드랑 소통하기

by 매진2 2023. 6. 22.
728x90

이번주 fetch 함수를 배우고 mock 데이터와 상수 데이터를 만들어서 적용해보는 과제를 해보았는데

백엔드와의 직접적인 소통은 생각보다 어려웠다...

그리고 아직도 리액트가 적응이 안돼서 이게 되네...? 하고 있는 중이라 더 어려웠다.

바닐라자바스크립트로 할 때는 DOM을 직접 조작해야해서 뭔가 꼬고 또 꼬아 다가가는 느낌이었는데

리액트는 그냥 inputValue의 name 값을 가져오면 된다니...!

아직도 적응이 안된다. 리액트로 첨부터 배웠으면 더 쉽게 생각할 수 있었을까 하는 생각도 든다.


fetch 함수의 첫번째 인자는 백엔드에게 받는 API 주소이며 두번째는 옵션객체이다.

옵션 객체 안에 method가 GET이라면 옵션객체 전체가 생략 가능하다.

오늘은 로그인과 회원가입 기능이기때문에 POST를 쓸 예정이라 생략을 할 수 없다.

headers 에는 Content-Type을 application/json으로 넣어주어 Message Body에 들어가는 타입을 명시해준다.

body에는 JSON.stringify 넣어주어 자바스크립트의 값을 json으로 변환해달라고 요청하고

그 안에 내용에는 백엔드의 key값을 가져오고 input의 값을 가져올 변수를 넣어준다.

이때 우리는 react를 쓰고 있기 때문에 state의 값과 input의 name 속성값을 가져와주면 쉽게 input의 값을 가져올 수 있다.

fetch('http://10.58.52.71:3000/users/signIn', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        email: inputValue.id,
        password: inputValue.pw,
      }),
    })

이때 body 부분은 이렇게 쓸 수도 있다.

만약에 inputValue의 name이랑 백엔드에서 쓴 key 값이 같다면 아래와 같이 간단하게 쓸 수 있다.
        (예를 들어 email:inputValue.email 이라면 키값이 일치하기 때문에 생략 가능하다.)

     body: JSON.stringify(
        inputValue)

fetch 함수 뒤에는 then 함수가 같이 오는데 보통 2개를 사용하지만 간혹 1개를 사용하는 경우도 있다고 했다.

오늘은 2개를 사용할 예정이며 첫번째 then에서 인자를 fetch 함수의 결과를 가져오고 그 결과를 json 화 해달라고 한다.

  .then(response => {
        return response.json();
         }

그리고 첫번째 then에서 throw new Error 메소드를 쓰면 통신이 되는지 안되는지 확인할 수 있고

일반 alert와는 다르게 전체화면이 에러가 뜬 것처럼 바뀐다.

하지만 이 코드는 신기술이기도 하고 잘 안쓰고 처음 한번만 통신되는지 안되는지 확인 위해서 쓴다.

  .then(response => {
        if (response.ok === true) {
        return response.json();
         }
        throw new Error('통신실패!'); 
      })

두번째 then에서는 처음 값을 받기 전 console.log(data)로 값이 잘 들어오는지 확인을 한다.

console이 잘 뜬다면 if문으로 백엔드의 데이터와 연결한다.

data.message에서 message도 백엔드의 데이터의 객체의 키 값을 가져오는 것이기 때문에

백엔드가 message로 썼는지 comment 등 다른 것으로 썼는지 확인을 해야하며

소괄호 안에 들어간 LOGIN_SUCCESS, data.TOKEN 등 백엔드에게 가져오는 값은 미리 소통을 해서 확인을 해주어야한다.

우리는 localStorage에 토큰을 저장할 예정이기 때문에 setIem으로 저장해주고

값이 일치한다면 main으로 가는 navigator를 연결해준다. (이 내용은 이미 포스팅해두었다.)

만약 값이 안 맞다면 alert 창을 띄울 수 있게 해두었다.

이때 throw new Error 메소드가 남아있다면 모든 잘못된 정보에 반응해서 alert가 안 뜨고 에러창이 뜰 수도 있다.

처음 한번만 확인 해보고 바로 지우는것을 추천한다.

 .then(data => {
        // console.log(data); 
        if (data.message === 'LOGIN_SUCCESS') { 
          localStorage.setItem('token', data.TOKEN); 
          goToMain(); 
        } else if (data.message === '잘못된정보') { 
          alert('아이디 혹은 비밀번호를 확인 해 주세요');
        }

마지막으로 fetch 함수를 바로 적용했더니 계속 리랜더링이 되면서 네트워크도 터지려고 하고

렉도 너무 심하게 걸려서 아무것도 안눌려지고 런캣을 깔아뒀는데 고양이가 세상 열심히 뛰고 있었다.

fetch 함수 바깥에 함수를 또 걸어줘 조건이 이루어졌을 때만 작동될 수 있도록 만들어줬다.

아래는 전체코드이다.

const data = () => {
    fetch('http://10.58.52.71:3000/users/signIn', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        email: inputValue.id,
        password: inputValue.pw,
      }),
    })
      .then(response => {
        return response.json();
      })
      .then(data => {
        if (data.message === 'LOGIN_SUCCESS') {
          localStorage.setItem('token', data.TOKEN);
          goToMain();
        } else if (data.message === '잘못된정보') {
          alert('아이디 혹은 비밀번호를 확인 해 주세요');
        }
      });
  };
728x90