constructor가 생성자이다. 내부에this.state라는 부분은 현재 컴포넌트의state를 나타낸다. (클래스 컴포넌트의 경우 위와 같이 생성자에state를 정의한다.)

개발자가 의도 한대로 동작 하지 않을 수 있다. (setState 라는 함수를 사용해야한다.)

- Mounting : 생성자가 실행, 컴포넌트의
State를 정의한다.
또한 컴포넌트가 렌더링 되며 이후에componentDidMount함수가 호출됨
- Updating : 여러번 렌더링 되는 과정, 컴포넌트의
props가 변경되거나setState함수 호출에 의해state가 변경되거나,forceUpdate라는 강제 업데이트 함수 호출로 인해 컴포넌트가 다시 렌더링 된다.
이후componentDidUpdate함수가 호출된다.
- Unmounting : 컴포넌트가 사라지는 시점
componentWillUnmount함수가 호출
=> 그러면 Unmount 되는 시점은 ? : 상위 컴포넌트에서 현재 컴포넌트를 더 이상 화면에 표시하지 않게 될때Unmount되나고 볼 수 있다. 해당 시점 전에 위 함수가 호출되는 것이다.
초록 부분 : 생명 주기에 따라 호출 되는 클래스 컴포넌트의 함수
(라이프 사이클 메소드 : 생명 주기 함수)
위 생명주기 3개 함수 외에도 다른 생명주기 함수가 존재하지만 지금은 클래스 컴포넌트를 거의 사용하지 않는다. (요즘은 함수형 컴포넌트 사용)
1) Notification.jsx
import React from "react";
const styles = {
wrapper : {
margin : 8,
padding : 8,
display: "flex",
flexDirection: "row",
border : "1px solid grey",
borderRadius : 18,
},
messageText : {
color : "black",
fontSize : 16,
},
};
class Notification extends React.Component{
constructor(props){
super(props);
this.state = {};
}
render(){
return(
<div style={styles.wrapper}>
<span style={styles.messageText}>{this.props.message}</span>
</div>
)
}
}
export default Notification;
위와 같이 Notification.jsx 를 생성함, 여기서는 상태 관리가 필요 없다. 그래서 비워둠
2) NotificationList.jsx
import React from "react";
import Notification from "./Notification";
const reservedNotifications = [
{
message: "안녕하세요 123",
},
{
message: "안녕하세요 456",
},
{
message: "안녕하세요 789",
},
];
var timer;
class NotificationList extends React.Component {
constructor(props) {
super(props);
this.state = {
notifications: [],
};
}
componentDidMount(){
const {notifications} = this.state;
timer = setInterval (()=>{
if(notifications.length < reservedNotifications.length){
const index = notifications.length;
notifications.push(reservedNotifications[index]);
this.setState({
notifications : notifications, // notifications 배열이 업데이트 된다. (1초마다)
});
}
else{
clearInterval(timer); // 다 수행하면 타이머 종료
}
},1000); // 1초마다 정해진 작업 수행
}
render(){
return(
<div>
{this.state.notifications.map((notification)=>{
return <Notification message={notification.message}/>
})}
</div>
)
}
}
export default NotificationList;
클래스 컴포넌트임과 동시에 state 를 가지는 컴포넌트 설정이다.
조건에 맞게this.state에 배열을 넣고 해당 배열을 넣어가면서setState함수를 이용하여 1초마다 업데이트 하고 있다.componentDidMount함수를 이용하고 있다.
3) index.js
import NotificationList from './ch06/NotificationList';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<NotificationList/>
</React.StrictMode>
)
(일부 코드 생략) : 위처럼 index.js 에서 실행한다.
이때React.StrictMode의 변경으로 인해서 위 경우는 1초에 2개씩 나타난다.
=> 따라서 React.StrictMode를 빼고 아래와같이 쓰면 1개씩 나타나게 된다.
import NotificationList from './ch06/NotificationList';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
// 이부분을 삭제함
<NotificationList/>
)

(최종적으로는 위와같이 지정해준 값이 모두 출력된다. [밑에 3개는 따로 추가함])

