SCSS
- CSS를 편하게 쓸 수 있도록 도와줌
- node-sass 설치하기
yarn add node-sass@4.14.1 open-color sass-loader classnames
- 중첩된 속성
div {
p {
color: #888888;
font: {
family: sans-serif;
size: 14px;
}
}
img {
width: 400px;
}
}
- 상위 요소 이어쓰기 (& 사용)
div {
background-color: green
&:hover { background-color: blue }
}
.div {
background-color: green
&_blue { background-color: blue }
}
- 변수 사용
$defaultSize: 20px;
$className: blue;
p {
font-size: #{$defaultSize};
&.#{$className} {color: #{$className}}
}
styled-components
- 컴포넌트에 스타일을 직접 입히는 방식
- styled-components 패키지 설치하기
yarn add styled-components
- class 이름 지을 필요 없어짐, 간단하고 직관적임
import React from 'react';
import styled from 'styled-components';
function App() {
return (
<div className="App">
<MyStyled bgColor={"red"}>hello react!</MyStyled>
</div>
);
}
const MyStyled = styled.div`
width: 50vw;
min-height: 150px;
padding: 10px;
border-radius: 15px;
color: #fff;
&:hover {
background-color: #ddd;
}
background-color: ${(props) => (props.bgColor ? "red" : "purple")};
`;
export default App;
가상돔
DOM (Document Object Model)
- HTML의 단위 하나하나를 객체로 생각하는 모델
- 트리 구조를 가짐
- 수정이 일어날 때마다 모든 DOM을 조회해서 수정할 것을 찾고 전부 수정하면 연산이 많이 일어남 → 가상돔의 필요성
가상돔 (Virtual DOM)
- 메모리 상에서 돌아가는 가짜 DOM
- 기존 DOM과 새로 그린 DOM을 비교해서 바뀐 부분만 수정
라이프 사이클
- 컴포넌트가 렌더링을 준비하는 순간 ~ 페이지에서 사라질 때까지
- 컴포넌트 생성 → 수정(업데이트) → 제거
- 생성 : 처음으로 컴포넌트를 불러오는 단계
- 수정(업데이트) : 사용자의 행동으로 데이터가 바뀌거나 부모 컴포넌트가 렌더링할 때 발생
- ex. props가 바뀔 때, state가 바뀔 때, 부모 컴포넌트가 업데이트 되었을 때 (리렌더링), 강제로 업데이트했을 때 (forceUpdate())
- 제거 : 페이지를 이동하거나 사용자의 행동으로 인해 컴포넌트가 화면에서 사라지는 단계
라이프 사이클 함수
- constuctor() : 생성자 함수, 컴포넌트가 생성되면 가장 처음 호출되는 함수
- render() : 컴포넌트의 모양을 정의하는 함수
- componentDidMount() : 첫번째 렌더링을 마친 후에 실행, 리렌더링시에는 호출되지 않음 (컴포넌트가 화면에 나타나는 것 → 마운트(Mount) 한다고 표현함)
- componentDidUpdate(prevProps, prevState, snapshot) : 리렌더링을 완료한 후 실행되는 함수, prevProps/prevState는 업데이트 전 props/state
- componentWillUnmount() : 컴포넌트가 DOM에서 제거될 때 실행하는 함수, 컴포넌트에 이벤트 리스너를 등록했다면 반드시 해제해야 함
import React from 'react';
class LifecycleEx extends React.Component {
//생성자 함수
constructor(props) {
super(props);
this.state = {
cat_name: '나비',
};
console.log('in constructor!');
}
componentDidMount() {
console.log('in componentDidMount!');
}
componentDidUpdate(prevProps, prevState) {
console.log(prevProps, prevState);
console.log('in componentDidUpdate!');
}
componentWillUnmount() {
console.log('in componentWillUnmount!');
}
render() {
return (
<div>
<h1>고양이 이름은 {this.state.cat_name}</h1>
<button onClick={this.changeCatName}>고양이 이름 바꾸기</button>
</div>
);
}
}
export default LifecycleEx;
- 라이프 사이클 함수는 클래스형 컴포넌트에서만 사용 가능함
Ref
- 리액트에서 DOM 요소를 가져올 때 사용
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
list: ['영화관 가기', '매일 책읽기', '수영 배우기']
};
this.text = React.createRef(); //ref 선언하기
}
componentDidMount() {
console.log(this.text);
console.log(this.text.current);
}
render() {
return (
<div className="App">
...
<input type="text" ref={this.text}/>
</div>
);
}
}
클래스형 컴포넌트 state 관리
- setState() : 클래스형 컴포넌트의 state를 업데이트할 때 사용하는 함수
- 네모 추가/삭제 예제
더보기
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 3,
};
}
componentDidMount() {}
addNemo = () => {
this.setState({count: this.state.count + 1});
};
removeNemo = () => {
if (this.state.count > 0) {
this.setState({count: this.state.count - 1});
} else {
window.alert('네모가 없습니다');
}
};
render() {
const nemo_count = Array.from({length: this.state.count}, (v, i) => i);
console.log(nemo_count);
return (
<div className="App">
{nemo_count.map((num, idx) => {
return (
<div
key={idx}
style={{
width: '150px',
height: '150px',
backgroundColor: '#ddd',
margin: '10px',
})
></div>
);
}}}
<div>
<button onClick={this.addNemo}>하나 추가</button>
<button onClick={this.removeNemo}하나 빼기</button>
</div>
);
}
}
export default App;
- addNemo, removeNemo에서 count 상태를 수정함
함수형 컴포넌트에서 state 관리
- 함수형 컴포넌트는 state가 없음
- 그러나 react hooks를 사용하면 state를 가질 수 있음
- useState()를 이용하여 state 관리
- 네모 추가/삭제 예제
더보기
import React from "react";
const Nemo = (props) => {
//setCount로 count라는 state 값을 수정함
const [count, setCount] = React.useState(3); //useState로 초깃값 설정
const addNemo = () => {
setCount(count + 1); //setCount로 count 1 증가
};
const removeNemo = () => {
setCount(count > 0 ? count - 1 : 0); //setCount로 count 1 감소
};
const nemo_count = Array.from({ length: count }, (v, i) => i);
return (
<div className="App">
{nemo_count.map((num, idx) => {
return (
<div
key={idx}
style={{
width: "150px",
height: "150px",
backgroundColor: "#ddd",
margin: "10px",
}}
>
nemo
</div>
);
})}
<div>
<button onClick={addNemo}>하나 추가</button>
<button onClick={removeNemo}>하나 빼기</button>
</div>
</div>
);
};
export default Nemo;
이벤트 리스너 (Event Listener)
- 사용자가 어떤 행동(이벤트)을 하는지 지켜보고 알려줌
- 마우스 클릭, 터치, 마우스 오버, 키보드 누름 등의 이벤트
- onClick처럼 엘리먼트에 직접 넣어주는 방법 or addEventListener을 통해 추가하는 방법이 있음
클래스형 컴포넌트에서 Event Listener 구독하기
- DOM 요소가 있어야 이벤트 발생하는지를 지켜볼 수 있음 → componentDidMount()에서 작성
- addEventListener() : 이벤트 등록 함수
- removeEventListener() : 이벤트 제거 함수
constructor(props) {
super(props);
this.state = {
count: 3,
};
this.div = React.createRef();
}
hoverEvent = (e) => {
console.log(e.target);
if (e.target.className === "App") {
e.target.style.background = "#eee";
}
}
componentDidMount() {
console.log(this.div);
//addEventListener로 이벤트 등록
this.div.current.addEventListener("mouseover", this.hoverEvent);
}
componentWillUnmount() {
//컴포넌트가 제거될 때 이벤트 지우기
this.div.current.removeEventListener("mouseover", this.hoverEvent);
}
return (
<div className="App" ref={this.div}>
<Nemo/>
</div>
);
'[스파르타코딩클럽] > 프론트엔드의 꽃, 리액트' 카테고리의 다른 글
프론트엔드의 꽃, 리액트 4주차 정리 (Firebase, 리액트에 Firestore 연동하기) (0) | 2021.08.19 |
---|---|
프론트엔드의 꽃, 리액트 4주차 정리 (애니메이션 keyframes) (0) | 2021.08.19 |
프론트엔드의 꽃, 리액트 3주차 정리 (리덕스, react-redux) (0) | 2021.08.06 |
프론트엔드의 꽃, 리액트 3주차 정리 (라우팅) (0) | 2021.08.06 |
프론트엔드의 꽃, 리액트 1주차 정리 (Javascript 기초, JSX, Component) (0) | 2021.07.18 |