UI를 만들기 위한 JS 라이브러리
React Native
를 이용하면 모바일 앱도 만들 수 있음.React 컴포넌트는 render()
라는 메서드를 구현하는데, 이것은 데이터를 입력받아 화면에 표시할 내용을 반환하는 역할을 함.
이 예제에서는 XML과 유사한 문법인 JSX를 사용.
컴포넌트로 전달된 데이터는 render()
안에서 this.props를 통해 접근 가능.
React를 사용하기 위해 JSX가 꼭 필요한 것은 아님. JSX를 컴파일한 JS 코드를 확인하려면 Babel REPL 이용.
예제
// JS 문법 이용
class HelloMessage extends React.Component {
render() {
return React.createElement(
"div",
null,
"Hello ",
this.props.name
);
}
}
root.render(React.createElement(HelloMessage, { name: "Taylor" }));
// JSX 문법 이용 -> 컴파일 시 JS로 변경됨
class HelloMessage extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
}
root.render(<HelloMessage name="Taylor" />);
this.props
를 이용해 입력 데이터를 다루는 것 외에도 내부적인 상태 데이터를 가질 수 있고, 이는 this.state
로 접근.render()
가 다시 호출되어 마크업이 갱신됨.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>
);
}
}
root.render(<Timer />);
props
와 state
를 사용해서 간단한 Todo App을 만들 수 있음.
이 예제에서는 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>
);
}
}
root.render(<TodoApp />);
React는 유연하며 다른 라이브러리나 프레임워크를 함께 활용할 수 있음.
이 예제에서는 외부 마크다운 라이브러리인 remarkable
을 사용해 <textarea>
의 값을 실시간을 변환
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>
);
}
}
root.render(<MarkdownEditor />);
Reference
React 공식 문서