본문 바로가기

22 - 1학기/팀 스터디

[웹 FE 스터디] #7 PRACTICE MOVIE APP

TAB 2022 2학기 학회활동 [팀 스터디]

 TIL 포스팅입니다.

작성자 : 38기_서다원


간단한 투두 앱부터 만들어보자

import logo from "./logo.svg";
import "./App.css";
import { useState, useEffect } from "react";

function App() {
  const [toDo, setToDo] = useState(""); // 입력할 toDo
  const [toDos, setTodos] = useState([]); //todo 들의 리스트
  const onChange = (event) => setToDo(event.target.value); // 입력한 값이 toDo가 됨
  const onSubmit = (event) => {
    //submit 이벤트. 누르면 일어날 일들.
    event.preventDefault();
    if (toDo === "") {
      return;
    }
    setToDo(""); // 버튼을 누르면 폼이 비워지도록
    setTodos((currentArray) => [toDo, ...currentArray]); //원래의 state에 입력한 toDo를 추가
    console.log(toDos);
  };
  return (
    <div>
      <h1>My ToDos ({toDos.length})</h1>
      <form onSubmit={onSubmit}>
        <input
          onChange={onChange}
          value={toDo}
          type="text"
          placeholder="write your to do..."
        ></input>
        <button>Add To Do</button>
      </form>
      <hr />
      <ul>
        {toDos.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;

map 함수

let arr = [3, 4, 5, 6];

let modifiedArr = arr.map(function(element){
    return element *3;
});

console.log(modifiedArr); // [9, 12, 15, 18]

 

 


코인 정보를 가져오는 간단한 프로젝트이다.

import logo from "./logo.svg";
import "./App.css";
import { useEffect, useState } from "react";

function App() {
  const [loading, setLoading] = useState(true);
  const [coins, setCoins] = useState([]);
  useEffect(() => {
    fetch("https://api.coinpaprika.com/v1/tickers")
      .then((response) => response.json())
      .then((json) => {
        setCoins(json);
        setLoading(false);
      });
  }, []); //useEffect 를 한번만 실행시킬 거여서 [] 작성.
  return (
    //만약 loading 이 아니라면 아무것도 보여주지 않음.
    <div>
      <h1>The Coins! {loading ? "" : `(${coins.length})`}</h1>
      {loading ? <strong>loading...</strong> : null}
      <ul>
        {coins.map((coin) => (
          <li>
            {coin.name} ({coin.symbol} : ${coin.quotes.USD.price} USD
          </li>
        ))}
      </ul>
    </div>
  );
}
export default App;

fetch

서버에 네트워크 요청을 보내고 새로운 정보를 받아올 때 사용

API를 사용하여 백엔드 서버와 비동기 요청을 하는 방식 중 하나

  • url-접근하고자 하는 URL
  • options - 선택 매개변수, mehtod나 header 등을 지정할 수 있다
let promise = fetch(url, [options])

 

 

 


Browser Router

 

먼저 react-router-dom 을 설치하고 진행

 

App.js

import logo from "./logo.svg";
import "./App.css";
import { useState, useEffect } from "react";
import Movie from "./components/Movie";
import ProTypes from "prop-types";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Home from "./routes/Home";
import Detail from "./routes/Detail";

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/movie">
          <Detail />
        </Route>
        <Route path="/">
          <Home />
        </Route>
      </Switch>
    </Router>
  );
}

export default App;
http://localhost:3000/movie
http://localhost:3000/

Link

 

브라우저의 새로고침 없이 페이지를 이동할 수 있다.

 

App.js

import logo from "./logo.svg";
import "./App.css";
import { useState, useEffect } from "react";
import Movie from "./components/Movie";
import ProTypes from "prop-types";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import Home from "./routes/Home";
import Detail from "./routes/Detail";

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/movie/:id">
          <Detail />
        </Route>
        <Route path="/">
          <Home />
        </Route>
      </Switch>
    </Router>
  );
}

export default App;

Movie.js

import { Link } from "react-router-dom";
import PropTypes from "prop-types";

function Movie({ id, medium_cover_image, title, summary, genres }) {
  return (
    <div>
      <img src={medium_cover_image} alt={title} />
      <h2>
        <Link to={`/movie/${id}`}>{title}</Link>
      </h2>
      <p>{summary.length > 235 ? `${summary.slice(0, 235)}...` : summary}</p>
      <ul>
        {genres.map((g) => (
          <li key={g}>{g}</li>
        ))}
      </ul>
    </div>
  );
}

Movie.propTypes = {
  id: PropTypes.number.isRequired,
  coverImg: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string).isRequired,
};

export default Movie;

Detail.js

import { useEffect } from "react";
import { useParams } from "react-router-dom";
function Detail() {
  const { id } = useParams(); //App.js 에서 :id 에 해당
  const getMovie = async () => {
    const json = await (
      await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`)
    ).json();
    console.log(json);
  };
  useEffect(() => {
    getMovie();
  }, []);
  return <h1>Detail</h1>;
}
export default Detail;

Home.js

import { useState, useEffect } from "react";
import Movie from "../components/Movie";

function Home() {
  const [loading, setLoading] = useState(true);
  const [movies, setMovies] = useState([]);

  const getMovies = async () => {
    const json = await (
      await fetch(
        `https://yts.mx/api/v2/list_movies.json?minimum_rating=8.8&sort_by=year`
      )
    ).json();
    setMovies(json.data.movies);
    setLoading(false); //로딩이 끝남.
  };

  useEffect(() => {
    getMovies();
  }, []);
  return (
    <div>
      {loading ? (
        <h1>Loading...</h1>
      ) : (
        //로딩중이 아닐 때 보여줄 화면
        <div>
          {movies.map((movie) => (
            <Movie
              key={movie.id}
              id={movie.id}
              medium_cover_image={movie.medium_cover_image}
              title={movie.title}
              summary={movie.summary}
              genres={movie.genres}
            ></Movie>
          ))}
        </div>
      )}{" "}
    </div>
  );
}

export default Home;

Github Pages 배포하기

 

github pages 로 웹페이지 호스팅 하는건 구글링하면 방법이 굉장히 많이 나온다.

의외로 쓸일도 많고 간편하고

과제 제출용으로도 쓰이는 편!