프로젝트 생성
npx create-react-app movie_app
리액트 동작 방식 : 모든 react application을 div#root 사이에 삽입
// index.js
ReactDOM.render(<App />, document.getElementById("root"));
react는 소스코드에 처음부터 HTML을 넣지 않고, application이 빈 HTML을 로드하면 Virtual DOM을 통해 HTML을 채운다
컴포넌트 생성
import React from 'react';
function Apple(){
return <h3>hi</h3>
}
export default Apple
props 전달
<Food fav="kimchi" />
props 사용
function Food(props){
console.log(props) // {fav : "kimchi"}
return <h3>hi {props.fav}</h3>
}
// 구조분해할당(Destructuring) es6문법
function Food({fav}){
return <h3>hi {fav}</h3>
}
샘플데이터 배열
foodILike=[0,1,2,3,4]
동적 데이터 렌더링
// 반드시 유니크한 key값을 넘겨주어야 한다.
// key는 컴포넌트에서 사용하지 않고, react 내부에서 사용하기 위함
<div>
{foodILike.map(ele => <Food key={ele} number={ele}/>)}
</div>
props 타입 체크
npm i prop-types
import Proptypes from "prop-types";
function Food({name,rating}){}
Food.propTypes = {
name: Proptypes.string,isRequired,
rating: Proptypes.number,isRequired,
}
class 컴포넌트
import React from "react";
class App extends React.Component {
// state 사용 가능(가변 데이터)
state = {
count: 0
}
// react는 자동적으로 render함수를 실행
render(){
return <h1>number: {this.state.count}</h1>
}
}
state 값 변경(직접 변경 x)
add = () => {
this.setState({ count: 1 })
}
setState 사용 이유: setState를 호출하면 react는 state값을 변경하고 render함수 재호출
이전 state 값 사용
add = () => {
this.setState(current => ({ count: current.count + 1 }))
}
setState함수를 통해 기존에 없던 state를 추가할 수도 있다.
마운트 : 컴포넌트의 인스턴스가 생성되어 DOM 상에 삽입될 때
1. constructor()
2. render()
3. componentDidMount()
업데이트 : props 또는 state의 변경으로 리렌더링될 때
1. render()
2. componentDidUpdate()
마운트 해제 : 컴포넌트가 DOM 상에서 제거될 때
1. componentWillUnmount()
데이터 fetching(비동기 처리)
npm i axios
async componentDidMount(){
const { data: movies } = await axios.get("url")
this.setState({movies})
}
긴 텍스트 짜르기
<p>summary.slice(0,180)...</p>
github static 웹사이트 배포
npm i gh-pages
//package.json
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
// 이 부분 추가
"predeploy": "npm run build",
"deploy": "gh-pages -d build",
// 1. predeploy로 빌드 하여 build폴더 생성
// 2. build 폴더를 gh-pages로 배포
}
...
// 밑 부분에 추가(모두 소문자)
"homepage": "https://{git username}.github.io/{git project name}"
}
npm run deploy
npm i react-router-dom
라우터: url에 따른 컴포넌트 렌더링
import { HashRouter, Route } from "react-router-dom";
function App(){
return (
<HashRouter>
<Route path="/" exact={true} component={Home} />
<Route path="/about" component={About} />
</HashRouter>
)
}
export default App;
"/" url인 경우 중복렌더링을 방지하기 위하여 exact 옵셥을 주어야한다.
import { Link } from "react-router-dom";
function Navigation(){
return (
<div>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</div>
)
}
export default Navigation;
a 태그는 페이지를 새로고침함으로 리액트에서는 Link를 사용해야 SPA를 유지할 수 있다.
Link를 사용할 땐 반드시 Router 안에서 사용하여야 한다.
function App(){ return ( <HashRouter> <Navigation /> <Route path="/" exact={true} component={Home} /> <Route path="/about" component={About} /> </HashRouter> ) }
BrowerRouter도 있으나 github pages에 부적합
라우터 간 props 보내기
<Link
to={{
pathname: "/about",
state: {
fromNavigation: true
}
>About</Link>
보낸 props는 props.location.state에 담겨져 있다
class Detail extends React.Component {
componentDidMount(){
const { location, history } = this.props;
// 유저가 url을 직접 치고 들어올경우 props는 전달 안됌
if(location.state === undefined){
history.push('/'); // 리다이렉션
}
}
}