24년 1월 31일 강의를 들은 내용과 추가로 학습한 내용을 기록한 글입니다.
리액트
📘SPA (single Page Application)
한개의 페이지로 이루어진 애플리케이션을 의미 필요한 부분만 재렌더링해서 가져오는 방식
■ 단점
- 규모가 커지면 초기에 로딩해야하는 자바스크립트 파일, CSS 번들 파일의 용량이 증가
- 검색 엔진 최적화가 어려움
- Why? 검색 엔진 봇이 자바스크립트를 실행하지 않고, 파싱된 HTML만 대상으로 크롤링하기 때문
📘리액트
- 자바스크립트 라이브러리 중 하나
- single Page Application
- 업데이트가 있을 때 마다 전체 화면을 새로 그리지 않고, 가상 DOM을 사용해서 업데이트된 부분만 새롭게 그려줌
- JSX라는 문법을 사용
📘리액트 동작 원리
- 초기 렌더링
- 가상 DOM 변경
- 재조정
- 실제 DOM 업데이트
출처: https://mniyunsu.github.io
📘리액트 생명주기 (클래스 컴포넌트)
출처: http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
Every React component goes through the same lifecycle:
- A component mounts when it’s added to the screen.
- A component updates when it receives new props or state, usually in response to an interaction.
- A component unmounts when it’s removed from the screen.
리액트 공식문서 - 한글
- 화면에 추가될 때 마운트 (componentDidMount)
- 새로운 props나 state를 받으면 업데이트 (componentDidUpdate)
- 화면에서 제거되면 언마운트 (componentWillUnmount)
📘리액트 생명주기 (함수형 컴포넌트)
함수형 컴포넌트에서는 useEffect()
hook를 사용해서 비슷한 기능을 구현
- 의존성 배열을 통해 어떤 상태 또는 props가 변경될 때 실행시킬지를 정한다.
1
2
3
| useEffect(() => {
// 실행 코드
}, [의존성_배열]);
|
■ useEffect 예시
- 1초에 한번씩
setTime()
실행하여 현재 시각을 가져오는 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| function Time() {
const [time, setTime] = useState(getTime());
const getTime = () => {
const now = new Date();
return `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} `;
};
useEffect(() => {
const timer = setInterval(() => {
setTime(getTime());
}, 1000);
return () => clearInterval(timer);
}, []);
return <h2>{time}</h2>;
}
|
useEffect
의 의존성 배열이 비어있기 때문에 처음에 마운트 될 때만 실행- 컴포넌트가 언마운트될 때
return () => clearInterval(timer);
코드가 실행되어 타이머를 정지시킴
codepen source
■ useEffect 예시2
시작버튼을 누르면 타이머가 실행되고, 멈춤 버튼을 누르면 타이머가 종료되는 타이머
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| function Timer() {
const [running, setRunning] = useState(false);
const [timer, setTimer] = useState(0);
useEffect(() => {
let timeId;
if (running) {
timeId = setInterval(() => {
setTimer((prevTime) => prevTime + 1);
}, 1000);
}
return () => clearInterval(timeId);
}, [running]);
return (
<>
<h2>{timer}초</h2>
<button onClick={() => setRunning(true)}>시작</button>
<button onClick={() => setRunning(false)}>멈춤</button>
</>
);
}
|
useEffect
의 의존성 배열에 running이 들어있기 때문에 처음 마운트 될 때와 running의 상태가 변경될 때마다 실행됨- running이 true일 때에는
setInterval()
로직이 실행 - running이 false일 때와 컴포넌트가 언마운트 될 때
return () => clearInterval(timeId);
코드가 실행되어 타이머가 종료됨
codepen source
📘리액트 설치
1. CRA로 설치하기
1
| npx create-react-app 프로젝트이름
|
2. CRA로 설치하기 (타입스크립트)
1
| npx create-react-app 프로젝트이름 --template typescript
|
3. vite로 설치하기
① package 이름 설정
② 프레임워크 선택
③언어: javascript or typescript
📘리액트 개발서버 실행
1. CRA
2. vite
jsx 문법
- 자바스크립트의 확장 문법
- 자바스크립트 내에서 마크업 코드를 작성할 수 있게 해줌
📘규칙
1. 하나의 루트 엘리먼트로 반환하기
한 컴포넌트에 여러개 엘리먼트가 있다면, 부모 태그로 감싸서 반환하기
왜 여러 태그를 감싸야 하는가?
- HTML처럼 보이지만, 내부적으로는 자바스크립트 객체로 변환되기 때문에
- 하나의 배열로 감싸지 않으면 두개의 객체를 반환해야함
1
2
3
4
5
6
7
8
9
10
11
| <div>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</div>
|
1
2
3
4
5
6
7
8
9
10
11
| <>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</>
|
2. 모든 태그는 닫아주기
1
2
3
4
5
6
| <>
<img src="" alt="" />
<ul>
<li></li>
</ul>
</>
|
3. 캐멀 케이스로 작성하기
변수명에 대시를 포함하거나 class
와 같은 예약어를 사용할 수 없음
1
| <div className="container"></div>
|
1
2
3
| <div style=>
<p style=>글자입니다</p>
</div>
|
————- 강의 내용 정리 ————-
📘데이터바인딩
■ 데이터 바인딩?
데이터를 연결하는 프로세스
- 사용자가 내용을 동적으로 반영시키고 싶을 때 사용
- 리액트에서는 단방향 바인딩
1
2
3
4
5
6
7
8
9
10
11
12
13
| import "./App.css";
function App() {
const title = "Hello React";
return (
<>
<h1>{title}</h1>
<p>만나서 반갑습니다</p>
</>
);
}
export default App;
|
📘클래스 설정
- html에서는
class
를 사용해서 클래스 이름을 지정했지만, - react에서는
className
을 사용해서 클래스 이름을 지정
1
2
3
4
5
6
7
8
9
| function App() {
const title = "Hello React";
return (
<>
<h1 className="title">{title}</h1>
<p>만나서 반갑습니다</p>
</>
);
}
|
📘함수형 컴포넌트 - React.FC
- 함수형 컴포넌트를 정의할 때 사용하는 타입
- 해당 컴포넌트의 props를 명시적으로 지정할 때 사용
1
2
3
4
| interface MyComponentProps {
name: string;
}
const MyComponent: React.FC<MyComponentProps> = ({ name }) => {};
|
- React.FC를 사용하지 않고 props에 바로 타입을 지정해도 됨
1
2
3
4
| interface MyComponentProps {
name: string;
}
const MyComponent = ({ name }: MyComponentProps) => {};
|