CSS Flex
CSS Grid
var, let, const
var은 함수 단위로 정의됨
let은 Block 단위로 정의됨
function test(){
var a = 0;
let b = 0;
if (a === 0){
var a = 1;
let b = 1;
}
console.log(a, b);
// a = 1, b = 0
// a는 함수 단위로 동작하기 때문에 if block 안에서 정의한 a = 1이 if 바깥에서도 유효함
// b는 블록 단위기 때문에 if를 벗어나는 순간 b = 1의 효력이 사라짐
}
[Component]
리액트는 레고, 컴포넌트는 블록
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<header>
...
</header>
<div class="container">
<div id="image-banner">
...
</div>
<div id="contents-1">
...
</div>
</div>
<footer>
...
</footer>
</body>
</html>
HTML 구조가 있을때 Component로 구성시 다음과 같음
<header/>
<container/>
<imagebanner/>
<contents1/>
<footer/>
자식 컴포넌트가 부모 컴포넌트로 전달 받은 데이터를 props라고 함
Props로 받은 데이터는 수정 할 수 없음
자식 컴포넌트는 부모 컴포넌트에 속해있음
yarn add styled-components
컴포넌트 스타일링 기법 중 하나
[리액트에서 DOM 요소 사용]
방법 1: React.createRef()
this.text = React.createRef();
<input type="text" ref={this.text} />
방법 2: React.useRef()
const my_wrap = React.useRef(null);
<div ref={my_wrap}>
[State 관리]
단방향 데이터 흐름
State 관리 방법 1: setState()
this.state = { count: 3, };
this.setState({ count: this.state.count - 1 });
State 관리 방법 2: useState()
const [count, setCount] = React.useState(3);
count에는 state 값이, setCount는 count라는 state 값을 수정하는 함수가 됨
setCount(count + 1);
[Event]
addEventListener()를 통해 특정 요소에 이벤트를 등록 가능
this.특정요소.current.addEventListener("mouseover", this.이벤트명);
useEffect()는 리액트 훅
// 첫번째 인자는 렌더링 시 실행할 함수
// 두번째 인자[]! 디펜던시 어레이가 변하면 첫번째 인자 함수를 호출함
React.useEffect(() => {
// rendering 때 실행될 구문
// componentDidMount, componentDidUpdate일 때 동작하는 부분
text.current.addEventListener("mouseover", hoverEvent);
return () => {
// clean up 부분
// componentWillUnmount 때 동작하는 부분
// 이벤트는 컴포넌트가 사라지면 지워야함
text.current.removeEventListener("mouseover", hoverEvent);
};
}, [text]);
[SPA]
Single Page Application
라우팅
import { BrowserRouter } from "react-router-dom";
<BrowserRouter>
<App />
</BrowserRouter>,
BrowserRouter(브라우저라우터)는 웹 브라우저가 가지고 있는 주소 관련 정보를 props로 넘겨줌
[Route 적용]
방법1: 넘겨줄 props가 없을 때
<Route path="주소[/home 처럼 /와 주소를 적음]" component={[보여줄 컴포넌트]}/>
방법2: 넘겨줄 props가 있을 때
<Route path="주소[/home 처럼 /와 주소를 적음]" render={(props) => (<BucketList list={this.state.list} />)} />
정리:
import { Route } from "react-router-dom";
render(){
return (
<div className="App">
<Route path="/" exact component={Home} />
<Route path="/cat" component={Cat} />
<Route path="/dog" component={Dog} />
</div>
);
}
/cat과 /dog에는 /이 있기에 {Home} 페이지가 포함되서 나옴
exact를 적용해 제외시킴
파라미터 주는 방법
<Route path="/cat/:cat_name" component={Cat}/>
파라미터는 props로 받아올 수 있지만, useParams 훅을 이용해 받을 수도 있음
import React from "react";
import { useParams } from "react-router-dom";
const Cat = (props) => {
const cat_name = useParams();
console.log(cat_name);
// console.log(props);
return (
<div>고양이 화면입니다!</div>
);
};
export default Cat;
Link 컴포넌트를 이용해 리액트 내에서 페이지 전환 가능
import { Route, Link } from "react-router-dom";
<div className="App">
<div>
<Link to="/">Home으로 가기</Link>
<Link to="/cat">Cat으로 가기</Link>
<Link to="/dog">Dog으로 가기</Link>
</div>
<Route path="/" exact>
<Home />
</Route>
<Route path="/cat" component={Cat}>
{/* <Cat /> */}
</Route>
<Route path="/dog">
<Dog />
</Route>
</div>
Link 대신 props로 history 객체를 받아 이동 가능
props.history.push("/home");
props를 안써도 useHistory 훅을 이용하면 간단히 history 객체에 접근 가능
let history = useHistory();
history.push("/cat");
react-router-dom 버전 6부터는 useHistory 대신 useNavigate를 사용
history에 goBack을 이용하면 뒤로가기 이벤트 생성 가능
history.goBack();
Route에 주소없이 연결시 지정하지 않은 주소로 들어오는 요청 대응 가능
import { Route, Switch } from "react-router-dom";
<Route component={NotFound} />
react-router-dom 버전 6부터는 Switch 대신 Routes를 사용
component -> element로 변경
[리덕스를 이용한 상태관리]
리덕스는 여러 컴포넌트가 동일한 상태를 보고 있을 때 유용
데이터 관리 로직을 컴포넌트에서 빼면, 컴포넌트는 뷰만 관리 가능
상태 관리 주요 흐름: Store, Action, Reducer, Component
1. 리덕스 Store를 Component에 연결
2. Component에서 상태 변화가 필요할 때 Action 호출
3. Reducer를 통해서 새로운 상태값을 만듬
4. 새 상태값을 Store에 저장
5. Component는 새로운 상태값을 받아옴(props를 통해 받아오며 다시 랜더링)
리덕스는 상태관리 라이브러리, 전역 상태관리를 도와줌
리덕스는 데이터를 한 군데 몰아넣고, 여기저기에서 꺼내볼 수 있게 해줌
yarn add redux react-redux
1. State: 리덕스에서 저장하고 있는 상태값(딕셔너리 형태로 보관)
2. Action: 상태에 변화가 필요할 떄 발생(액션은 객체)
3. ActionCreator: 액션 생성 함수, 액션을 만들기 위해 사용
4. Reducer: 리덕스에 저장된 상태(=데이터)를 변경하는 함수
액션 생성 함수 호출 -> 액션 생성 -> 리듀서가 현재 상태와 액션 객체를 받음 -> 새로운 데이터 생성 -> 리턴
// 기본 상태값을 임의로 정함
const initialState = {
name: 'mean0'
}
function reducer(state = initialState, action) {
switch(action.type){
// action의 타입마다 케이스문을 걸어줌
// 액션에 따라서 새로운 값을 리턴
case CHANGE_STATE:
return {name: 'mean1'};
default:
return false;
}
}
[리덕스의 3가지 특징]
1. store는 1개만
2. store의 state(데이터)는 오직 action으로만 변경 가능
[덕스 구조]
보통 리덕스를 사용할 때는 모양새대로 action, actionCreator, reducer를 분리해 작성
(액션은 액션끼리, 액션생성함수는 액션생성함수끼리, 리듀서는 리듀서끼리 작성)
덕스 구조는 모양새로 묶는 대신 기능을 묶어 작성
(특정 기능의 action, actionCreator, reducer를 한 파일에 넣음)
[컴포넌트 리덕스 데이터]
리더스도 훅이 존재함 2개의 훅을 주로 씀
import {useDispatch, useSelector} from "react-redux";
const my_lists = useSelector((state) => state.bucket.list);
state는 리덕스 스토어가 가진 전체 데이터
const dispatch = useDispatch();
dispatch(createBucket(text.current.value));