Meta에서 개발한 오픈 소스 자바스크립트 라이브러리.
React는 UI 자바스크립트 라이브러리로써 싱글 페이지 애플리케이션(SPA)의 UI(User Interface)를 생성하는데 집중한 라이브러리이다.
자바스크립트에 HTML을 포함하는 JSX(JavaScript XML)이라는 간단한 문법과
단방향 데이터 바인딩(One-way Data Binding)을 사용하고 있다.
가상 돔(Virtual DOM)이라는 개념을 사용하여 웹 애플리케이션의 퍼포먼스를 최적화한 라이브러리이다.
페이지 전환 기능을 제공하지 않기 때문에, React를 사용하여 페이지 전환을 해야 한다면, react-router와 같은 추가적인 라이브러리를 사용해야 한다.
선언형으로 상호작용이 많은 UI를 만들 때 생기는 어려움을 줄여준다. React는 데이터가 변경됨에 따라 적절한 컴포넌트만 효율적으로 갱신하고 렌더링하고, 선언형 뷰는 코드를 예측 가능하고 디버그 하기 쉽게 만들어 준다.
서버에서 HTML을 생성하고 브라우저는 출력하기만 하는 전통적인 형태가 아니라,
서버가 하던 대부분의 작업을 브라우저에서 처리하는 웹 애플리케이션 개발 방법이다.
적절한 Event를 통해 데이터 흐름이 단방향으로 이루어지고(부모 -> 자식)
뷰가 바로 업데이트되지 않는다.
JavaScript에서 HTML의 문서에 접근하는 API를 뜻하는 용어로 DOM이 등장하였다.
DOM은 XML이나 HTML 문서에 접근하기 위한 일종의 인터페이스이다. 이 객체 모델은 문서 내의 모든 요소를 정의하고, 각각의 요소에 접근하는 방법을 제공한다.
오늘날 JavaScript가 가장 널리 쓰이는 분야는 클라이언트용 인터페이스이다.
이때 주로 JavaScript는 웹 브라우저에서 제공되는 DOM API를 사용하게 된다.
서버와의 데이터 통신과는 별개로 DOM을 직접적으로 조작해야 하는 기존의 웹 화면 개발 방식과 달리, React는 DOM을 직접적으로 조작하지 않고 데이터가 변화할 때 변경사항이 적용된 Virtual DOM을 만든다.
그다음 실제 DOM과 Virtual DOM의 차이점을 비교하고, 변경된 부분을 실제 DOM에 적용한다.
이 방식은 보여지는 데이터의 잦은 변경이 필요한 웹앱의 경우 성능을 크게 향상시킬 수 있다.
단, 데이터가 자주 변경되지 않는 비교적 정적인 웹 페이지에 이를 적용할 경우 오히려 성능면에서 손해를 볼 수 있다.
Javascript에 XML을 추가한 확장한 문법이다.
React에서 HTML을 표현할 때, JSX를 사용한다.
보기에는 HTML 같은 마크업 언어를 리터럴로 입력하는 것으로 보이는데, 빌드 시 Babel에 의해 자바스크립트로 변환된다.(Babel은 자바스크립트 컴파일러이다.)
자바스크립트 코드를 HTML처럼 표현할 수 있기 때문에 용이한 개발이 가능하다.
HTML과 매우 흡사하지만, XML을 기반으로 한데다 Javascript 내부에서 사용하다 보니 차이점이 몇 가지 있다.
<p class="container"></p>
위와 같이 하면 되었지만, class라는 단어가 ECMAScript6(ES6)의 클래스 문법과 겹치는 예약어이기 때문에 대신에 className이라는 단어를 사용한다.
<!-- 주석 -->
이렇게 했었지만 JSX에서는
{/*주석*/}
으로 표현한다.
<my-element>
와 같이 표기했지만 React의 Custom Element는
<MyElement />
와 같이 Pascal Case(첫 단어를 대문자로 시작하는 표기법)로 표기한다. 닫는 태그에는 꼭 명시적으로 /> 표기를 해준다.
React 컴포넌트는 render()라는 메서드를 구현하는데, 이것은 데이터를 입력받아 화면에 표시할 내용을 반환하는 역할을 한다.
class HelloMessage extends React.Component {
render() {
return (
<div>
Hello {this.props.name}
</div>
);
}
}
ReactDOM.render(
<HelloMessage name="Taylor" />,
document.getElementById('hello-example')
);
컴포넌트로 전달된 데이터는 render() 안에서 this.props를 통해 접근할 수 있다.
컴포넌트는 this.props를 이용해 입력 데이터를 다루는 것 외에도 내부적인 상태 데이터를 가질 수 있습니다. 이는 this.state로 접근할 수 있다.
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = { seconds: 0 };
}
tick() {
this.setState(state => ({
seconds: state.seconds + 1
}));
}
componentDidMount() {
this.interval = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<div>
Seconds: {this.state.seconds}
</div>
);
}
}
ReactDOM.render(
<Timer />,
document.getElementById('timer-example')
);
컴포넌트의 상태 데이터가 바뀌면 render()가 다시 호출되어 마크업이 갱신된다.
props와 state를 사용해서 간단한 Todo 애플리케이션을 만들 수 있다.
아래 코드에서는 state를 사용해 사용자가 입력한 텍스트와 할 일 목록을 관리한다.
class TodoApp extends React.Component {
constructor(props) {
super(props);
this.state = { items: [], text: '' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
render() {
return (
<div>
<h3>TODO</h3>
<TodoList items={this.state.items} />
<form onSubmit={this.handleSubmit}>
<label htmlFor="new-todo">
What needs to be done?
</label>
<input
id="new-todo"
onChange={this.handleChange}
value={this.state.text}
/>
<button>
Add #{this.state.items.length + 1}
</button>
</form>
</div>
);
}
handleChange(e) {
this.setState({ text: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
if (this.state.text.length === 0) {
return;
}
const newItem = {
text: this.state.text,
id: Date.now()
};
this.setState(state => ({
items: state.items.concat(newItem),
text: ''
}));
}
}
class TodoList extends React.Component {
render() {
return (
<ul>
{this.props.items.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
}
ReactDOM.render(
<TodoApp />,
document.getElementById('todos-example')
);
이벤트 핸들러들이 인라인으로 각각 존재하는 것처럼 보이지만,
실제로는 이벤트 위임을 통해 하나로 구현된다.
React는 유연하며 다른 라이브러리나 프레임워크를 함께 활용할 수 있다.
class MarkdownEditor extends React.Component {
constructor(props) {
super(props);
this.md = new Remarkable();
this.handleChange = this.handleChange.bind(this);
this.state = { value: 'Hello, **world**!' };
}
handleChange(e) {
this.setState({ value: e.target.value });
}
getRawMarkup() {
return { __html: this.md.render(this.state.value) };
}
render() {
return (
<div className="MarkdownEditor">
<h3>Input</h3>
<label htmlFor="markdown-content">
Enter some markdown
</label>
<textarea
id="markdown-content"
onChange={this.handleChange}
defaultValue={this.state.value}
/>
<h3>Output</h3>
<div
className="content"
dangerouslySetInnerHTML={this.getRawMarkup()}
/>
</div>
);
}
}
ReactDOM.render(
<MarkdownEditor />,
document.getElementById('markdown-example')
);
위 코드는 외부 마크다운 라이브러리인 remarkable을 사용해 <textarea>
의 값을 실시간으로 변환한다.
이렇게 React에 대하여 알아보았습니다. 감사합니다 😊