스터디/React

[노마드코더 ReactJS] React JS 로 영화 웹서비스 만들기

_leezoee_ 2022. 5. 4. 15:12

Babel

JSX 문법 사용시 브라우저가 읽을 수 있도록 호환

 

JSX

<Title/> <Button/> 이런식으로 대문자로 생성해서 기존 html <button></button>과 구분

 

state

기본적으로 데이터가 저장되는 곳

 

React js state특징 : 리랜더링 필요없이 컴포넌트에 바뀐부분만 업데이트 됨. 상호작용성이 좋음.

 * React 의 컴포넌트 리랜더링 방법 => React.useState(초기값); 사용  이때 [값, 실행함수] 가 리턴. 실행함수 실행 시

   리랜더링이 자동으로 이루어짐

 * js 배열 요소 꺼내기 => const food = ["tomato", "potato"]   const [myFavFood, mySecondFavFood] = food; 

   하면 myFavFood  했을때 tomato 나옴.

콘솔창 테스트

 

 * state를 바꾸는 2가지 방법 => 1. 실행함수에 원하는 값 넣기, 2. 이전 값을 이용해 현재 값을 계산

  2번의 경우  setCurrent((current) => current +1);  처럼 현재 값을 인자로 받아서 사용하는게 버그방지에 좋음

  

 * 삼항연산자 => inverted ? amount : Math.round(amount/60)  : inverted가 true면 amount를 그냥 보여주고  false면

   /60 반올림 값을 보여줌

 

 

함수형 컴포넌트

function ConfirmBtn(){//함수형 컴포넌트
	return <button>Confirm</button>
}

function App(){//JSX
	return(
    	<div>
        	<ConfirmBtn/>
        </div>
    )
}

 

Props 사용

function Btn({test, big , border=0}) {//props는 object 형태로 props.test 혹은 저렇게 {test}로도 사용가능.
	return(
		<button>
        	style={{
            	backgroundColor : "tomato",
                color : "white",
                padding : "10px",
                border, //props  에 =0을 주면 기본값으로 0을 줄수 있음, required props 아니니까 
                borderRadius : 10,
                fontSize : big ? 18 : 16 //넘어온 인자 기준
            }}
            {test}
        </button>    
    )
}

//PropsType 패키지 설치하면 props 의 타입을 명시할 수 있음.
Btn.propTypes = {
	test : PropTypes.string.isRequired, //필수인자
    big : PropTypes.boolean,
    border : PropTypes.number
}

function App() {
	return(
    	<div>
        	<Btn test="Save" big={true} border={1} />
            <Btn test="Cancle" big={false} />
        </div>
    )
}

 

React Memo

 부모컴포넌트의 state 변화로 자식 컴포넌트들까지 전부 re-render 되면 복잡한 컴포넌트 경우 나중에 느려지는 문제가 있을 수 있음. const = MemorizedBtn = React.memo(Btn); 처럼 momo를 사용하면 props가 변화되지 않는 자식 컴포넌트들은 re-render 되지 않도록 막을 수 있음.

 

 

create-react-app

 class css 를 모듈화 해서 임포트 할 수 있는 장점이 있음

/*Button.module.css*/
.btn{
	color : white;
    background-color : tomato;
}
//Button.js
import styles from "./Button.module.css";

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

 

effects

state가 변화할때 모든 component는 다시 실행되고, 모든 code도 다시 실행 됨.

component 내부 몇몇 코드는 처음 한번만 실행 시키고 싶으면?

useEffect 사용 : 코드가 원하는 때에 실행될 수 있도록 보호해줌. 두개의 argument를 가짐 => 1. 실행하려는 코드, 2. dependency (지켜보고자 하는 state)

useEffect(() => {
	if(keyword !== "" && keyword.length > 5){
    	console.log("SEARCH FOR", keyword);
    }	
}, [keyword]);//keyword가 변화 될 때만 실행하겠다고 명시

useEffect(() => {
	console.log("START API...");
}, []);//빈 배열이므로 react가 아무것도 주시하고있지않음. 처음 한번만 실행

 

To Do List 만들어보기

*state 직접변경X, 함수를 통해 변경

+ js 새 배열에 기존 배열 값 추가 : const test = [1,2,3], const testNew = [4, ...test] 방식으로 ... 사용

* jsx 에서 javascript 쓰고싶으면 중괄호 사용 {}

* [].map() 함수는 array 안에 인자 개수만큼 돌면서 실행됨, 기존 array 변경

  ex)  ['there' , 'are' , 'you' , 'are' , 'how' , 'hello!'].map((item) => item.toUpperCase())

        ['THERE' , 'ARE' , 'YOU' , 'ARE' , 'HOW' , 'HELLO!']

 

//App.js

import { 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("");
    } 

	return(
    	<div>
        	<h1>My To Do List ({toDos.length})</h1>
        	<form onSubmit={onSubmit}>
            	<input
                	onChange={onChange}
                    value={toDo}
                    type="text"
                    placeholder="Write your to do..."
                />
                <button>Add</button>
            </form>
            <hr />
            <ul>
            	{toDos.map((item, index) => (
                	<li key=(index)>{item}</li>
 	               )
                )}
            </ul>
        </div>
    );
}

 

 

Coin Tracker (useEffect연습)

//App.js

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

	return(
    	<div>
        	<h1>The Coins! {loading ? "" : `(${coins.length})`}</h1>
            {loading ? (
            	<strong>Loading...</strong>
            ) : (
            	<select>
                	{coins.map((coin) => {
                    	<option>
                        	{coin.name} ({coin.symbol}) : ${coin.quotes.USD.price} USD
                        </option>
                    })}
                </select>
            )}
        </div>
    );
}

 

Movie App

* .then() 대신 async-await 사용

* react-router-dom

 

react-router-dom

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

 * 다이나믹 동적 url 제공 <Route path="/movie/:id"> 형태로 사용 : 필수

 * useParams() 사용 : React Router 가 넘겨주는 변수를 받을 수 있음.

 

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

//Detail.js
function Detail(){
	const { id } = useParams();//라우터에서 넘기는 id를 그대로 받아 쓸수 있음
    console.log(id);
    return <h1>Detail</h1>
}
export default Detail;

 

Breaking Change : 버전 업데이트로 코드가 깨져서 코드를 수정해야 하는 상황