react.dev의 생명주기에 대한 페이지를 번역했습니다.
모든 리액트 컴포넌트는 동일한 생명주기 과정을 거친다.
Effect가 아닌 컴포넌트 기준으로 생각하는 것이 좋다. 대신 컴포넌트의 생애 주기에서 각각의 독립적인 Effect에 대해 생각하도록 해라. Effect는 외부시스템을 어떻게 현재 props/state와 연동(synchronize)시킬지를 설명한다. 당신의 코드가 바뀜에 따라 연동과정은 더 자주 일어나게 된다.
아래의 코드를 통해 지금까지의 설명을 이해해보자.다음은 chat 서버로 연결하는 컴포넌트 코드이다.
const serverUrl = 'https://localhost:1234';
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
}; // cleanup function
}, [roomId]);
// ...
}
여러분들은 본능적으로 컴포넌트가 마운팅될 때 연동을 시작하고 컴포넌트가 언마운팅할 때 연동을 멈출거라고 생각할 것이다. 하지만 그것이 끝이 아니다. 때로는 컴포넌트가 마운팅하는 동안 연동을 시작하고 멈추는 과정을 여러번 해야하는 경우도 있다.
📝 경우에 따라 Effect가 cleanup 함수를 리턴하지 않을 수도 있다. 종종 cleanup함수를 리턴해야하지만 하지 않은 경우 React는 당신이 빈 cleanup 함수를 리턴했다고 생각하고 작동한다.
왜 연동을 여러번 해야하는 일들이 생길까?
위 코드에서 ChatRoom
컴포넌트는 roomId
를 prop으로 받는다.
초기값으로 roomId
값으로 "general"
이 주어졌다고 생각해보자.
const serverUrl = 'https://localhost:1234';
function ChatRoom({ roomId /* "general" */ }) {
// ...
return <h1>Welcome to the {roomId} room!</h1>;
}
UI가 보여지고 난 후 React는 Effect를 동작시켜 연동을 시작할 것이다. "general"
room과 연결시킬 것이다.
function ChatRoom({ roomId /* "general" */ }) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId); // Connects to the "general" room
connection.connect();
return () => {
connection.disconnect(); // Disconnects from the "general" room
};
}, [roomId]);
// ...
다음으로 roomId
값으로 "travel"
이 들어왔다고 치자.
function ChatRoom({ roomId /* "travel" */ }) {
// ...
return <h1>Welcome to the {roomId} room!</h1>;
}
다음으로 어떤 일이 생길까? 사용자는 UI에 보이는 "travel"
room 이 선택됐다고 생각할 것이다. 그러나 마지막으로 동작한 Effect는 여전히 "general"
room과 연동하고 있다. roomId
prop은 변했지만 Effect는 여전히 "general"
을 연동하고 있으므로써 더 이상 현재 UI와 매칭되지 않는 것이다.
이 상황에서 당신은 React에게 2가지를 기대하게 된다.
1. 이전 roomId
인 "general"
과의 연결을 끊을 것
2. 새로운 roomId
인 "travel"
과 연결을 시작할 것
당신이 만든 Effect문에서 이미 위 2가지 사항들을 주문(어떻게 연결을 하고 cleanup 함수를 통해 어떻게 연동을 끊을 것인지)하고 있다.
이제 React가 알아야 할 것은 제대로 된 prop과 state을 가지고 정확한 순서 코드를 동작시키는 것이다.
리액트는 어떻게 Effect 코드로 재연동을 시키는 걸까?
ChatRoom
컴포넌트는 roomId
로 새로운 값("travel"
)을 받았다. 이제 React는 이 내용을 업데이트해야한다.
기존의 연동을 끊기 위해서 React는 cleanup 함수를 동작시켜서 "general"
room에 대한 로직을 return 시켜서 "general"
room과의 연동을 종료한다.
function ChatRoom({ roomId /* "general" */ }) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId); // Connects to the "general" room
connection.connect();
return () => {
connection.disconnect(); // Disconnects from the "general" room
};
// ...
그리고 React는 Effect를 동작시켜서 렌더하는 동안 새로 업데이트 된 Effect문을 동작시킨다. 이번에는 roomId
가 "travel"
로 업데이트 되었으므로 "travel"
chat room과의 연동을 시작한다. 물론 이 연동도 cleanup함수가 작동하기 전까지만 유효하다.
function ChatRoom({ roomId /* "travel" */ }) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId); // Connects to the "travel" room
connection.connect();
// ...
이로 인해 당신은 사용자가 선택한 것과 동일한 room의 UI를 띄울 수 있게 된다.