React App 만들기

  1. React
    1. Create React App
      1. CSS Module
      2. Clean up
      3. map
    2. 예제 및 실습
      1. 예제1. Coin List
      2. 실습1. Movie
    3. React Router
    4. Link
    5. breaking change

React

  • SPA(Single Page Appliication) 페이지가 1개인 어플리케이션을 의미한다.

react-router-dom

  • SPA에서 화면 전환을 위해 사용되는 모듈

Create React App

react-app 만들기
npx create-react-app [프로젝트명]

실행
npm satrt

type error를 받기 위해 prop 설치
🔧 npm install prop-types

사용 예시

import PropTypes from "prop-types";

function Button({ text }) {
  return <button>{text}</button>;
}

Button.propTypes = {
  text: PropTypes.string.isRequired,
};
export default Button;

CSS Module

  • css 파일을 만들어 여러 곳에서 사용할 수 있게 한다.

사용법

  1. Button.module.css 생성
    Button.module.css
.btn {
  color: white;
  background-color: seagreen;
  font-size: 20px;
}
  1. import 후 적용 Button.js ```js import PropTypes from “prop-types”; import styles from “./Button.module.css”;

function Button({ text }) { return <button className={styles.btn}>{text}</button>; }

Button.propTypes = { text: PropTypes.string.isRequired, }; export default Button;

<hr>

### useEffect
- 두개의 argument를 가진다.

첫번째 argument : 한번만 실행할 코드
두번째 argument : 해당 argument에 업데이트가 있다면 re-render
```js
useEffect(() => {
    console.log("Call the API...");
  }, []);
  useEffect(() => {
    console.log("Search for", keyword);
  }, [keyword]);

Clean up

  • 메모리 누수를 방지하기 위해 사용
function Hello() {
    useEffect(()=> {
        console.log("created :)");
        return () => console.log("destroyed :(");
    }, []);
    return <h1>Hello</h1>
}

간단하게 쓰기

  useEffect(function () {
    console.log("hi :)");
    return function () {
      console.log("bye :)");
    };
  }, []);

  useEffect(() => {
    console.log("hi :)");
    return () => console.log("bye :(");
  }, []);

map

예제3. To Do List

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>To Do List ({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.reverse().map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

예제 및 실습

예제1. Coin List

function App() {
  const [loading, setLoading] = useState(true);
  const [coins, setCoins] = useState([]);
  const [selectPrice, setSelectPrice] = useState(0);
  const [usd, setUsd] = useState(0);

  const onChange = (event) => setUsd(event.target.value);
  const onChangeSelect = (event) => {
    setSelectPrice(event.target.value);
  };

  const reset = () => {
    setUsd(0);
  };

  useEffect(() => {
    fetch("https://api.coinpaprika.com/v1/tickers")
      .then((response) => response.json())
      .then((json) => {
        setCoins(json);
        setLoading(false);
      });
  }, []);
  return (
    <div>
      <h1>Coin List {loading ? "" : `(${coins.length})`}</h1>
      {loading ? (
        <strong>Loading...</strong>
      ) : (
        <select onChange={onChangeSelect} style={{ fontSize: "20px" }}>
          {coins.map((coin, index) => (
            <option value={coin.quotes.USD.price} key={coin.id}>
              {coin.name} ({coin.symbol}) : $ {coin.quotes.USD.price.toFixed(5)} USD
            </option>
          ))}
        </select>
      )}
      <hr />
      <form>
        <div>
          <label htmlFor="usd" style={{ fontSize: "25px" }}>
            ${" "}
          </label>
          <input value={usd} type="number" placeholder="Write Your Dollar..." style={{ fontSize: "20px" }} onChange={onChange} />
        </div>
        <div>
          <span style={{ fontSize: "20px" }}> </span>
          <input value={(usd / selectPrice).toFixed(5)} type="number" placeholder="Write Your BTC..." style={{ fontSize: "20px" }} disabled />
        </div>
        <button style={{ fontSize: "20px" }}>calculate</button>
        <button onClick={reset} style={{ fontSize: "20px" }}>
          reset
        </button>
      </form>
    </div>
  );
}

실습1. Movie

useEffect(() => {
    fetch(`
    https://yts.mx/api/v2/list_movies.json?minimum_rating=8.8&sort_by=year
    `)
      .then((response) => response.json())
      .then((json) => {
        setMovies(json.data.movies);
        setLoading(false);
      });
  }, []);

async await

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();
  }, []);

React Router

React Router 살펴보기

React Router 설치
npm install react-router-dom

import
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

BrowserRouter과 HashRouter는 URL 생김새에 차이가 있다.


href와 달리 페이지가 새로고침되지 않는다.

※※ async는 function안에 없으면 사용할 수 없다.


breaking change

버전 업데이트 후 코드 에러


Nomad Coders