• react router는 동적 url을 지원
  • 동적 -> url에 변수를 넣을 수 있다는 의미
  • :를 붙여줘야 함, 안그러면 진짜 텍스트임
  • useParams -> 변수의 값을 넘겨줌
  • await는 asyns함수 내부에 있지 않으면 사용할 수 없음
import {
    BrowserRouter as Router,
    Route,
    Switch,
} from "react-router-dom";
import Detail from "./routes/Detail";
import Home from "./routes/Home";

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

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

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

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

export default Movie;
import { useEffect } from "react";
import { useParams } from "react-router-dom";
import { useState } from "react";

function Detail(){
    const [loading, setLoading] = useState(true);
    const [movie, setMovies] = useState([]);
    const {id} = useParams();
    const getMovie = async() => {
        const json = await( await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`))
        .json(); //id를 알고 있으니 api로부터 정보를 fetch해올 수 있음
        setMovies(json.data.movie);
        setLoading(false);
    }; 
    useEffect(()=>{
        getMovie();
    },[])
    console.log(movie);
    return <div>{loading ? <h1>Loading...</h1> :
      (<div>
        <div>
            <h1>{movie.title_long}</h1>
            <img src={movie.medium_cover_image} alt={movie.title}/>
            <h3>{movie.description_full}</h3>
            
      </div>
      </div>
      )}
    </div>;
}

export default Detail;

'React' 카테고리의 다른 글

#7.5 React Router  (1) 2023.03.13
#7.4 Movie App part Two  (1) 2023.03.13
#7.3 Movie App part One  (1) 2023.03.12
#7.2 Coin Tracker  (1) 2023.03.11
#7.1 To Do List part Two  (1) 2023.03.11
  • react-router-dom:컴포넌트들의 모음집
    • url이 바뀌면 어떤 걸 보여줄지 결정함
    • Router은 렌더링해주는 애
    • route는 url을 의미
    • switch는 route를 찾는 역할, 한번에 하나의 route만 렌더링 하기 위함
    • Link는 브라우저 새로고침 없이도 유저를 다른 페이지로 이동시켜주는 컴포넌트

  • 이전에는 app컴포넌트가 모든걸 다 하고 있었음
    그 다음에는 app컴포넌트에 만들었던 모든 로직을 별개의 장소로 옮김
    현재 app.js에서 react-router-dom의 컴포넌트를 가져다 쓰는 중
import PropTypes from "prop-types";
import {Link} from "react-router-dom";

function Movie({ coverImage, title, summary, genres }) {
    return (
        <div>
            <img src={coverImage} alt={title}/>
            <h2>
                <Link to="/movie">{title}</Link>
            </h2>
            <p>{summary}</p>
            <ul>
                {genres.map((g) => (
                    <li key={g}>{g}</li>
                    ))}
        </ul>
      </div>
    );
} 

Movie.propTypes = { //propTypes설정
    coverImage: PropTypes.string.isRequired,
    title: PropTypes.string.isRequired,
    summary: PropTypes.string.isRequired,
    genres: PropTypes.arrayOf(PropTypes.string).isRequired,
};

export default Movie;

movie.js

import {
    BrowserRouter as Router,
    Route,
    Switch,
} from "react-router-dom";
import Detail from "./routes/Detail";
import Home from "./routes/Home";

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

export default App;

app.js

'React' 카테고리의 다른 글

#7.6 Parameters  (0) 2023.03.15
#7.4 Movie App part Two  (1) 2023.03.13
#7.3 Movie App part One  (1) 2023.03.12
#7.2 Coin Tracker  (1) 2023.03.11
#7.1 To Do List part Two  (1) 2023.03.11
  • key는 react.js안에서만, map안에서 component들을 render할 때 사용함
    • props로써 우리의 component로 넘겨 component들이 받아서 사용하게 해줌
  • react router : 페이지를 전환하는 역할
  • app.js는 router를 render -> router은 url을 보고 있는 컴포넌트
  • Select and Ctrl + D 하면 vs코드 한번에 선택됨
  • Movie 컴포넌트 따로 만들어서 import 해온 뒤 prop으로 가져옴
import { useEffect, useState } from "react";
import Movie from "./components/Movie";

function App() {
 return null;
}

export default App;

app.js

import { useEffect, useState } 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();
    }, []);
    console.log(movies);
    return <div>{loading ? <h1>Loading...</h1> :
      (<div>
        {movies.map(movie => 
        <Movie //props로써 우리의 component로 넘겨 component들이 받아서 사용하게 해줌
          key={movie.id}
          coverImage={movie.medium_cover_image}
          title={movie.title}
          summary={movie.summary}
          genres={movie.genres}
        />)}
      </div>
      )}
    </div>;
}

export default Home;

home.js

'React' 카테고리의 다른 글

#7.6 Parameters  (0) 2023.03.15
#7.5 React Router  (1) 2023.03.13
#7.3 Movie App part One  (1) 2023.03.12
#7.2 Coin Tracker  (1) 2023.03.11
#7.1 To Do List part Two  (1) 2023.03.11

  • map을 쓰려면 key를 꼭 줘야 함
  • fetch, json을 진행 후 로딩을 끝냈기 때문에 반드시 setLoading(false)를 해줘야함
    then대신에 async-await를 보편적으로 사용함
    await을 감싸는 await을 만들 수 있음
    movies.map((movie
    ->map의 argument는 x, m, g 등등 마음대로 해도됨
    여기선 movie라고 정함
    div key={movie.id} h2{movie.title}/h2
    -> 이 컴포넌트들은 movie 배열에 있는 각 movie에서 변형되어 나온 것

    key={g} -> 따로 정해진 key가 없기 때문에 g를 가져와 key로 써줌
    단, g가 고유한 값일 경우에만 가능
import { useEffect, useState } from "react";

function App() {
  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();
  }, []);
  console.log(movies);
  return <div>{loading ? <h1>Loading...</h1> :
    <div>{movies.map(movie =>
      <div key={movie.id}>
        <img src={movie.medium_cover_image} />
        <h2>{movie.title}</h2>
        <p>{movie.summary}</p>
        <ul>
          {movie.genres.map((g)=>(
            <li key={g}>{g}</li>
          ))}
        </ul>
      </div>
    )}</div>}
  </div>;
}

export default App;

'React' 카테고리의 다른 글

#7.5 React Router  (1) 2023.03.13
#7.4 Movie App part Two  (1) 2023.03.13
#7.2 Coin Tracker  (1) 2023.03.11
#7.1 To Do List part Two  (1) 2023.03.11
#7.0 To Do List part One  (1) 2023.03.10
  • select에 있는 값을 가져오고 싶다면 onChange함수를 사용한 후, option의 value값을 지정해주면 useState함수에서  set함수를 사용해서 가져오면 된당
  • 함수가 1,2,3,4,5가 있다면
    • 동기함수는 1끝나고 2, 2끝나고 3 이런식으로 순차적으로 진행하고 
    • 비동기함수는 순서와 상관없이 완성된 쪽이 실행결과를 return 
  • fetch함수는 비동기적으로 처리되는 함수, fetch가 끝나기도 전에 다른 함수가 먼저 실행될 수 있기 때문에 then을 써서 순서를 고정시킴
    • then은 fetch끝나고 나서 실행해줘!라는 뜻이당
fetch('api 주소')
.then(res => res.json())
.then(res => {
  // data를 응답 받은 후의 로직
});
import { useEffect, useState } from "react";

function App() {
  const [loading, setLoading] = useState(true);
  const [coins, setCoins] = useState([]) //비어있는 array로 두면 undefined됨
  const [money, setmoney] = useState(0)
  const [selectCoin, setSelectCoin] = useState(0)
  const onChange=(event)=>{
    setmoney(event.target.value);
  };
  const changeValue = (event)=>{
    setSelectCoin(Math.floor(money/event.target.value));
  }
  useEffect(() => {
    fetch("https://api.coinpaprika.com/v1/tickers")
      .then((response => response.json()))
      .then((json) => {
        setCoins(json);
        setLoading(false);
      });
  }, []);
  console.log(money);
  console.log(selectCoin);
  return (
    <div>
      <h1>The Coins! {loading ? "" : `(${coins.length})`}</h1>
      {loading ? <strong>loading...</strong> : ""}
        <div><input onChange={onChange} value={money}/></div>
      <select onChange={changeValue} >
        {coins.map((coin) => (//coin은 coins array안에 있는 각각의 coin의미
          <option key={coin.id} value={coin.quotes.USD.price}>
            {coin.name} ({coin.symbol}) : ${coin.quotes.USD.price} USD
          </option>
        ))}
      </select>
      <h3>{selectCoin}개 구매가능</h3>
    </div>
  );
}

export default App;

 

'React' 카테고리의 다른 글

#7.4 Movie App part Two  (1) 2023.03.13
#7.3 Movie App part One  (1) 2023.03.12
#7.1 To Do List part Two  (1) 2023.03.11
#7.0 To Do List part One  (1) 2023.03.10
#6.4 Cleanup  (0) 2023.03.10
  • map() : array 각각의 element를 바꾸고 싶을때 사용하는 것
    [a,b,c].map()을 하면 각각의 a,b,c에 대해 map안에 적은 함수가 6번 실행됨
    그 함수로부터 return한 어떤 값은 새로운 array에 들어감 

  • array를 가져와서 그 array의 item을 변형해서 li가 되도록 한것 
import { useEffect, useState } from "react";

function App() {
  const [toDo, setToDo] = useState("");
  const [toDos, setToDos] = useState([]);
  const onChange = (event) => setToDo(event.target.value);
  const onSubmit = (event) => {
    event.preventDefault();
    if (toDo === "") {
      return;
    }
    setToDos((currentArray) => [toDo, ...currentArray]);
    setToDo("");
  };
  console.log(toDos);
  console.log(toDos.map((item, index) => <li key={index}>{item}</li>))
  return (
    <div>
      <h1>My To Dos ({toDos.length})</h1>
      <form onSubmit={onSubmit}>
        <input onChange={onChange} value={toDo} type="text" placeholder="Write your to do.." />
        <button>Add To Do</button>
      </form>
      <hr />
      <ul>
        {toDos.map((item, index) => <li key={index}>{item}</li>)}
      </ul>
    </div>
  );
}

export default App;

'React' 카테고리의 다른 글

#7.3 Movie App part One  (1) 2023.03.12
#7.2 Coin Tracker  (1) 2023.03.11
#7.0 To Do List part One  (1) 2023.03.10
#6.4 Cleanup  (0) 2023.03.10
#6.3 Recap  (1) 2023.03.10

배열 원소 합치는 법

  • array를 직접적으로 수정하지 않으면서 setToDos로 array에 element를 추가하는 방법 
import { useEffect, useState } from "react";

function App() {
  const [toDo, setToDo] = useState("");
  const [toDos, setToDos] = useState([]);
  const onChange = (event) => setToDo(event.target.value);
  const onSubmit = (event) => {
    event.preventDefault();
    if (toDo === ""){
      return;
    }
    setToDos((currentArray) => [toDo, ...currentArray]);
    setToDo("");
  };
  console.log(toDos);
  return (
    <div>
      <h1>My To Dos ({toDos.length})</h1>
      <form onSubmit={onSubmit}>
        <input onChange={onChange} value={toDo} type="text" placeholder="Write your to do.." />
        <button>Add To Do</button> {/*버튼이 클릭됐을때 form을 submit*/}

      </form>
    </div>
  );
}

export default App;

'React' 카테고리의 다른 글

#7.2 Coin Tracker  (1) 2023.03.11
#7.1 To Do List part Two  (1) 2023.03.11
#6.4 Cleanup  (0) 2023.03.10
#6.3 Recap  (1) 2023.03.10
#6.2 Deps  (0) 2023.03.10
    • component는 단지 jsx를 부르는 function임
    • 우리가 component를 show할 때 함수가 작동됨 
    • 컴포넌트가 제거될때 뭔가 할 수 있도록 해주는 애 = cleanup function
    • 컴포넌트가 파괴될 때도 function을 실행하고 싶으면 hiFn이 byFn을 return해야함
function byeFn(){
    console.log("bye :(");
  }
  function hiFn() {
    console.log("created :)");
    return byeFn; //컴포넌트가 파괴될 때 실행 
  }
  useEffect(hiFn,[]);
import { useEffect, useState } from "react";

function Hello() {
  useEffect(()=> {
    console.log("hi :)");
    return () => console.log("bye :(")
  }, []);
  useEffect(function () {
    console.log("hi :)");
    return function(){
      console.log("bye :(")
    };
  }, []);
  return <h1>Hello</h1>;
}

function App() {
  const [showing, setShowing] = useState(false);
  const onClick = () => setShowing((prev) => !prev);
  return (
    <div>
      {showing? <Hello/> : null}
      <button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
    </div>
  );
}

export default App;
useEffect(() => {
    console.log("created :)"); //component가 처음 생성될 때만 실행됨
    return () => {console.log("destroyed :(")} //component가 제거될 때 실행됨
  }, []); //우리가 component를 show할 때 함수가 작동됨

'React' 카테고리의 다른 글

#7.1 To Do List part Two  (1) 2023.03.11
#7.0 To Do List part One  (1) 2023.03.10
#6.3 Recap  (1) 2023.03.10
#6.2 Deps  (0) 2023.03.10
#6.1 useEffect  (0) 2023.03.10

+ Recent posts