이 포스트는 직접 React 독학을 하며, 블로그를 만들어 보자는 취지로 작성하게 되었습니다.
오류가 있거나 코드 에러가 나는 부분이 있다면, 댓글 부탁드리겠습니다.
참고 문서
React – 사용자 인터페이스를 만들기 위한 JavaScript 라이브러리
A JavaScript library for building user interfaces
ko.reactjs.org
![](https://t1.daumcdn.net/keditor/emoticon/friends1/large/010.gif)
React는 JavaScript 라이브러리이기 때문에 , 배우기 전에 사전 지식이 권장됩니다. JavaScript 언어에 대한 기본적인 이해가 필요합니다.
React는 "JSX"라는 문법을 사용합니다. "JSX"란 JavaScript를 확장한 문법입니다. 형태는 아래와 같습니다.
중괄호 내에 Javasciprt 표현식 사용 가능합니다.
const Hello = <h1>Hello, World!</h1>;
const element = <h1>Hello, {name}</h1>;
자, 우리는 지금 "Hello"라는 엘리먼트를 생성하였습니다. 엘리먼트는 화면에 표시할 내용 기술합니다.
즉, 우리는 브라우저에 렌더링 할 내용을 엘리먼트에 작성하는 것입니다.
엘리먼트는 React 앱의 가장 작은 단위
"브라우저 DOM 엘리먼트와 달리 React 엘리먼트는 일반 객체이며(plain object) 쉽게 생성할 수 있습니다
React DOM은 React 엘리먼트와 일치하도록 DOM을 업데이트합니다."
참조 : "https://ko.reactjs.org/docs/rendering-elements.html"
Q. DOM(Document Object Model)(+ 브라우저 DOM)은 무엇일까?
A. 웹 페이지(문서 : Document)에 대한 인터페이스(=객체 지향 표현)이다. 프로그래밍 언어가 접근할 수 있게 하는 API 기능또한 갖고 있다.
API (web or XML page) = DOM(Document(문서) > Element(요소)) + JS (scripting 언어)
Q. DOM 의 객체지향 표현? 구조는 어떻게 되있을까?
A. "노드 트리" 구조로 표현이 됩니다.
DOM 에 대해 윤곽이 잡히셨다면, Reactfh DOM에 엘리먼트를 렌더링하는 실습을 진행해봅시다.
우선, React는 ReactDOM.render() 함수를 통해 엘리먼트를 DOM에 전달합니다. (유일한 방법)
React 엘리먼트는 불변객체이며, UI를 업데이트하는 유일한 방법은 ReactDOM.render()로 전달하는 방법으로 그 외에방법은 없습니다.
아래 예시는 React DOCS에 나와있는 예시입니다. 아래 코드는 1초마다 Clock 함수를 호출하여, 시간값을 받아내어 브라우저 DOM에 표현하는 내용입니다.
function Clock() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(element, document.getElementById('root'));
}
setInterval(Clock, 1000); /// 1초마다, tick 함수 실행
참조 : ko.reactjs.org
Q. 그렇다면, React를 사용하여 시간 UI값을 변경할때마다 ReactDOM.render 함수가 페이지 전부를 재 리로드를 하는 것인가요?
A. 아닙니다. 위의 코드는 Clock 함수가 호출될때마다 전체 UI(const element)값을 재 랜더링하도록 되어 있지만,
실제로 React DOM은 내용이 변경된 텍스트 노드만 업데이트를 합니다.
이것이 React 를 사용하는 이유 중 하나라고 보셔도 될거 같습니다.
이번에는 React의 코어라고 할 수 있는 State and Lifecycle에 대해 알아보도록 하겠습니다. 그 전에 우리는 "컴포넌트" 라는 것에 대해 알 아야 합니다. React에 컴포넌트는 두가지 존재합니다. "함수형 컴포넌트" 와 "클래스형 컴포넌트" 입니다.
위의 코드 function Clock()은 함수형 컴포넌트라고 부릅니다. 아래 코드는 클래스형 컴포넌트라고 부릅니다.
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
코드 참조 : ko.reactjs.org
Q. 그렇다면 함수형 컴포넌트를 사용해야 하나요? 클래스형 컴포넌트를 사용해야 하나요?
A. 공식문서에서 함수형 컴포넌트와 리액트 훅(hook)을 같이 사용할 것을 권장하고 있으나, 요구되는 상황에 따라 유동적으로 선택하셔서 사용하시는 것을 권장드립니다.
위 함수에 State를 추가해 봅시다. State를 사용하는 방법은 "함수형 컴포넌트" , "클래스형 컴포넌트" 사용 방식이 조금 다릅니다.
#### 클래스 컴포넌트 State 사용방법 ####
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
#### 함수형 컴포넌트 State 사용방법 ####
function Clock() {
const [date,setDate] = setState("")
const processing = () => {
let result = new Date().toLocaleTimeString()
setDate(result)
}
useeffect(() => {processing}
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {date}.</h2>
</div>
)
}
function tick() {
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
}
setInterval(tick, 1000);
그 다음으로는 LifeCycle -> "생명주기 메서드"들을 소개해드리겠습니다. 아래 사진과 같이 4가지 단계가 존재합니다.
-. componenetDidMount() : 컴포넌트 출력물이 DOM에 렌더링 된 후에 실행
위의 코드로 따지면, Hello , world! 화면이 출력된후, {date}값이 Mount가 되는 시간대입니다.
-. componentDidUpdate() : DOM 렌더링 후, DOM 업데이트
-. componentWillUnmount() : 컴포넌트 제거를 할 때
적용된 코드는 아래와 같습니다.
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
출처 : https://ko.reactjs.org/docs/state-and-lifecycle.html
State 사용시 주의점
1. 직접 수정 X
// Wrong
this.state.comment = 'Hello';
// Correct
this.setState({comment: 'Hello'});
this.state를 지정할 수 있는 유일한 공간 : constructor
constructor(props) {
super(props);
this.state = {comment: 'Hello'};
}
2. 비동기적 특성으로 인한 오류발생
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
원인은 this.props 와 this.state가 비동기적 업데이트 되어, setState( another function(state,props) ) 형식으로 사용을 하여,
==>
3. State 업데이트 병합됩니다. --> state로 선언된 값들은 하나의 object로 병합됩니다.
4. 컴포넌트는 각각 독립적 , State 값은 컴포넌트 내부에서 각각 독립적, state 는 캡슐화(소유,설정 컴포넌트 이외 접근 불가)
function App() {
return (
<div>
<Clock />
<Clock />
<Clock />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
위의 코드를 실행해보면, Clock(시계)함수가 독립적으로 3개 실행된것을 알 수 있으며, 각각의 Clock 함수내의 State 값들도 모두 독립적인 것을 알 수 있습니다.