=> 컴포넌트는 위와 같이 클래스 컴포넌트, 함수 컴포넌트 의 두 종류가 있다.

=> Hooks 이 있기 전에는 함수형 컴포넌트에서는 state와 lifecycle 기능을 구현하지 못했지만 Hooks 이 등장하면서 클래스 컴포넌트의 기능을 모두 구현 가능하다.

=> Hooks(갈고리) 라는 말 답게 기능마다 갈고리를 걸어 원하는 시점에 함수가 실행되도록 한 것이다. 그리고 이때 실행되는 함수를 hook 이라고 부르기로 정함. (use.. 로 시작하는 함수들)
=> 함수 컴포넌트에서 사용하지 않는 state를 사용하기 위한 훅

Counter 라는 함수 컴포넌트의 예시, 위 코드의 경우는 버튼을 클릭 시 변수 값은 변하지만 재렌더링이 일어나지 않아서 새로운 카운트 값이 화면에 표시되지 않는다.

useState 함수의 리턴값은 위와 같이 [변수명, set함수명] 이 존재한다.

=> 이전의 코드에서 useState를 사용하여 상태가 업데이트 되도록 변경한 코드, 컴포넌트가 재렌더링되는 과정과 동일 (초기 값 : 0)
클래스 컴포넌트에서는 모든 state 값을
setState값을 이용해서 업데이트
함수 컴포넌트에서는 변수 각각에 대해set함수가 따로 존재한다.
=> Side effect를 수행하기 위한 훅 (리액트에서는 부작용이 아니다.)
(그냥 effect (영향) 라고 봐도 무방하다.)
side effect : 서버에서 데이터를 받아오거나 수동으로 DOM 을 변경하는 등의 작업을 의미한다.
(이 작업들이 다른 컴포넌트에 영향을 미칠 수 있으며, 렌더링 중에는 작업이 완료될 수 없기 때문) -> 약간 부수적인 작업 느낌

=> 위 기능 (생명주기 함수) 들을 하나로 통합해서 제공하는 것이 useEffect() 이다.

의존성 배열은 이 이펙트가 의존하고 있는 배열로서 내부의 변수 중에 하나라도 값이 변경 되면 이펙트 함수가 실행된다.
=> 이펙트 함수는 처음 컴포넌트가 렌더링 된 이후와 업데이트로 인한 재렌더링 이후에 실행된다. 아래와 같이 mount, unmount 시에 한번만 실행되게 하려면 빈 배열을 넣으면 됨

해당 이펙트가 props 나 state 에 있는 어떤 값에도 의존하지 않는 것이 된다. (여러번 실행되지 않는다.)

생략 시에는 컴포넌트 업데이트 때마다 호출 됨
예시코드 (useEffect 사용 추가)

클래스에서 사용하던 생명주기 함수의 기능을 동일하게 수행하도록 함
(브라우저의 탭을 업데이트 하도록 함)
의존성 배열이 없으므로 새로고침마다 호출
결과적으로componentDidMount, componentDidUpdate와 동일 역할
또한 해당 함수 컴포넌트의propsstate에 접근 가능
componentWillUnmount 를 useEffect로 구현해보기

위 강조된 부분은 unmount 될 때 호출됨 즉
return문이componentWillUnmount의 역할을 한다.

이처럼 두개의 useEffect, useState 훅을 사용할 수 있다.
useEffect(() => {
fetchUser(userId).then((data) => setUser(data));
// 마운트 시 실행
return () =>{
// 언마운트 시 실행
}
}, [userId]);
userId가 변경 될때만 fetchUser 함수가 호출된다.
업데이트 시에 즉언마운트가 실행 되고 다시마운트가 실행됨
return 문은 언마운트 실행 시 추가 동작 설명

=> 추가적으로 useMemo(), useCallback(), useRef() 그리고 custom Hook 까지 다양한 것이 있지만 그건 다음 아티클에서 알아보자 (중요하고 여려운 내용이라 보충이 필요할 듯)