일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 개발공부
- react 기초
- context switching
- 알고리즘
- Operating System
- 컴퓨터공학
- node.js
- Python
- 비동기
- codestates
- Zerobase
- 자바
- python algorithm
- 파이썬 알고리즘 인터뷰
- 자바스크립트
- 코드스테이츠
- execution context
- 프로그래머스
- OS
- 운영체제
- Computer Science
- REACT
- useState
- 글또
- java
- 파이썬
- JavaScript
- typeScript
- algorithm
- 자료구조
Archives
- Today
- Total
Back to the Basics
[React] React-State and Lifecycle 본문
728x90
이 포스트는 React 공식문서를 참고하여 작성하였습니다.
State 란?
- state는 component 내에서 변할 수 있는 값이다.
예를 들어, 쇼핑몰에서 제품을 선택하는 체크박스를 예로 들 수 있다. 여기서 상태는 체크박스를 checked 상태와 uncheck 한 상태로 볼 수 있다. - state는 local 또는 캡슐화라고도 불리며 **state가 소유하고 설정한 component 이외의 component도 접근할 수 없다.
- 부모 -> 자식 의 하향식 (단방향식 이라고도 불림)의 데이터 흐름만 가능하다 : 어떤 하나의 component는 자식 component의 props로 그것의 state를 넘겨줄 수 있다.
- state는 특정한 component에 의해 소유되며 , 이 state로부터 파생된 데이터 또는 UI 등은 Tree 구조에서 아래에 있는 component에만 영향을 미칠 수 있다
Porps Vs State
- state는 데이터를 갖는 객체의 형태라는 점에서 props와 비슷하지만, private이며 전적으로 component에 의해 제어된다.
- props는 함수 매개변수처럼 copmpoent에 전달되는 반면 state는 함수 내에 선언된 변수처럼 component 안에서 관리된다.
위의 설명 만으로는 이해하기 어렵다. 위의 공식문서에서 설명한 코드를 빌려 하나하나 살펴보자.
class Clock extends React.Component {
// 클래스 생성자 (class constructor)를 넣는다.
constructor(props) {
super(props);
this.state = {date: new Date()};
}
// Lufe Cycle (생면주기 메서트)를 추가한다
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
// setState()를 호출하여 component의 state객체에 대한 업데이트를 실행한다.
tick() {
this.setState({
date: new Date()
});
}
// state를 랜더링한다. 화면에 표시되어야 할 내용들.
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
위의 코드의 Clock 은 class형 component이며, 현재 시간 설정하고 1초마다 시간을 업데이트를 스스로 하는 component이다.
위 코드의 실행 순서를 먼저 보면 아래와 같다.
- React.render 에서 이 전달되었으므로 React는 Clock의 생성자(constructor)를 호출한다.
--> 현재 시각이 포함된 객체로 this.state를 초기화한다. - React는 Clock component의 render() 메서드를 호출하고 DOM을 업데이트한다.
- React는 생명주기 메서드인 componentDidMount()를 호출한다. 이 메서드는 매 초마다 component의 tick() 메서드를 호출한다.
- 매초 브라우저는 tick()을 호출하고 이 메서드(tick())은 steState()에 현재 시각을 포함하는 객체를 호출하면서 UI를 업데이트한다.
--> 이때 render() 안의 this.state.date가 달라지고 DOM은 업데이트된다. - Clock component가 DOM으로부터 한 번이라도 삭제된 적이 있다면 componentWillCunmount() 생명주기 메서드를 호출한다.
이제 각 순서와 코드를 같이 보면서 아래의 개념들을 알아보자.
Contructor (생성자)와 super(props)
constructor(props){
super(props);
this.state={date:new Date()};
}
초기의 this.state를 지정하는 클래스 생성자를 추가한다. 이 생성자에 의해서 현재의 시각을 포함하는 객체로 this.state를 초기화하고 Clock은 현재 시각을 표시할 수 있게 된다.
super란??
- super는 JavaScript에서 부모 class 생성자를 참조하는 키워드이다.
- 자바스크립트는 클래스 생성자에서 super 호출 전에 this를 사용하지 못한다는 언어적 제약사항이 있다.
그 이유와 super(props)에 대한 상세 설명을 이 포스트를 참고하자 Why Do We Write super(props)?
super의 인자로 props를 넣는 이유는?
- React Component 객체가 생성될 때 props 속성을 초기화하기 위해 부모 component에 props를 전달한다.
- super()에 인자로 props를 넣지 않아도 Reac는 생성사 호출 이후에 prop속성을 setting 해주기 때문에 실수로 빠뜨려도 정상적으로 동작은 된다. 하지만 super()만 실행하는 경우 생성자가 호출되고 끝나기 전까지 this.props === undefined 이기 때문에 내부에서 this.props의 사용은 불가능하다. 그렇기 때문에 super(props)로 호출하는 것이 바람직하다고 한다..!
Life Cycle (생명주기)
// mount lifecycle
componentDidMount(){
this.timerID=sterInterval(()=>this.tick(), 1000));
}
// unmount lifecycle
componentwillUnmount(){
clearInterval(this.timerID);
}
- 위의 코드는 Clock이 처음 DOM에 렌더링이 될 때마다 타이머를 설정하는 코드와 Clock에 의해 생성된 DOM이 삭제될 때마다 타이머를 해제하는 코드이다. 전자는 Mounting이라고 하고 후자는 Unmounting이라고 한다. 이와 같은 메서드를 Lifecycle methode(생명주기 메서드)라고 한다.
- componentDiMount()는 component 출력이 DOM에 렌더링 된 후에 실행이 된다.
- 코드에서 this.timerID같이 데이터 flow 안에는 포함되지 않는 어떠한 것을 저장해야 할 때 클래스에 부가적인 필드를 추가해도 된다.
- ( 왜 그런가 생각을 해보니, 부모 클래스를 상속받은 것이고, 자식 클래스는 상속받은 부모 클래스에 추가적으로 더 만들기가 가능하기 때문.. 인가?)
- MDN문서에 의하면 setInterval()은 설정한 time delay로 함수 또는 코드 snippet을 반복적으로 호출한다.
- interval을 고유하게 식별하는 interval ID를 반환하고 이 ID로 clearInterval()를 호출하여 제거할 수 있다.
- 위의 코드에서 setInterval(()=> this.tick(),1000))은 1초마다 tick()을 반복적으로 호출한다.
- 위에서 설명했듯이, clearIntercal(intercalID) method는 호출된 setInterval을 제거한다.
- return value : undefined
setState()
tick() {
this.setState({
date: new Date()
{);
}
- setState(updater, [calback])
- setState()는 Event handler, server response로 인한 UI 업데이트를 하기 위해 사용한다.
- Component의 state 변화를 대기열에 추가하고 React에 re-rendering을 하도록 알려준다.
- 위의 코드는 component의 state 객체에 대한 업데이트를 실행한다. 현재 시각과 함께 setStater가 호출되면 React는 state가 변했음을 인지한다.
- local state를 업데이트하기 위해 setState()를 사용한다.
Note!!!
- State를 직접적으로 수정하면 안 된다.
- this.state.comment="Wrong"; // Wrong!!!
- this.setState({comment:"Goooooood"}); // Correct!!
- this.satte에 직접 할당할 수 있는 곳은 constructor이다.
- state update는 비동기적일 수 있다.
- this.state와 this.props는 비동기적으로 업데이트가 될 수 있다.
this.setState({
counter: this.state.counter + this.props.increment,
});
위의 코드와 같이 작성하게 되면 아마 업데이트에 실패할 수도 있다.( this.state 와 props의 업데이트가 동기적으로만 일어나는 것이 아니기 때문에)
이를 수정하려면 아래와 같이 코드를 작성한다
this.setState((state,props)=>({
counter:state.counter+props.increment
}));
위의 코드는 객체가 아닌 함수를 인자로 사용하였다. 첫 번째 인자는 이전의 state이고 두 번째 인자는 업데이트가 적용된 시점의 props이다.
State updates are Merged
setState()를 call 할 때 React는 제공한 객체를 current state로 병합한다.
constructor(props){
super(props);
this.state={
title:[],
introcuce:[]
};
}
componentDidMount() {
fetchTitle().then(response => {
this.setState({
title: response.title
});
});
fetchintro().then(response => {
this.setState({
introduce: response.introduce
});
});
}
병합은 shallow(얕게) 이루어지기 때문에 this.setState({title})은 thie.state.introduce에 영향을 주지 않지만 this.state.title은 완전히 대체된다.
728x90
'Frontend Development > React' 카테고리의 다른 글
[React][Codestates]- React Twittler Intro - Advanced (0) | 2021.08.19 |
---|---|
[React][Codestates] React SPA & Router (0) | 2021.08.12 |
[React] React-Components and Props (0) | 2021.08.09 |
[React][Codestates] React 기초 II (0) | 2021.08.07 |
[React] React 기초 I (0) | 2021.08.07 |
Comments