article thumbnail image
Published 2024. 7. 24. 12:39

1. State

리액트 컴포넌트의 상태를 의미함, 즉 리액트 컴포넌트의 변경 가능한 데이터

state는 자바스크립트 객체

state는 사전에 미리 정해진 것이 아니므로 컴포넌트를 개발하는 개발자가 직접 정의해서 사용함

렌더링이나 데이터 흐름에 사용되는 값만 state에 포함시켜야 함

  • 왜냐하면 state가 변경될 경우 컴포넌트가 다시 렌더링 되기 때문에 렌더링과 데이터 흐름에 관련 없는 값을 포함하면, 컴포넌트가 다시 렌더링 되어 성능을 저하 시킬 수 있기 때문
import React, { useState } from 'react';
const WrongExample = () => {
const [name, setName] = useState('나마니');
const [count, setCount] = useState(0);
const [unusedValue, setUnusedValue] = useState('이 값은 렌더링과 관계없음');
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>{name}</p>
<p>{count}</p>
<button onClick={increment}>Increase Count</button>
</div>
);
};
export default WrongExample;

unusedValuestate 에 포함되어 있지만 렌더링에 영향을 주지 않으므로 결과에 나타나지 않음.


 

결과

처음 결과

<div>
<p>나마니</p>
<p>0</p>
<button>Increase Count</button>
</div>

 

이후 Increase Count 버튼을 누르면 count 값이 1씩 증가됨 다시 렌더링이 됨

<div>
<p>나마니</p>
<p>1</p>
<button>Increase Count</button>
</div>

해당 값은 컴포넌트의 성능에 부정적인 영향을 줄 수 있으므로 불필요하게 state 에 포함시키지 말 것

 


올바른 결과

import React, { useState } from 'react';
const CorrectExample = () => {
const [name, setName] = useState('나마니');
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>{name}</p>
<p>{count}</p>
<button onClick={increment}>Increase Count</button>
</div>
);
};
export default CorrectExample;

여기서는 namecountstate로 관리하고 있고, 두 값 모두 렌더링에 사용되므로 state에 포함시키는 것이 많음

 

만약 컴포넌트에 사용되지 않는 데이터를 관리해야 한다면, 그 값을 단순한 변수로 두는 것이 좋다.
그렇게 하면 불필요한 렌더링을 피할 수 있다.

1.1. state의 특징

모든 클래스 컴포넌트에는 constructor라는 이름의 함수가 존재한다.

class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = {
liked: false
};
}
}

위 코드에서 this.state라는 부분이 나오는데 이 부분이 바로 현재 컴포넌트의 state를 정의하는 부분이다.

클래스 컴포넌트의 경우 state를 생성자에서 정의하고, 함수 컴포넌트는 stateuseState()라는 훅을 사용해서 정의한다.

state정의된 이후 직접적인 변경이 불가능하다. (setState() 함수를 통해 수정해야 함)

 


2. 생명주기

Lifecycle method, 생명주기 함수

https://soldonii.tistory.com/113

 


2.1. Mounting (출생)

https://soldonii.tistory.com/113

 

컴포넌트가 생성되는 시점, 이 과정을 Mount (마운트) 라고 한다.

이때 컴포넌트의 constructor(생성자) 가 실행된다. 생성자에서는 컴포넌트의 state를 정의하게 된다.

또한 컴포넌트가 렌더링되며 이후에 componentDidMount() 함수가 호출된다.

Rendering(렌더링): 컴포넌트의 props와 state의 상태에 기초하여 UI를 어떻게 구성할지 컴포넌트에게 요청하는 작업, 쉽게 말해 해당 컴포넌트를 다시 실행한다고 생각하면 된다.
렌더링이 발생하면 선언부에서 초기화 한 값으로 변경되고, 렌더링의 발생 조건은 컴포넌트가 가지고 있는 값이 변경될 때이다. 그래서 state를 사용해야하고, 그 외에 다른 것들은 값이 고정되어 있어야 한다.  (리액트의 순수성)
https://react.dev/learn/keeping-components-pure


렌더링이 왜 필요한가?
1. UI 상태 관리의 복잡성 해결: 전통적인 방법으로는 DOM을 직접 조작하면서 모든 변경사항을 관리해야 함
2. 가상 DOM: 가상 DOM은 실제 DOM의 가벼운 복사본으로, 상태 변화가 있을 때마다 새 가상 DOM을 생성하고 이전 가상 DOM과 비교하여 실제 DOM을 최소한으로 업데이트 한다. (참고: https://namaniflow.tistory.com/292)
3. 컴포넌트 기반 아키텍처: 리액트는 UI를 재사용 가능한 컴포넌트로 분리해서 개발할 수 있게 하는데, 각 컴포넌트는 독립적인 상태와 렌더링 로직을 갖고 있다. 때문에 변경이 필요한 부분만 업데이트 되도록 한다.
4. 데이터 흐름과 상태 관리: 리액트는 단방향 데이터 흐름을 지향한다. 즉, 상태가 변경되면 그 상태를 기반으로 컴포넌트를 다시 렌더링하여 UI를 업데이트 한다. state와 UI가 항상 일치하게 유지된다.
5. 성능 최적화: 가상 DOM을 통해 불필요한 DOM 업데이트를 피하고, 최적의 방법으로 UI 업데이트 가능하다.

 


2.2. Updating

https://soldonii.tistory.com/113

 

컴포넌트의 props가 변경되거나 setState() 함수 호출에 의해 state가 변경되거나, forceUpdate()라는 강제 업데이트 함수 호출로 인해 컴포넌트가 다시 렌더링 된다.

렌더링 이후에 componentDidUpdate() 함수가 호출 된다.


2.3. Unmount(언마운트)

https://soldonii.tistory.com/113

상위 컴포넌트에서 현재 컴포넌트를 더 이상 화면에 표시하지 않게 될 때 언마운트 된다.

언마운트 직전에 componentWillUnmount() 함수가 호출 된다.


2.3.1. 참고

1. https://velog.io/@rookieand/React-%EC%97%90%EC%84%9C-%EB%A0%8C%EB%8D%94%EB%A7%81%EC%9D%B4%EB%9E%80-%EB%8C%80%EC%B2%B4-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C - 생명주기 이미지

2. https://velog.io/@rookieand/React-%EC%97%90%EC%84%9C-%EB%A0%8C%EB%8D%94%EB%A7%81%EC%9D%B4%EB%9E%80-%EB%8C%80%EC%B2%B4-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C - 렌더링이란 무엇일까?

복사했습니다!