React JS
๋ฆฌ์กํธ๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์
๋๋ค.
๋ฆฌ์กํธ ํน์ง
1. ์ ์ธํ
React๋ ์ํธ์์ฉ์ด ๋ง์ UI๋ฅผ ๋ง๋ค ๋ ์๊ธฐ๋ ์ด๋ ค์์ ์ค์ฌ์ค๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ ๊ฐ ์ํ์ ๋ํ ๊ฐ๋จํ ๋ทฐ๋ง ์ค๊ณํ์ธ์. ๊ทธ๋ผ React๋ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋จ์ ๋ฐ๋ผ ์ ์ ํ ์ปดํฌ๋ํธ๋ง ํจ์จ์ ์ผ๋ก ๊ฐฑ์ ํ๊ณ ๋ ๋๋งํฉ๋๋ค.
์ ์ธํ ๋ทฐ๋ ์ฝ๋๋ฅผ ์์ธก ๊ฐ๋ฅํ๊ณ ๋๋ฒ๊ทธํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค์ด ์ค๋๋ค.
ย
2. ์ปดํฌ๋ํธ ๊ธฐ๋ฐ
์ค์ค๋ก ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ์บก์ํ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋์ธ์. ๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ์กฐํฉํด ๋ณต์กํ UI๋ฅผ ๋ง๋ค์ด๋ณด์ธ์.
์ปดํฌ๋ํธ ๋ก์ง์ ํ
ํ๋ฆฟ์ด ์๋ JavaScript๋ก ์์ฑ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๋ค์ํ ํ์์ ๋ฐ์ดํฐ๋ฅผ ์ฑ ์์์ ์์ฝ๊ฒ ์ ๋ฌํ ์ ์๊ณ , DOM๊ณผ๋ ๋ณ๊ฐ๋ก ์ํ๋ฅผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
ย
3. ์ด๋์๋ ์ฌ์ฉ๊ฐ๋ฅ
๊ธฐ์ ์คํ์ ๋๋จธ์ง ๋ถ๋ถ์๋ ๊ด์ฌํ์ง ์๊ธฐ ๋๋ฌธ์, ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ค์ ์์ฑํ์ง ์๊ณ ๋ React์ ์๋ก์ด ๊ธฐ๋ฅ์ ์ด์ฉํด ๊ฐ๋ฐํ ์ ์์ต๋๋ค.
React๋ Node ์๋ฒ์์ ๋ ๋๋ง์ ํ ์๋ ์๊ณ ,ย React Native๋ฅผ ์ด์ฉํ๋ฉด ๋ชจ๋ฐ์ผ ์ฑ๋ ๋ง๋ค ์ ์์ต๋๋ค.
ย
ย
์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ
1. ๊ฐ๋จํ ์ปดํฌ๋ํธ
React ์ปดํฌ๋ํธ๋ย
render()
๋ผ๋ ๋ฉ์๋๋ฅผ ๊ตฌํํ๋๋ฐ, ์ด๊ฒ์ ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅ๋ฐ์ ํ๋ฉด์ ํ์ํ ๋ด์ฉ์ ๋ฐํํ๋ ์ญํ ์ ํฉ๋๋ค. ์ด ์์ ์์๋ XML๊ณผ ์ ์ฌํ ๋ฌธ๋ฒ์ธ JSX๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ปดํฌ๋ํธ๋ก ์ ๋ฌ๋ ๋ฐ์ดํฐ๋ย render()
ย ์์์ย this.props
๋ฅผ ํตํด ์ ๊ทผํ ์ ์์ต๋๋ค.React๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ JSX๊ฐ ๊ผญ ํ์ํ ๊ฒ์ ์๋๋๋ค.ย JSX๋ฅผ ์ปดํ์ผํ JavaScript ์ฝ๋๋ฅผ ํ์ธํ๋ ค๋ฉดย Babel REPL์ ์ด์ฉํด๋ณด์ธ์.
ย
class HelloMessage extends React.Component {
render() {
return (
<div>
Hello {this.props.name}
</div>
);
}
}
ReactDOM.render(
<HelloMessage name="Taylor" />,
document.getElementById('hello-example')
);
ย
2. ์ํ๋ฅผ ๊ฐ์ง๋ ์ปดํฌ๋ํธ
์ปดํฌ๋ํธ๋ย
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);
}
ย
3. React Todo App
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')
);
ย
4. ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ ์ปดํฌ๋ํธ
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')
);