[노마드코더 ReactJS] React JS 로 영화 웹서비스 만들기
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 : 버전 업데이트로 코드가 깨져서 코드를 수정해야 하는 상황