그럼에도 불구하고

👨‍💻

[React] SWAPI 이용하기 본문

React/React basics

[React] SWAPI 이용하기

zenghyun 2023. 5. 31. 20:28

오늘은 SWAPI를 이용한 애플리케이션을 만들어보겠습니다.

 

 

[ SWAPI ]

SWAPI에는 각종 실습을 할 수 있는 더미데이터가 존재합니다.

 

 

https://swapi.dev/

 

SWAPI - The Star Wars API

What is this? The Star Wars API, or "swapi" (Swah-pee) is the world's first quantified and programmatically-accessible data source for all the data from the Star Wars canon universe! We've taken all the rich contextual stuff from the universe and formatted

swapi.dev

 

 

 

 

📌 App.js

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import React, { useState, useEffect , useCallback } from "react";
 
import MoviesList from "./components/MoviesList";
import "./App.css";
 
function App() {
  const [movies, setMovies] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);
 
  
 
  const fetchMoviesHandler = useCallback( async () => {
    setIsLoading(true);
    setError(null);
    try {
      const response = await fetch("https://swapi.dev/api/films");
      if (!response.ok) {
        throw new Error("Something went wrong!");
      }
      const data = await response.json();
 
      const transformedData = data.results.map((movieData) => {
        return {
          id: movieData.episode_id,
          title: movieData.title,
          releaseDate: movieData.release_date,
          openingText: movieData.opening_crawl,
        };
      });
      setMovies(transformedData);
      setIsLoading(false);
    } catch (error) {
      setError(error.message);
    }
    setIsLoading(false);
  }, []);
 
  useEffect( () => {
    fetchMoviesHandler();
  }, [fetchMoviesHandler]);
 
  let content = <p>Found no movies.</p>
 
  if(movies.length > 0 ){
    content = <MoviesList movies={movies} />;
  }
 
  if(error) {
    content = <p>{error}</p>
  }
 
  if(isLoading) {
    content = <p>Loading...</p>;
  }
 
  return (
    <React.Fragment>
      <section>
        <button onClick={fetchMoviesHandler}>Fetch Movies</button>
      </section>
      <section>
        {content}
      </section>
    </React.Fragment>
  );
}
 
export default App;
 
 
cs

 

1. SWAPI를 통해 데이터 받아옵니다. 

 

1
  const response = await fetch("https://swapi.dev/api/films");
cs

 

 

2. useEffect를 사용하여 button을 누르지 않아도 페이지 로드 시 자동으로 fetchMoviesHandler 함수를 호출하여 movieList를 가져옵니다. 

 

1
2
3
 useEffect( () => {
    fetchMoviesHandler();
  }, [fetchMoviesHandler]);
cs

 

 

3. useCallback을 사용하여 fetchMovieHandler의 재사용을 방지합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const fetchMoviesHandler = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    try {
      const response = await fetch("https://swapi.dev/api/films/");
      if(!response.ok) {
        throw new Error('Something went wrong!');
      }
      const datas = await response.json();
      const loadedMovies = datas.results.map((data) => ({
        id: data.episode_id,
        title: data.title,
        openingText: data.opening_crawl,
        releaseDate: data.rease_date,
      }));
      setMovies(loadedMovies);
    } catch (error) {
      setError(error.message);
    }
    setIsLoading(false);
  },[]);
cs

 

 

📌 MoviesList.js

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import React from 'react';
 
import Movie from './Movie';
import classes from './MoviesList.module.css';
 
const MovieList = (props) => {
  return (
    <ul className={classes['movies-list']}>
      {props.movies.map((movie) => (
        <Movie
          key={movie.id}
          title={movie.title}
          releaseDate={movie.releaseDate}
          openingText={movie.openingText}
        />
      ))}
    </ul>
  );
};
 
export default MovieList;
 
cs

 

 

📌 Movie.js

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React from 'react';
 
import classes from './Movie.module.css';
 
const Movie = (props) => {
  return (
    <li className={classes.movie}>
      <h2>{props.title}</h2>
      <h3>{props.releaseDate}</h3>
      <p>{props.openingText}</p>
    </li>
  );
};
 
export default Movie;
 
cs
Comments