[TIL] API

동화·2022년 12월 21일
0

TIL

목록 보기
2/21
post-custom-banner

👨‍💻 React HTTP 요청 보내기

  • 클라이언트에 직접적으로 서버를 연결하면 자바스크립트 코드는 누구나 확인할 수 있기 때문에 인증 정보를 노출시키는 행위이며 보안에 취약해진다.
  • HTTP 요청에 대한 API를 말할 때는 보통 REST 또는 GraphQL API를 말하며 이 두 개는 서버가 데이터를 노출하는 방식에 대한 서로 다른 표준이다.
  • Fetch API는 브라우저 내장형이며 데이터를 불러오고 이름과는 다르게 전송도 가능하다.

사용한 API주소 : https://swapi.dev/
API 설명: 영화에 대한 정보를 JSON형식으로 보여줌

영화에 대한 정보를 불러와 그를 보여주는 간단한 함수

const [movies, setMovies] = useState([]);

// 이제 이 함수가 호출될 때 마다 매 번 HTTP 요청이 전송됨
function fetchMoviesHandler () {
  // fetch를 통해 프로미스 객체를 반환함
  fetch('https://swapi.dev/api/films/')
  // *중요* 왜? then을 사용해야 하냐? - HTTP 요청은 즉각 끝나는 작업이 아니기에 미래의 어느 시점에서 확인할 수 있음
  // 이 말은 즉, 끝나는 시점에 맞춰 then을 이용하여 비동기 처리를 해야함

  // 요청 받은 데이터는 JSON 형식이므로 코드에서 사용할 수 있는 객체로 반환함
  .then(response => response.json())
  // 그 변환된 데이터를 useState로 movies에 넣어줌
  .then((data) => {
    setMovies(data.results);
  }
}





위 처럼 데이터를 바로 넣어줄 수 있겠지만 실제로 짜여진 코드와 불러오는 데이터에서 키 값에 차이가 있을 수 있다.
그러므로 map을 이용하여 원래 짜여진 키 값에 맞춰주는 게 좋다.
(물론, 받아오는 데이터의 키 값에 맞게 코드를 수정하는 방법도 있다.)

const [movies, setMovies] = useState([]);

function fetchMoviesHandler () {
  fetch('https://swapi.dev/api/films/')
  .then(response => response.json())
  .then((data) => {
    const transformedMovies = data.results.map(movieData => {
      return {
        id: movieData.episode_id,
        title: movieData.title,
        openingText: movieData.opening_crawl,
        releaseDate: movieData.release_date
      };
    });
    setMovies(transformedMovies);
  }
}



이해를 위한 더미데이터와 API 요청에 의해 가져온 데이터 비교



  • 위의 fetch를 이용한 방법과 똑같이 async, await를 이용하여 코드를 간결하게 할 수 있다.
  • 이건 리액트의 특별 기능이 아닌 자바스크립트의 기본 기능이다.
  • 실제로 이 코드가 실행될 땐 then으로 번역되어 실행된다.
const [movies, setMovies] = useState([]);

async function fetchMoviesHandler () {
  const response = await fetch('https://swapi.dev/api/films/')
  const data = await response.json();
  const transformedMovies = data.results.map(movieData => {
    return {
      id: movieData.episode_id,
      title: movieData.title,
      openingText: movieData.opening_crawl,
      releaseDate: movieData.release_date
    };
  });
  setMovies(transformedMovies);
}




로딩 화면 구현하기 💭

const [movies, setMovies] = useState([]);
const [isLoading, setIsLoading] = useState(false);

async function fetchMoviesHandler () {
  // 아래의 코드들이 실현되기 전에 로딩 상태를 true로 만듬
  setIsLoading(true);
  const response = await fetch('https://swapi.dev/api/films/')
  const data = await response.json();
  const transformedMovies = data.results.map(movieData => {
    return {
      id: movieData.episode_id,
      title: movieData.title,
      openingText: movieData.opening_crawl,
      releaseDate: movieData.release_date
    };
  });
  setMovies(transformedMovies);
  // 모든 코드가 돌아갔다면 다시 로딩 상태를 false로 만듬
  setIsLoading(false);
}

const App () => {
  return (
    <React.Fragment>
      // 로딩 상태가 false일 경우 MovieList 컴퍼넌트를 보여주고
      {!isLoading && <MovieList/>}
      // 로딩 상태가 true일 경우 LoadingPage 컴퍼넌트를 보여줌
      {isLoading && <LoadingPage>}
    </React.Fragment>
  )
}



  • 추가로 컨텐츠가 없을 경우의 화면도 나누는 방법도 있다.
  • 활용할 수 있는 방법은 무궁무진하다.
const App () => {
  return (
    <React.Fragment>
      // 로딩은 되었고 보여줄 내용이 있는 경우
      {!isLoading && movies.length > 0 && <MovieList/>}
      // 로딩은 되었지만 보여줄 내용이 없는 경우
      {!isLoasing && movies.length === 0 && <EmptyList/>}
      // 로딩이 안 된 경우
      {isLoading && <LoadingPage>}
    </React.Fragment>
  )
}
post-custom-banner

0개의 댓글