안녕하세요
createElemet함수에 대해 알아보고, 리액트의 요소들에 대해 알아보겠습니다.
JSX문법으로 작성한 코드는 바벨 플러그인이 리액트의 createElement함수로 변경해줍니다.
React는 가상돔을 이용하며, 실제 돔과 비교해 변경된 부분만 실제 돔에 반영한다.라는 말을 많이 들어봤습니다.
create-react-app을 이용해 컴포넌트를 작성해보겠습니다.
import React from 'react'
export default class Timer extends React.Component {
constructor (props) {
super(props);
this.state = {
seconds:0
}
}
componentDidMount () {
this.timerID = setInterval(()=>this.update(),1000)
}
componentWillUnmount() {
clearInterval(this.timerID)
}
update() {
const newSeconds = this.state.seconds + 1;
this.setState({seconds : newSeconds})
}
render() {
return (
<div>
<h1>지금까지 {this.state.seconds}초 가 지났습니다.</h1>
</div>
)
}
}
1초마다 컴포넌트를 업데이트하는 타이머입니다.
setInterval함수에서 this바인딩을 생성하지 않도록 화살표 함수를 이용해주세요
1초마다 update함수를 호출하는데
react돔 요소중 업데이트 부분은 seconds변수로 표현된 부분 뿐입니다.
리액트에서 데이터 변경에 의한 업데이트는 render phase 와 commit phase로 나뉩니다.
리액트는 렌더링 할 때마다 가상돔을 만들고 이전의 가상돔과 비교합니다.
정확히 어떤 요소들을 비교하는지 알아보겠습니다.
리액트의 요소를 보겠습니다.
{
type : 'a',
key : 'key1',
ref : 'null',
props : {
href : 'http://google.com',
style : {
width:100,
},
children : 'click here'
},
...
}
type이 문자열일 경우 HTML태그가 됩니다. type이 함수이면 작성된 컴포넌트 입니다.
key는 요소를 식별하는 값입니다. 동일한 컴포넌트 들이 있을경우 식별할 수있습니다.
ref속성을 입력하지 않으면 null입니다.
children은 내용인데 중첩된 요소의 경우, children에 요소가 들어갑니다.
** 이런 각각의 속성들을 비교합니다. 그리고 요소들은 불변객체입니다. **
가상 DOM은 리액트 요소의 트리(tree)입니다.
먼저 root컴포넌트(가장상위)의 리액트 요소들을 읽습니다. 그리고 컴포넌트가 중첩된 구조일 경우 요소의 type이 함수가 됩니다.
모든 요소의 type이 문자열이 될 때 까지 render함수를 호출합니다.
모든 type속성이 문자열이여야 HTML로 변환할 수 있습니다.
이런 과정을 거쳐 리액트 요소의 트리가 완성된 것이 가상 DOM입니다.
최초 과정을 거친 가상DOM은 화면을 업데이트할 때 가상돔과 현재의 가상돔을 비교해서 변경된 부분만 실제 돔에 반영합니다.
최초의 render단계는 ReactDOM.render에 의해 수행되고,
그리고, 이후의 render단계는 setState가 수행하는데, 비교해서 필요한 부분만 업데이트 하게됩니다.
리액트 버전 16부터는 파이버라는 구조체로 변환됩니다.
하지만, 모든 type속성값이 문자열이 될 때까지 연산한다는 사실은 같습니다.
다음 포스팅에서는 생명주기에대해 정리해보겠습니다.