react란

react는 프론트엔드 라이브러리 중 하나이다. (다른 라이브러리로는 Angular.js, vue.js 등이 있다.)
이제까지 HTML, javascript, css등을 통해서 웹사이트를 잘 만들었는데 react와 같은 라이브러리가 왜 필요할까?
예를 들어 다음과 같은 코드가 있다고 가정해 보자.

<div id="chats">
    <ul class="chatBoard">
        <li class="name">Tom</li>
        <li class="message">Hi!</li>
    </ul>
    <ul class="chatBoard">
        <li id="name">Kelly</li>
        <li class="message">Hello</li>
    </ul>
    <ul class="chatBoard">
        <li id="name">Amy</li>
        <li class="message">Example</li>
    </ul>
</div>

여기에 자바스크립트로 이벤트를 추가하려면 각 DOM 엘리먼트에 대한 레퍼런스를 찾고, 해당 DOM에 접근해서 작업을 해야한다.
하지만 리액트는 훨씬 간편하게 코드를 짤 수 있다.

Component 만들어보기

다음은 ES6문법 및 JSX로 작성된 단순한 React Component이다.

const Chat = () => (
  <li>Tom</li>
);

위 함수로 JSX를 반환하는 React Component를 생성했으니 랜더링을 해야한다. 랜더링은 ReactDOM.render(, <그릴 실제="" DOM="" element="">)와 같은 구조로 작성된다. 다음과 같이 id가 chats인 div에 랜더링한다.

import React from 'react';
import ReactDOM from 'react-dom';

const Chat = () => (
  <li>Tom</li>
);

ReactDOM.render(<App />, document.getElementById="chats");

위 코드는 chats안에 <li>Tom</li>이라는 요소를 하나 생성한다. 이번에는 Chat을 감싸는 ChatBoard를 만들어 보자.

const Chat = () => (
  <li>Tom</li>
);

const ChatBoard = () => (
  <ul>
    <Chat />
  </ul>
);

ReactDOM.render(<SuperWorld />, document.getElementById("root"));

위 코드는 실행하면 chats안에 <ul><li>Tom</li></ul>이라는 요소를 생성한다.
여기까지 만든 코드는 li내부에 직접 값을 넣어주었지만 데이터를 받아와서 넣어야 할 때는 어떻게 해야할까? 다음과 같이 코드를 작성해보자.

const ChatListItem = (props) => (
    <ul>
        <li>{props.chat[0].name}</li>
        <li>{props.chat[0].message}</li>
    </ul>
    <ul>
        <li>{props.chat[1].name}</li>
        <li>{props.chat[1].message}</li>
    </ul>
    <ul>
        <li>{props.chat[2].name}</li>
        <li>{props.chat[2].message}</li>
    </ul>

)

const App = () => (
    <ChatList chats={[
        {name: 'Tom', message: 'Hi!'},
        {name: 'Kelly', message: 'Hello'},
        {name: 'Amy', message: 'Example'}
    ]} />
);

App의 ChatList에서 chats이라는 props를 만들고 그 안에 배열을 집어넣었다. 이것을 ChatListItem함수에서 props로 받아와서 중괄호안에 사용을 했다.
여기서 props 는 부모 컴포넌트가 자식 컴포넌트에게 주는 값이다. 자식 컴포넌트에서는 props 를 받아오기만하고, 받아온 props 를 직접 수정 할 수 는 없다.

반면에 state는 컴포넌트 내부에서 선언하며 내부에서 값을 변경 할 수 있다. 그래서 컴포넌트들의 상호작용 구현할 때 사용한다. 다음 코드를 보자.

import React from 'react';
import ReactDOM from 'react-dom';

class ChatListItem extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            done: false
        }
    }
    onListItemClick() {
        // 기존의 state를 this.setState을 통해 바꿀 수 있습니다.
        this.setState({
        done: !this.state.done
        });
    }
    render() {
        const style = {
            textDecoration: this.state.done ? 'line-through' : 'none'
        };

        return (
            <ul>
                <li style={style} onClick={this.onListItemClick.bind(this)}>{this.props.chat.name}</li>
                <li style={style} onClick={this.onListItemClick.bind(this)}>{this.props.chat.message}</li>
            </ul>
        );
    }
}

const ChatList = (props) => (
    <Fragment>
        {props.chats.map(chat =>
            <ChatListItem chat={chat}/>
        )}
    </Fragment>
);

const App = () => (
    <ChatList chats={[
        {name: 'Tom', message: 'Hi!'},
        {name: 'Kelly', message: 'Hello'},
        {name: 'Amy', message: 'Example'}
    ]} />
);

ReactDOM.render(<App />, document.getElementById="chats");

li의 name, message를 클릭했을 때 onClick이벤트를 이용하여 state의 상태를 바꿔서 style을 바꾼다. 이와 같이 이벤트 처리를 할 때 보통 state를 사용한다.