mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
1073 lines
100 KiB
HTML
1073 lines
100 KiB
HTML
<!DOCTYPE html>
|
|
<!--[if IE]><![endif]-->
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
<title>튜토리얼 | React</title>
|
|
<meta name="viewport" content="width=device-width">
|
|
<meta property="og:title" content="튜토리얼 | React">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:url" content="https://facebook.github.io/react/docs/tutorial-ko-KR.html">
|
|
<meta property="og:image" content="https://facebook.github.io/react/img/logo_og.png">
|
|
<meta property="og:description" content="A JavaScript library for building user interfaces">
|
|
<meta property="fb:app_id" content="623268441017527">
|
|
|
|
<link rel="shortcut icon" href="/react/favicon.ico">
|
|
<link rel="alternate" type="application/rss+xml" title="React" href="https://facebook.github.io/react/feed.xml">
|
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css" />
|
|
<link rel="stylesheet" href="/react/css/syntax.css">
|
|
<link rel="stylesheet" href="/react/css/codemirror.css">
|
|
<link rel="stylesheet" href="/react/css/react.css">
|
|
|
|
<script src="//use.typekit.net/vqa1hcx.js"></script>
|
|
<script>try{Typekit.load();}catch(e){}</script>
|
|
|
|
<!--[if lte IE 8]>
|
|
<script src="/react/js/html5shiv.min.js"></script>
|
|
<script src="/react/js/es5-shim.min.js"></script>
|
|
<script src="/react/js/es5-sham.min.js"></script>
|
|
<![endif]-->
|
|
<script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script>
|
|
<script src="/react/js/codemirror.js"></script>
|
|
<script src="/react/js/javascript.js"></script>
|
|
<script src="/react/js/react.js"></script>
|
|
<script src="/react/js/react-dom.js"></script>
|
|
<script src="/react/js/babel-browser.min.js"></script>
|
|
<script src="/react/js/live_editor.js"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="container">
|
|
|
|
<div class="nav-main">
|
|
<div class="wrap">
|
|
<a class="nav-home" href="/react/index.html">
|
|
<img class="nav-logo" src="/react/img/logo.svg" width="36" height="36">
|
|
React
|
|
</a>
|
|
<ul class="nav-site nav-site-internal">
|
|
<li><a href="/react/docs/getting-started.html" class="active">Docs</a></li>
|
|
<li><a href="/react/support.html">Support</a></li>
|
|
<li><a href="/react/downloads.html">Download</a></li>
|
|
<li><a href="/react/blog/">Blog</a></li>
|
|
<li>
|
|
<input id="algolia-doc-search" type="text" placeholder="Search docs..." />
|
|
</li>
|
|
</ul>
|
|
|
|
<ul class="nav-site nav-site-external">
|
|
<li><a href="https://github.com/facebook/react">GitHub</a></li>
|
|
<li><a href="https://facebook.github.io/react-native/">React Native</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<section class="content wrap documentationContent">
|
|
<div class="nav-docs">
|
|
<!-- Docs Nav -->
|
|
|
|
<div class="nav-docs-section">
|
|
<h3>Quick Start</h3>
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="/react/docs/getting-started.html">Getting Started</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/tutorial.html">Tutorial</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/thinking-in-react.html">Thinking in React</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="nav-docs-section">
|
|
<h3>Community Resources</h3>
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="/react/docs/conferences.html">Conferences</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/videos.html">Videos</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="https://github.com/facebook/react/wiki/Complementary-Tools" class="external">Complementary Tools</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="https://github.com/facebook/react/wiki/Examples" class="external">Examples</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="nav-docs-section">
|
|
<h3>Guides</h3>
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="/react/docs/why-react.html">Why React?</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/displaying-data.html">Displaying Data</a>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="/react/docs/jsx-in-depth.html">JSX in Depth</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/jsx-spread.html">JSX Spread Attributes</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/jsx-gotchas.html">JSX Gotchas</a>
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/interactivity-and-dynamic-uis.html">Interactivity and Dynamic UIs</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/multiple-components.html">Multiple Components</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/reusable-components.html">Reusable Components</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/transferring-props.html">Transferring Props</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/forms.html">Forms</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/working-with-the-browser.html">Working With the Browser</a>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="/react/docs/more-about-refs.html">Refs to Components</a>
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/tooling-integration.html">Tooling Integration</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/addons.html">Add-Ons</a>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="/react/docs/animation.html">Animation</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/two-way-binding-helpers.html">Two-Way Binding Helpers</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/test-utils.html">Test Utilities</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/clone-with-props.html">Cloning Elements</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/create-fragment.html">Keyed Fragments</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/update.html">Immutability Helpers</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/pure-render-mixin.html">PureRenderMixin</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/perf.html">Performance Tools</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/shallow-compare.html">Shallow Compare</a>
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/advanced-performance.html">Advanced Performance</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/context.html">Context</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="nav-docs-section">
|
|
<h3>Reference</h3>
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="/react/docs/top-level-api.html">Top-Level API</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/component-api.html">Component API</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/component-specs.html">Component Specs and Lifecycle</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/tags-and-attributes.html">Supported Tags and Attributes</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/events.html">Event System</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/dom-differences.html">DOM Differences</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/special-non-dom-attributes.html">Special Non-DOM Attributes</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/reconciliation.html">Reconciliation</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/webcomponents.html">Web Components</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/docs/glossary.html">React (Virtual) DOM Terminology</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="nav-docs-section">
|
|
<h3>Flux</h3>
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="https://facebook.github.io/flux/docs/overview.html" class="external">Flux Overview</a>
|
|
|
|
</li>
|
|
|
|
<li>
|
|
<a href="https://facebook.github.io/flux/docs/todo-list.html" class="external">Flux TodoMVC Tutorial</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
<!-- Tips Nav -->
|
|
|
|
<div class="nav-docs-section">
|
|
<h3>Tips</h3>
|
|
<ul>
|
|
|
|
<li>
|
|
<a href="/react/tips/introduction.html">Introduction</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/inline-styles.html">Inline Styles</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/if-else-in-JSX.html">If-Else in JSX</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/self-closing-tag.html">Self-Closing Tag</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/maximum-number-of-jsx-root-nodes.html">Maximum Number of JSX Root Nodes</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/style-props-value-px.html">Shorthand for Specifying Pixel Values in style props</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/children-props-type.html">Type of the Children props</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/controlled-input-null-value.html">Value of null for Controlled Input</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/componentWillReceiveProps-not-triggered-after-mounting.html">componentWillReceiveProps Not Triggered After Mounting</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/props-in-getInitialState-as-anti-pattern.html">Props in getInitialState Is an Anti-Pattern</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/dom-event-listeners.html">DOM Event Listeners in a Component</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/initial-ajax.html">Load Initial Data via AJAX</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/false-in-jsx.html">False in JSX</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/communicate-between-components.html">Communicate Between Components</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/expose-component-functions.html">Expose Component Functions</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/children-undefined.html">this.props.children undefined</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/use-react-with-other-libraries.html">Use React with Other Libraries</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="/react/tips/dangerously-set-inner-html.html">Dangerously Set innerHTML</a>
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
<div class="inner-content">
|
|
<a class="edit-page-link" href="https://github.com/facebook/react/tree/master/docs/docs/tutorial.ko-KR.md" target="_blank">Edit on GitHub</a>
|
|
<h1>
|
|
튜토리얼
|
|
</h1>
|
|
<div class="subHeader"></div>
|
|
|
|
<p>블로그에 붙일만한 간단하지만 실용적인 댓글상자를 만들어 볼 것입니다. Disqus, LiveFyre, Facebook에서 제공하는 것 같은 실시간 댓글의 간단한 버전이죠.</p>
|
|
|
|
<p>이런 기능을 넣겠습니다:</p>
|
|
|
|
<ul>
|
|
<li>댓글목록</li>
|
|
<li>댓글작성폼</li>
|
|
<li>커스텀 백엔드를 위한 Hooks</li>
|
|
</ul>
|
|
|
|
<p>멋진 기능도 조금 넣어보겠습니다:</p>
|
|
|
|
<ul>
|
|
<li><strong>낙관적 댓글 달기:</strong> 댓글은 서버에 저장되기도 전에 목록에 나타납니다. 그래서 빠르게 느껴집니다.</li>
|
|
<li><strong>실시간 업데이트:</strong> 다른 사용자가 남기는 댓글이 실시간으로 나타납니다.</li>
|
|
<li><strong>Markdown 지원:</strong> 사용자는 글을 꾸미기 위해 Markdown 형식을 사용할 수 있습니다.</li>
|
|
</ul>
|
|
<h3><a class="anchor" name="-----"></a>그냥 다 생략하고 소스만 보고 싶나요? <a class="hash-link" href="#-----">#</a></h3>
|
|
<p><a href="https://github.com/reactjs/react-tutorial">GitHub에 전부 있습니다.</a></p>
|
|
<h3><a class="anchor" name="-"></a>서버 구동하기 <a class="hash-link" href="#-">#</a></h3>
|
|
<p>이 튜토리얼을 시작하기 위해, 서버를 구동할 필요가 있습니다. 이 서버는 순수하게 우리가 받고 저장할 데이터의 API 엔드포인트로써만 사용합니다. 이를 가능한한 쉽게하기 위해, 필요한 것만 제공하는 간단한 서버를 몇가지 스크립트 언어로 만들었습니다. <strong>시작하는데 필요한 모든 것이 들어있는 <a href="https://github.com/reactjs/react-tutorial/">소스</a>를 보시거나 <a href="https://github.com/reactjs/react-tutorial/archive/master.zip">zip 파일</a>을 다운로드 할 수 있습니다.</strong></p>
|
|
|
|
<p>단순하게 하기위해, 서버는 <code>JSON</code> 파일을 데이터베이스로 사용합니다. 프로덕션에서 사용할 수는 없지만 이렇게 하면 API를 사용할 때 시뮬레이션이 단순해집니다. 서버가 시작되면, API 엔드포인트를 제공하고 필요한 정적 페이지를 서빙합니다.</p>
|
|
<h3><a class="anchor" name=""></a>시작하기 <a class="hash-link" href="#">#</a></h3>
|
|
<p>이 튜토리얼에서는 가능한한 간단하게 만들겠습니다. 위에서 언급된 서버 패키지에 우리가 작업할 HTML 파일 포함되어 있습니다. 편한 편집기에서 <code>public/index.html</code>를 여세요. 이는 이런 내용이어야 합니다.(아마 조금 다를 수 있습니다만, 여기에 나중에 <code><script></code> 태그를 추가 할 것입니다.)</p>
|
|
<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="c"><!-- index.html --></span>
|
|
<span class="cp"><!DOCTYPE html></span>
|
|
<span class="nt"><html></span>
|
|
<span class="nt"><head></span>
|
|
<span class="nt"><meta</span> <span class="na">charset=</span><span class="s">"utf-8"</span> <span class="nt">/></span>
|
|
<span class="nt"><title></span>React Tutorial<span class="nt"></title></span>
|
|
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.js"</span><span class="nt">></script></span>
|
|
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.js"</span><span class="nt">></script></span>
|
|
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"</span><span class="nt">></script></span>
|
|
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"</span><span class="nt">></script></span>
|
|
<span class="nt"></head></span>
|
|
<span class="nt"><body></span>
|
|
<span class="nt"><div</span> <span class="na">id=</span><span class="s">"content"</span><span class="nt">></div></span>
|
|
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/babel"</span> <span class="na">src=</span><span class="s">"scripts/example.js"</span><span class="nt">></script></span>
|
|
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/babel"</span><span class="nt">></span>
|
|
<span class="c1">// 이 튜토리얼을 시작하려면, 그냥 scripts/example.js를 로드하는 스크립트</span>
|
|
<span class="c1">// 태그를 제거하고 여기에 코드를 적으세요.</span>
|
|
<span class="nt"></script></span>
|
|
<span class="nt"></body></span>
|
|
<span class="nt"></html></span>
|
|
</code></pre></div>
|
|
<p>다음 진행을 위해, 위의 스크립트 태그안에 JavaScript 코드를 작성합니다. (이 튜토리얼에서는) 진보된 라이브 리로드가 없기 때문에, 수정 사항을 저장한 다음에는 브라우저를 새로고침해서 확인해야 합니다. 서버를 시작한 다음 브라우저에서 <code>http://localhost:3000</code>를 열어 따라해 보세요. 아무런 수정도 하지 않았다면, 최초 로드시 우리가 만들 제품의 완성품을 확인할 수 있을 것입니다. 작업할 준비가 되면, 이전의 <code><script></code> 태그를 삭제하고 진행하세요.</p>
|
|
|
|
<blockquote>
|
|
<p>주의:</p>
|
|
|
|
<p>여기서는 ajax 요청 코드를 단순화 하기 위해 jQuery를 넣었지만, 이는 React의 동작에 필수적인 것은 <strong>아닙니다</strong>.</p>
|
|
</blockquote>
|
|
<h3><a class="anchor" name="--"></a>첫 번째 컴포넌트 <a class="hash-link" href="#--">#</a></h3>
|
|
<p>모듈화 된, 조합가능한 컴포넌트가 React의 전부입니다. 댓글상자 예제에서 우리는 다음과 같은 컴포넌트 구조를 가질 것입니다:</p>
|
|
<div class="highlight"><pre><code class="language-text" data-lang="text">- CommentBox
|
|
- CommentList
|
|
- Comment
|
|
- CommentForm
|
|
</code></pre></div>
|
|
<p>자, 이제 <code>CommentBox</code> 컴포넌트를 만들어 봅시다. <code><div></code> 하나로 구성되어 있습니다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial1.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentBox</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentBox"</span><span class="o">></span>
|
|
<span class="nx">Hello</span><span class="p">,</span> <span class="nx">world</span><span class="o">!</span> <span class="nx">I</span> <span class="nx">am</span> <span class="nx">a</span> <span class="nx">CommentBox</span><span class="p">.</span>
|
|
<span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
<span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">CommentBox</span> <span class="o">/></span><span class="p">,</span>
|
|
<span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'content'</span><span class="p">)</span>
|
|
<span class="p">);</span>
|
|
</code></pre></div>
|
|
<p>네이티브 HTML 엘리먼트 이름은 소문자로 시작하고 커스텀 React 클래스 이름은 대문자로 시작합니다.</p>
|
|
<h4><a class="anchor" name="jsx-"></a>JSX 문법 <a class="hash-link" href="#jsx-">#</a></h4>
|
|
<p>JavsScript 안의 유사 XML 구문이 먼저 눈에 띌 것입니다. 우리에겐 이를 JavaScript로 변환해주는 간단한 프리컴파일러(precompiler)가 있습니다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial1-raw.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentBox</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span><span class="nx">displayName</span><span class="o">:</span> <span class="s1">'CommentBox'</span><span class="p">,</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="nx">React</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'div'</span><span class="p">,</span> <span class="p">{</span><span class="nx">className</span><span class="o">:</span> <span class="s2">"commentBox"</span><span class="p">},</span>
|
|
<span class="s2">"Hello, world! I am a CommentBox."</span>
|
|
<span class="p">)</span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
<span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
|
|
<span class="nx">React</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="nx">CommentBox</span><span class="p">,</span> <span class="kc">null</span><span class="p">),</span>
|
|
<span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'content'</span><span class="p">)</span>
|
|
<span class="p">);</span>
|
|
</code></pre></div>
|
|
<p>JSX의 사용은 선택적이지만 JSX 문법이 일반 JavsScript보다 사용하기 쉽습니다. <a href="/react/docs/jsx-in-depth.html">JSX 문법 문서</a>에서 더 알아보세요.</p>
|
|
<h4><a class="anchor" name="---"></a>무슨 일이 일어나고 있는가 <a class="hash-link" href="#---">#</a></h4>
|
|
<p>우리는 새로운 React 컴포넌트를 만들기 위해 <code>React.createClass()</code>로 JavaScript 객체에 몇 개의 메소드를 담아 넘겼습니다. 이 중 가장 중요한것은 <code>render</code> 메소드인데, 이는 React 컴포넌트 트리를 리턴해서 최종적으로 실제 HTML을 그려주게 됩니다.</p>
|
|
|
|
<p><code><div></code> 태그들은 실제 DOM 노드가 아니라 React <code>div</code> 컴포넌트의 인스턴스입니다. 이것은 React가 다룰 수 있는 데이터의 표시자(markers)나 조각이라 생각하셔도 됩니다. React는 <strong>안전합니다</strong>. 생(raw) HTML 문자열을 생성하는 것이 아니기 때문에 XSS을 기본적으로 방지합니다.</p>
|
|
|
|
<p>일반적인 HTML만 리턴할 수 있는 것은 아닙니다. 여러분이 직접 만든 (또는 다른 사람들이 만들어 놓은) 컴포넌트의 트리를 리턴할 수도 있습니다. 이것이 React를 <strong>조합가능(composable)하게 만듭니다</strong>: 유지보수 가능한 프론트엔드를 위한 핵심 교리(key tenet)지요.</p>
|
|
|
|
<p><code>ReactDOM.render()</code>는 최상위 컴포넌트의 인스턴스를 만들고, 두 번째 인수로 전달받은 DOM 엘리먼트에 마크업을 삽입해 프레임워크를 시작합니다.</p>
|
|
|
|
<p><code>ReactDOM</code> 모듈은 DOM 특정 메소드를 노출해, <code>React</code>가 코어 툴을 다른 플렛폼(예를 들어, <a href="http://facebook.github.io/react-native/">React Native</a>)에 공유할 수 있게 합니다.</p>
|
|
<h2><a class="anchor" name="-"></a>컴포넌트 조합하기 <a class="hash-link" href="#-">#</a></h2>
|
|
<p>이제 <code>CommentList</code>와 <code>CommentForm</code>을 위한 뼈대를 구축해 봅시다. 이전과 마찬가지로 단순히 <code><div></code> 태그 하나 입니다. 파일에 두 컴포넌트를 추가해, 이미 있는 <code>CommentBox</code> 선언을 참고로 <code>ReactDOM.render</code>를 호출합시다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial2.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentList</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentList"</span><span class="o">></span>
|
|
<span class="err">안녕</span><span class="o">!</span> <span class="err">난</span> <span class="err">댓글목록이야</span><span class="p">.</span>
|
|
<span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">CommentForm</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentForm"</span><span class="o">></span>
|
|
<span class="err">안녕</span><span class="o">!</span> <span class="err">난</span> <span class="err">댓글</span> <span class="err">폼이야</span><span class="p">.</span>
|
|
<span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>다음은 <code>CommentBox</code> 컴포넌트가 새로 만든 컴포넌트들을 사용하도록 수정합니다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial3.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentBox</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentBox"</span><span class="o">></span>
|
|
<span class="hll"> <span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="err">댓글</span><span class="o"><</span><span class="err">/h1></span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="nx">CommentList</span> <span class="o">/></span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="nx">CommentForm</span> <span class="o">/></span>
|
|
</span> <span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>방금 만든 컴포넌트들을 어떻게 HTML 태그들과 섞어 사용하는지 살펴보세요. HTML 컴포넌트들도 한가지 차이만 제외한다면 우리가 정의한 것과 같은 표준적인 React 컴포넌트입니다. JSX 컴파일러가 자동으로 HTML 태그들을 <code>React.createElement(tagName)</code> 표현식으로 재작성하고 나머지는 그대로 둘 것입니다. 이는 전역 네임스페이스가 오염되는 것을 막아줍니다.</p>
|
|
<h3><a class="anchor" name="props-"></a>props 사용하기 <a class="hash-link" href="#props-">#</a></h3>
|
|
<p>부모로 부터 받은 데이터에 의존하는 <code>Comment</code> 컴포넌트를 만들어 봅시다. 부모 컴포넌트로 부터 받은 데이터는 자식 컴포넌트에서 '프로퍼티'로 사용가능 합니다. 이 '프로퍼티들'은 <code>this.props</code>를 통해 접근합니다. props를 사용해, <code>CommentList</code>에서 전달받은 데이터를 읽어들이고, 마크업을 렌더할 수 있을 것입니다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial4.js</span>
|
|
<span class="kd">var</span> <span class="nx">Comment</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"comment"</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">h2</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentAuthor"</span><span class="o">></span>
|
|
<span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">author</span><span class="p">}</span>
|
|
<span class="o"><</span><span class="err">/h2></span>
|
|
<span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">children</span><span class="p">}</span>
|
|
<span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>JSX 내부의 중괄호로 둘러싸인 JavaScript 표현식(어트리뷰트나 엘리먼트의 자식으로 사용된)을 통해 텍스트나 React 컴포넌트를 트리에 더할 수 있습니다. <code>this.props</code>를 통해 컴포넌트에 전달된 특정한 어트리뷰트들에, <code>this.props.children</code>을 통해 중첩된 엘리먼트들에 접근할 수 있습니다.</p>
|
|
<h3><a class="anchor" name="--component-properties"></a>컴포넌트 프로퍼티 (Component Properties) <a class="hash-link" href="#--component-properties">#</a></h3>
|
|
<p><code>Comment</code> 컴포넌트를 만들었으니, 여기에 글쓴이와 내용을 넘겨보도록 합시다. 이렇게 함으로써 각 고유한 comment에서 같은 코드를 재사용할 수 있습니다. 먼저 댓글 몇 개를 <code>CommentList</code>에 추가해 봅시다:</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial5.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentList</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentList"</span><span class="o">></span>
|
|
<span class="hll"> <span class="o"><</span><span class="nx">Comment</span> <span class="nx">author</span><span class="o">=</span><span class="s2">"Pete Hunt"</span><span class="o">></span><span class="err">댓글입니다</span><span class="o"><</span><span class="err">/Comment></span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="nx">Comment</span> <span class="nx">author</span><span class="o">=</span><span class="s2">"Jordan Walke"</span><span class="o">>*</span><span class="err">또</span> <span class="err">다른</span><span class="o">*</span> <span class="err">댓글입니다</span><span class="o"><</span><span class="err">/Comment></span>
|
|
</span> <span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>부모 컴포넌트인 <code>CommentList</code>에서 자식 컴포넌트인 <code>Comment</code>에 데이터들을 전달하고 있는것을 확인할 수 있습니다. 예를 들어, 우리는 어트리뷰트로 <em>Pete Hunt</em>를, XML 형식의 자식 노드로 <em>댓글입니다</em>를 첫 번째 <code>Comment</code>로 넘겼습니다. 위에서 언급했듯이 <code>Comment</code> 컴포넌트는 그들의 '프로퍼티'를 <code>this.props.author</code>, <code>this.props.children</code>를 통해 접근합니다.</p>
|
|
<h3><a class="anchor" name="markdown-"></a>Markdown 추가하기 <a class="hash-link" href="#markdown-">#</a></h3>
|
|
<p>Markdown은 텍스트를 포맷팅하는 간단한 방식입니다. 예를 들어, 별표(<code>*</code>)로 텍스트를 둘러싸는 것은 강조의 의미입니다.</p>
|
|
|
|
<p>먼저 서드파티 라이브러리인 <strong>marked</strong>를 애플리케이션에 추가합니다. 이 JavaScript 라이브러리는 Markdown 텍스트를 HTML 문법으로 변환해줍니다. head 태그안에 스크립트 태그를 추가해 주세요. (React playground에는 이미 포함되어 있습니다):</p>
|
|
<div class="highlight"><pre><code class="language-html" data-lang="html"><span class="c"><!-- index.html --></span>
|
|
<span class="nt"><head></span>
|
|
<span class="nt"><meta</span> <span class="na">charset=</span><span class="s">"utf-8"</span> <span class="nt">/></span>
|
|
<span class="nt"><title></span>React Tutorial<span class="nt"></title></span>
|
|
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.js"</span><span class="nt">></script></span>
|
|
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.js"</span><span class="nt">></script></span>
|
|
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"</span><span class="nt">></script></span>
|
|
<span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"</span><span class="nt">></script></span>
|
|
<span class="hll"> <span class="nt"><script </span><span class="na">src=</span><span class="s">"https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.min.js"</span><span class="nt">></script></span>
|
|
</span><span class="nt"></head></span>
|
|
</code></pre></div>
|
|
<p>다음은, 댓글 텍스트를 Markdown으로 전환하고 출력해 봅시다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial6.js</span>
|
|
<span class="kd">var</span> <span class="nx">Comment</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"comment"</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">h2</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentAuthor"</span><span class="o">></span>
|
|
<span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">author</span><span class="p">}</span>
|
|
<span class="o"><</span><span class="err">/h2></span>
|
|
<span class="hll"> <span class="p">{</span><span class="nx">marked</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">children</span><span class="p">.</span><span class="nx">toString</span><span class="p">())}</span>
|
|
</span> <span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>우리가 한 일이라고는 marked 라이브러리를 호출한 것 뿐입니다. marked가 <code>this.props.children</code>에서 텍스트를 읽어들여 처리할 수 있도록 React 형식의 텍스트(React's wrapped text)를 단순 텍스트(raw string)으로 전환하기 위해 명시적으로 <code>toString()</code>을 호출했습니다.</p>
|
|
|
|
<p>하지만 여기엔 문제가 있습니다! 우리는 HTML 태그들이 정상적으로 렌더되길 원하지만 브라우저에 출력된 결과물은 "<code><p></code><code><em></code>또 다른<code></em></code> 댓글입니다<code></p></code>"처럼 태그가 그대로 보일것입니다.</p>
|
|
|
|
<p>React는 이런 식으로 <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">XSS 공격</a>을 예방합니다. 우회할 방법이 있긴 하지만 프레임워크는 사용하지 않도록 경고하고 있습니다:</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial7.js</span>
|
|
<span class="kd">var</span> <span class="nx">Comment</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="hll"> <span class="nx">rawMarkup</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="kd">var</span> <span class="nx">rawMarkup</span> <span class="o">=</span> <span class="nx">marked</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">children</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="p">{</span><span class="nx">sanitize</span><span class="o">:</span> <span class="kc">true</span><span class="p">});</span>
|
|
</span><span class="hll"> <span class="k">return</span> <span class="p">{</span> <span class="nx">__html</span><span class="o">:</span> <span class="nx">rawMarkup</span> <span class="p">};</span>
|
|
</span><span class="hll"> <span class="p">},</span>
|
|
</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"comment"</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">h2</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentAuthor"</span><span class="o">></span>
|
|
<span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">author</span><span class="p">}</span>
|
|
<span class="o"><</span><span class="err">/h2></span>
|
|
<span class="hll"> <span class="o"><</span><span class="nx">span</span> <span class="nx">dangerouslySetInnerHTML</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">rawMarkup</span><span class="p">()}</span> <span class="o">/></span>
|
|
</span> <span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>이는 의도적으로 생(raw) HTML을 넣기 힘들게 하려고 만든 특별한 API지만 marked를 사용하기 위해 이 백도어를 활용합시다.</p>
|
|
|
|
<p><strong>잊지 마세요:</strong> 이 기능은 marked가 안전한 것으로 믿고 사용하는 것입니다. 이 경우, 소스에 있는 그대로 넘겨 주는 대신, 모든 HTML 마크업을 이스케이프하도록 marked에게 <code>sanitize: true</code>를 넘겨 주었습니다.</p>
|
|
<h3><a class="anchor" name="--"></a>데이터 모델 연결하기 <a class="hash-link" href="#--">#</a></h3>
|
|
<p>지금까지는 소스코드에 직접 댓글을 넣었습니다. 이제부터는 JSON 데이터 덩어리를 댓글 목록에 렌더해보겠습니다. 최종적으로는 서버에서 데이터가 내려오겠지만, 지금은 소스에 직접 데이터를 넣어봅시다:</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial8.js</span>
|
|
<span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="p">{</span><span class="nx">author</span><span class="o">:</span> <span class="s2">"Pete Hunt"</span><span class="p">,</span> <span class="nx">text</span><span class="o">:</span> <span class="s2">"댓글입니다"</span><span class="p">},</span>
|
|
<span class="p">{</span><span class="nx">author</span><span class="o">:</span> <span class="s2">"Jordan Walke"</span><span class="p">,</span> <span class="nx">text</span><span class="o">:</span> <span class="s2">"*또 다른* 댓글입니다"</span><span class="p">}</span>
|
|
<span class="p">];</span>
|
|
</code></pre></div>
|
|
<p>이 데이터를 모듈화된 방식으로 <code>CommentList</code>에 넣어야 합니다. props을 이용해 데이터를 넘기도록 <code>CommentBox</code>와 <code>ReactDOM.render()</code> 호출 코드를 수정합시다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial9.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentBox</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentBox"</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="err">댓글</span><span class="o"><</span><span class="err">/h1></span>
|
|
<span class="hll"> <span class="o"><</span><span class="nx">CommentList</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">data</span><span class="p">}</span> <span class="o">/></span>
|
|
</span> <span class="o"><</span><span class="nx">CommentForm</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
|
|
<span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
|
|
<span class="hll"> <span class="o"><</span><span class="nx">CommentBox</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="nx">data</span><span class="p">}</span> <span class="o">/></span><span class="p">,</span>
|
|
</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'content'</span><span class="p">)</span>
|
|
<span class="p">);</span>
|
|
</code></pre></div>
|
|
<p>이제 <code>CommentList</code>에서 데이터를 다룰 수 있습니다. 댓글을 동적으로 렌더해봅시다:</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial10.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentList</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="hll"> <span class="kd">var</span> <span class="nx">commentNodes</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">comment</span><span class="p">)</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="k">return</span> <span class="p">(</span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="nx">Comment</span> <span class="nx">author</span><span class="o">=</span><span class="p">{</span><span class="nx">comment</span><span class="p">.</span><span class="nx">author</span><span class="p">}</span><span class="o">></span>
|
|
</span><span class="hll"> <span class="p">{</span><span class="nx">comment</span><span class="p">.</span><span class="nx">text</span><span class="p">}</span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="err">/Comment></span>
|
|
</span><span class="hll"> <span class="p">);</span>
|
|
</span><span class="hll"> <span class="p">});</span>
|
|
</span> <span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentList"</span><span class="o">></span>
|
|
<span class="hll"> <span class="p">{</span><span class="nx">commentNodes</span><span class="p">}</span>
|
|
</span> <span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>이게 전부입니다!</p>
|
|
<h3><a class="anchor" name="-fetching"></a>서버에서 가져오기(Fetching) <a class="hash-link" href="#-fetching">#</a></h3>
|
|
<p>이제 데이터를 소스에 직접 넣는 방식에서 서버에서 동적으로 받아서 처리하는 방식으로 바꿔봅시다. 데이터 prop을 삭제하고 처리할 URL로 변경해 줍시다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial11.js</span>
|
|
<span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
|
|
<span class="hll"> <span class="o"><</span><span class="nx">CommentBox</span> <span class="nx">url</span><span class="o">=</span><span class="s2">"/api/comments"</span> <span class="o">/></span><span class="p">,</span>
|
|
</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'content'</span><span class="p">)</span>
|
|
<span class="p">);</span>
|
|
</code></pre></div>
|
|
<p>이 컴포넌트는 이전 것과 다르게, 스스로 다시 렌더링해야 합니다. 컴포넌트는 서버에서 요청이 들어올때까지는 아무 데이터도 가지고 있지 않다가, 특정한 시점에서 새로운 댓글을 렌더할 필요가 있을 것입니다.</p>
|
|
|
|
<p>주의: 이 단계에서 코드는 아직 동작하지 않습니다.</p>
|
|
<h3><a class="anchor" name="-state"></a>반응적 state <a class="hash-link" href="#-state">#</a></h3>
|
|
<p>지금까지, 각각의 컴포넌트는 props를 기반으로 한번 렌더되었습니다. <code>props</code>는 불변성을 갖습니다: 그것들은 부모에서 전달되어 부모에게 "소유" 되어 있습니다. 컴포넌트에 상호작용을 구현하기 위해서, 가변성을 갖는 <strong>state</strong>를 소개합니다. <code>this.state</code>는 컴포넌트에 한정(private)되며 <code>this.setState()</code>를 통해 변경할 수 있습니다. state가 업데이트 되면, 컴포넌트는 자신을 스스로 다시 렌더링합니다.</p>
|
|
|
|
<p><code>render()</code> 메소드는 <code>this.props</code>와 <code>this.state</code>를 위한 함수로 선언적으로 작성됩니다. 프레임워크에서 입력값에 따른 UI가 항상 일관성 있음을 보장해줍니다.</p>
|
|
|
|
<p>서버가 데이터를 가져오면 댓글 데이터가 변경될 것입니다. 댓글 데이터의 배열을 <code>CommentBox</code>의 state로 추가해봅시다:</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial12.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentBox</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="hll"> <span class="nx">getInitialState</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="k">return</span> <span class="p">{</span><span class="nx">data</span><span class="o">:</span> <span class="p">[]};</span>
|
|
</span><span class="hll"> <span class="p">},</span>
|
|
</span> <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentBox"</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="err">댓글</span><span class="o"><</span><span class="err">/h1></span>
|
|
<span class="hll"> <span class="o"><</span><span class="nx">CommentList</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">data</span><span class="p">}</span> <span class="o">/></span>
|
|
</span> <span class="o"><</span><span class="nx">CommentForm</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p><code>getInitialState()</code> 는 컴포넌트의 생명주기동안 한 번만 실행되며 컴포넌트의 초기 state를 설정합니다.</p>
|
|
<h3><a class="anchor" name="state-"></a>state 업데이트하기 <a class="hash-link" href="#state-">#</a></h3>
|
|
<p>컴포넌트의 최초 생성 시에, 서버에서 GET 방식으로 JSON을 넘겨받아 최신의 데이터가 state에 반영되길 원했습니다. jQuery를 사용해 서버에 비동기 요청을 만들어 필요한 데이터를 빨리 가져올 수 있게 하겠습니다. 이런 식입니다.</p>
|
|
<div class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">[</span>
|
|
<span class="p">{</span><span class="nt">"author"</span><span class="p">:</span> <span class="s2">"Pete Hunt"</span><span class="p">,</span> <span class="nt">"text"</span><span class="p">:</span> <span class="s2">"댓글입니다"</span><span class="p">},</span>
|
|
<span class="p">{</span><span class="nt">"author"</span><span class="p">:</span> <span class="s2">"Jordan Walke"</span><span class="p">,</span> <span class="nt">"text"</span><span class="p">:</span> <span class="s2">"*또 다른* 댓글입니다"</span><span class="p">}</span>
|
|
<span class="p">]</span>
|
|
</code></pre></div><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial13.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentBox</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">getInitialState</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">{</span><span class="nx">data</span><span class="o">:</span> <span class="p">[]};</span>
|
|
<span class="p">},</span>
|
|
<span class="hll"> <span class="nx">componentDidMount</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
|
|
</span><span class="hll"> <span class="nx">url</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span>
|
|
</span><span class="hll"> <span class="nx">dataType</span><span class="o">:</span> <span class="s1">'json'</span><span class="p">,</span>
|
|
</span><span class="hll"> <span class="nx">cache</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
|
|
</span><span class="hll"> <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">data</span><span class="o">:</span> <span class="nx">data</span><span class="p">});</span>
|
|
</span><span class="hll"> <span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">),</span>
|
|
</span><span class="hll"> <span class="nx">error</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">xhr</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span>
|
|
</span><span class="hll"> <span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
|
|
</span><span class="hll"> <span class="p">});</span>
|
|
</span><span class="hll"> <span class="p">},</span>
|
|
</span> <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentBox"</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="err">댓글</span><span class="o"><</span><span class="err">/h1></span>
|
|
<span class="o"><</span><span class="nx">CommentList</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">data</span><span class="p">}</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="nx">CommentForm</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>여기서 <code>componentDidMount</code>는 컴포넌트가 렌더링 된 다음 React에 의해 자동으로 호출되는 메소드입니다. 동적 업데이트의 핵심은 <code>this.setState()</code>의 호출입니다. 우리가 이전의 댓글 목록을 서버에서 넘어온 새로운 목록으로 변경하면 자동으로 UI가 업데이트 될 것입니다. 이 반응성 덕분에 실시간 업데이트에 아주 작은 수정만 가해집니다. 우리는 여기선 간단한 폴링을 사용할 것이지만 웹소켓등의 다른 기술도 쉽게 사용할 수 있습니다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial14.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentBox</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="hll"> <span class="nx">loadCommentsFromServer</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
</span> <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
|
|
<span class="nx">url</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span>
|
|
<span class="nx">dataType</span><span class="o">:</span> <span class="s1">'json'</span><span class="p">,</span>
|
|
<span class="nx">cache</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
|
|
<span class="nx">success</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">data</span><span class="o">:</span> <span class="nx">data</span><span class="p">});</span>
|
|
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">),</span>
|
|
<span class="nx">error</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">xhr</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span>
|
|
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
|
|
<span class="p">});</span>
|
|
<span class="hll"> <span class="p">},</span>
|
|
</span> <span class="nx">getInitialState</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">{</span><span class="nx">data</span><span class="o">:</span> <span class="p">[]};</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">componentDidMount</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="hll"> <span class="k">this</span><span class="p">.</span><span class="nx">loadCommentsFromServer</span><span class="p">();</span>
|
|
</span><span class="hll"> <span class="nx">setInterval</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">loadCommentsFromServer</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">pollInterval</span><span class="p">);</span>
|
|
</span> <span class="p">},</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentBox"</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="err">댓글</span><span class="o"><</span><span class="err">/h1></span>
|
|
<span class="o"><</span><span class="nx">CommentList</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">data</span><span class="p">}</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="nx">CommentForm</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
|
|
<span class="nx">ReactDOM</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span>
|
|
<span class="hll"> <span class="o"><</span><span class="nx">CommentBox</span> <span class="nx">url</span><span class="o">=</span><span class="s2">"/api/comments"</span> <span class="nx">pollInterval</span><span class="o">=</span><span class="p">{</span><span class="mi">2000</span><span class="p">}</span> <span class="o">/></span><span class="p">,</span>
|
|
</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'content'</span><span class="p">)</span>
|
|
<span class="p">);</span>
|
|
</code></pre></div>
|
|
<p>우리가 여기서 한것은 AJAX 호출을 별도의 메소드로 분리하고 컴포넌트가 처음 로드된 시점부터 2초 간격으로 계속 호출되도록 한 것입니다. 브라우저에서 직접 돌려보고 <code>comments.json</code> 파일(서버의 같은 디렉토리에 있습니다)을 수정해보세요. 2초 간격으로 변화되는 모습이 보일 것입니다!</p>
|
|
<h3><a class="anchor" name="--"></a>새로운 댓글 추가하기 <a class="hash-link" href="#--">#</a></h3>
|
|
<p>이제 폼을 만들어볼 시간입니다. 우리의 <code>CommentForm</code> 컴포넌트는 사용자에게 이름과 내용을 입력받고 댓글을 저장하기 위해 서버에 요청을 전송해야 합니다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial15.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentForm</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="hll"> <span class="o"><</span><span class="nx">form</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentForm"</span><span class="o">></span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="nx">placeholder</span><span class="o">=</span><span class="s2">"이름"</span> <span class="o">/></span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="nx">placeholder</span><span class="o">=</span><span class="s2">"내용을 입력하세요..."</span> <span class="o">/></span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"submit"</span> <span class="nx">value</span><span class="o">=</span><span class="s2">"올리기"</span> <span class="o">/></span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="err">/form></span>
|
|
</span> <span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>이제 폼의 상호작용을 만들어 보겠습니다. 사용자가 폼을 전송하는 시점에 우리는 폼을 초기화하고 서버에 요청을 전송하고 댓글목록을 업데이트해야 합니다. 폼의 submit 이벤트를 감시하고 초기화 해주는 부분부터 시작해 보죠.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial16.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentForm</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="hll"> <span class="nx">handleSubmit</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
|
|
</span><span class="hll"> <span class="kd">var</span> <span class="nx">author</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">refs</span><span class="p">.</span><span class="nx">author</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">trim</span><span class="p">();</span>
|
|
</span><span class="hll"> <span class="kd">var</span> <span class="nx">text</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">refs</span><span class="p">.</span><span class="nx">text</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">trim</span><span class="p">();</span>
|
|
</span><span class="hll"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">text</span> <span class="o">||</span> <span class="o">!</span><span class="nx">author</span><span class="p">)</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="k">return</span><span class="p">;</span>
|
|
</span><span class="hll"> <span class="p">}</span>
|
|
</span><span class="hll"> <span class="c1">// TODO: 서버에 요청을 전송합니다</span>
|
|
</span><span class="hll"> <span class="k">this</span><span class="p">.</span><span class="nx">refs</span><span class="p">.</span><span class="nx">author</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span>
|
|
</span><span class="hll"> <span class="k">this</span><span class="p">.</span><span class="nx">refs</span><span class="p">.</span><span class="nx">text</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span>
|
|
</span><span class="hll"> <span class="k">return</span><span class="p">;</span>
|
|
</span> <span class="p">},</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="hll"> <span class="k">return</span> <span class="p">(</span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="nx">form</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentForm"</span> <span class="nx">onSubmit</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">handleSubmit</span><span class="p">}</span><span class="o">></span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="nx">placeholder</span><span class="o">=</span><span class="s2">"이름"</span> <span class="nx">ref</span><span class="o">=</span><span class="s2">"author"</span> <span class="o">/></span>
|
|
</span><span class="hll"> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="nx">placeholder</span><span class="o">=</span><span class="s2">"내용을 입력하세요..."</span> <span class="nx">ref</span><span class="o">=</span><span class="s2">"text"</span> <span class="o">/></span>
|
|
</span> <span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"submit"</span> <span class="nx">value</span><span class="o">=</span><span class="s2">"올리기"</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="err">/form></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div><h5><a class="anchor" name=""></a>이벤트 <a class="hash-link" href="#">#</a></h5>
|
|
<p>React는 카멜케이스 네이밍 컨벤션으로 컴포넌트에 이벤트 핸들러를 등록합니다. 폼이 유효한 값으로 submit되었을 때 폼필드들을 초기화하도록 <code>onSubmit</code> 핸들러를 등록합니다.</p>
|
|
|
|
<p>폼 submit에 대한 브라우저의 기본동작을 막기 위해 이벤트시점에 <code>preventDefault()</code>를 호출합니다.</p>
|
|
<h5><a class="anchor" name="refs"></a>Refs <a class="hash-link" href="#refs">#</a></h5>
|
|
<p>자식 컴포넌트의 이름을 지정하기 위해 <code>ref</code> 어트리뷰트를, DOM 노드를 참조하기 위해 <code>this.refs</code>를 사용합니다.</p>
|
|
<h5><a class="anchor" name="props--"></a>props으로 콜백 처리하기 <a class="hash-link" href="#props--">#</a></h5>
|
|
<p>사용자가 댓글을 등록할 때, 새로운 댓글을 추가하기 위해 댓글목록을 업데이트해주어야 합니다. <code>CommentBox</code>가 댓글목록의 state를 소유하고 있기 때문에 이 로직 또한 <code>CommentBox</code>에 있는것이 타당합니다.</p>
|
|
|
|
<p>자식 컴포넌트가 그의 부모에게 데이터를 넘겨줄 필요가 있습니다. 부모의 <code>render</code> 메소드에서 새로운 콜백(<code>handleCommentSubmit</code>)을 자식에게 넘겨주고, 자식의 <code>onCommentSubmit</code> 이벤트에 그것을 바인딩해주는 식으로 구현합니다. 이벤트가 작동될때(triggered)마다, 콜백이 호출됩니다:</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial17.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentBox</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">loadCommentsFromServer</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
|
|
<span class="nx">url</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span>
|
|
<span class="nx">dataType</span><span class="o">:</span> <span class="s1">'json'</span><span class="p">,</span>
|
|
<span class="nx">cache</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
|
|
<span class="nx">success</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">data</span><span class="o">:</span> <span class="nx">data</span><span class="p">});</span>
|
|
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">),</span>
|
|
<span class="nx">error</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">xhr</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span>
|
|
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
|
|
<span class="p">});</span>
|
|
<span class="p">},</span>
|
|
<span class="hll"> <span class="nx">handleCommentSubmit</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">comment</span><span class="p">)</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="c1">// TODO: 서버에 요청을 수행하고 목록을 업데이트한다</span>
|
|
</span><span class="hll"> <span class="p">},</span>
|
|
</span> <span class="nx">getInitialState</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">{</span><span class="nx">data</span><span class="o">:</span> <span class="p">[]};</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">componentDidMount</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">loadCommentsFromServer</span><span class="p">();</span>
|
|
<span class="nx">setInterval</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">loadCommentsFromServer</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">pollInterval</span><span class="p">);</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentBox"</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="err">댓글</span><span class="o"><</span><span class="err">/h1></span>
|
|
<span class="o"><</span><span class="nx">CommentList</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">data</span><span class="p">}</span> <span class="o">/></span>
|
|
<span class="hll"> <span class="o"><</span><span class="nx">CommentForm</span> <span class="nx">onCommentSubmit</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">handleCommentSubmit</span><span class="p">}</span> <span class="o">/></span>
|
|
</span> <span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>사용자가 폼을 전송할 때, <code>CommentForm</code>에서 콜백을 호출해 봅시다:</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial18.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentForm</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">handleSubmit</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
|
|
<span class="kd">var</span> <span class="nx">author</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">refs</span><span class="p">.</span><span class="nx">author</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">trim</span><span class="p">();</span>
|
|
<span class="kd">var</span> <span class="nx">text</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">refs</span><span class="p">.</span><span class="nx">text</span><span class="p">.</span><span class="nx">value</span><span class="p">.</span><span class="nx">trim</span><span class="p">();</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">text</span> <span class="o">||</span> <span class="o">!</span><span class="nx">author</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">return</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
<span class="hll"> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">onCommentSubmit</span><span class="p">({</span><span class="nx">author</span><span class="o">:</span> <span class="nx">author</span><span class="p">,</span> <span class="nx">text</span><span class="o">:</span> <span class="nx">text</span><span class="p">});</span>
|
|
</span> <span class="k">this</span><span class="p">.</span><span class="nx">refs</span><span class="p">.</span><span class="nx">author</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">refs</span><span class="p">.</span><span class="nx">text</span><span class="p">.</span><span class="nx">value</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span>
|
|
<span class="k">return</span><span class="p">;</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">form</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentForm"</span> <span class="nx">onSubmit</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">handleSubmit</span><span class="p">}</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="nx">placeholder</span><span class="o">=</span><span class="s2">"이름"</span> <span class="nx">ref</span><span class="o">=</span><span class="s2">"author"</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"text"</span> <span class="nx">placeholder</span><span class="o">=</span><span class="s2">"이름을 입력하세요..."</span> <span class="nx">ref</span><span class="o">=</span><span class="s2">"text"</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="nx">input</span> <span class="nx">type</span><span class="o">=</span><span class="s2">"submit"</span> <span class="nx">value</span><span class="o">=</span><span class="s2">"올리기"</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="err">/form></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div>
|
|
<p>이제 콜백이 제자리를 찾았습니다. 우리가 할 일은 서버에 요청을 날리고 목록을 업데이트하는 것 뿐입니다:</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial19.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentBox</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">loadCommentsFromServer</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
|
|
<span class="nx">url</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span>
|
|
<span class="nx">dataType</span><span class="o">:</span> <span class="s1">'json'</span><span class="p">,</span>
|
|
<span class="nx">cache</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
|
|
<span class="nx">success</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">data</span><span class="o">:</span> <span class="nx">data</span><span class="p">});</span>
|
|
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">),</span>
|
|
<span class="nx">error</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">xhr</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span>
|
|
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
|
|
<span class="p">});</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">handleCommentSubmit</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">comment</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="hll"> <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
|
|
</span><span class="hll"> <span class="nx">url</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span>
|
|
</span><span class="hll"> <span class="nx">dataType</span><span class="o">:</span> <span class="s1">'json'</span><span class="p">,</span>
|
|
</span><span class="hll"> <span class="nx">type</span><span class="o">:</span> <span class="s1">'POST'</span><span class="p">,</span>
|
|
</span><span class="hll"> <span class="nx">data</span><span class="o">:</span> <span class="nx">comment</span><span class="p">,</span>
|
|
</span><span class="hll"> <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">data</span><span class="o">:</span> <span class="nx">data</span><span class="p">});</span>
|
|
</span><span class="hll"> <span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">),</span>
|
|
</span><span class="hll"> <span class="nx">error</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">xhr</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
|
|
</span><span class="hll"> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span>
|
|
</span><span class="hll"> <span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
|
|
</span><span class="hll"> <span class="p">});</span>
|
|
</span> <span class="p">},</span>
|
|
<span class="nx">getInitialState</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">{</span><span class="nx">data</span><span class="o">:</span> <span class="p">[]};</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">componentDidMount</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">loadCommentsFromServer</span><span class="p">();</span>
|
|
<span class="nx">setInterval</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">loadCommentsFromServer</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">pollInterval</span><span class="p">);</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentBox"</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="err">댓글</span><span class="o"><</span><span class="err">/h1></span>
|
|
<span class="o"><</span><span class="nx">CommentList</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">data</span><span class="p">}</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="nx">CommentForm</span> <span class="nx">onCommentSubmit</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">handleCommentSubmit</span><span class="p">}</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div><h3><a class="anchor" name="--"></a>최적화: 낙관적 업데이트 <a class="hash-link" href="#--">#</a></h3>
|
|
<p>우리의 애플리케이션은 이제 모든 기능을 갖추었습니다. 하지만 댓글이 목록에 업데이트되기 전에 완료요청을 기다리는 게 조금 느린듯한 느낌이 드네요. 우리는 낙관적 업데이트를 통해 댓글이 목록에 추가되도록 함으로써 앱이 좀 더 빨라진 것처럼 느껴지도록 할 수 있습니다.</p>
|
|
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// tutorial20.js</span>
|
|
<span class="kd">var</span> <span class="nx">CommentBox</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
|
|
<span class="nx">loadCommentsFromServer</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
|
|
<span class="nx">url</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span>
|
|
<span class="nx">dataType</span><span class="o">:</span> <span class="s1">'json'</span><span class="p">,</span>
|
|
<span class="nx">cache</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
|
|
<span class="nx">success</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">data</span><span class="o">:</span> <span class="nx">data</span><span class="p">});</span>
|
|
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">),</span>
|
|
<span class="nx">error</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">xhr</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span>
|
|
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
|
|
<span class="p">});</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">handleCommentSubmit</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">comment</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="hll"> <span class="kd">var</span> <span class="nx">comments</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">data</span><span class="p">;</span>
|
|
</span><span class="hll"> <span class="kd">var</span> <span class="nx">newComments</span> <span class="o">=</span> <span class="nx">comments</span><span class="p">.</span><span class="nx">concat</span><span class="p">([</span><span class="nx">comment</span><span class="p">]);</span>
|
|
</span><span class="hll"> <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">data</span><span class="o">:</span> <span class="nx">newComments</span><span class="p">});</span>
|
|
</span> <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
|
|
<span class="nx">url</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span>
|
|
<span class="nx">dataType</span><span class="o">:</span> <span class="s1">'json'</span><span class="p">,</span>
|
|
<span class="nx">type</span><span class="o">:</span> <span class="s1">'POST'</span><span class="p">,</span>
|
|
<span class="nx">data</span><span class="o">:</span> <span class="nx">comment</span><span class="p">,</span>
|
|
<span class="nx">success</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">data</span><span class="o">:</span> <span class="nx">data</span><span class="p">});</span>
|
|
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">),</span>
|
|
<span class="nx">error</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">xhr</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="hll"> <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span><span class="nx">data</span><span class="o">:</span> <span class="nx">comments</span><span class="p">});</span>
|
|
</span> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="nx">status</span><span class="p">,</span> <span class="nx">err</span><span class="p">.</span><span class="nx">toString</span><span class="p">());</span>
|
|
<span class="p">}.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
|
|
<span class="p">});</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">getInitialState</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">{</span><span class="nx">data</span><span class="o">:</span> <span class="p">[]};</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">componentDidMount</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nx">loadCommentsFromServer</span><span class="p">();</span>
|
|
<span class="nx">setInterval</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">loadCommentsFromServer</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">pollInterval</span><span class="p">);</span>
|
|
<span class="p">},</span>
|
|
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">return</span> <span class="p">(</span>
|
|
<span class="o"><</span><span class="nx">div</span> <span class="nx">className</span><span class="o">=</span><span class="s2">"commentBox"</span><span class="o">></span>
|
|
<span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="err">댓글</span><span class="o"><</span><span class="err">/h1></span>
|
|
<span class="o"><</span><span class="nx">CommentList</span> <span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">data</span><span class="p">}</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="nx">CommentForm</span> <span class="nx">onCommentSubmit</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">handleCommentSubmit</span><span class="p">}</span> <span class="o">/></span>
|
|
<span class="o"><</span><span class="err">/div></span>
|
|
<span class="p">);</span>
|
|
<span class="p">}</span>
|
|
<span class="p">});</span>
|
|
</code></pre></div><h3><a class="anchor" name=""></a>축하합니다! <a class="hash-link" href="#">#</a></h3>
|
|
<p>몇 단계를 거쳐 간단하게 댓글창을 만들어 보았습니다. <a href="/react/docs/why-react-ko-KR.html">왜 React인가</a>에서 더 알아보거나, 혹은 <a href="/react/docs/top-level-api-ko-KR.html">API 레퍼런스</a>에 뛰어들어 해킹을 시작하세요! 행운을 빕니다!</p>
|
|
|
|
|
|
<div class="docs-prevnext">
|
|
|
|
<a class="docs-prev" href="/react/docs/getting-started-ko-KR.html">← Prev</a>
|
|
|
|
|
|
<a class="docs-next" href="/react/docs/thinking-in-react-ko-KR.html">Next →</a>
|
|
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<footer class="wrap">
|
|
<div class="left">
|
|
A Facebook & Instagram collaboration.<br>
|
|
<a href="/react/acknowledgements.html">Acknowledgements</a>
|
|
</div>
|
|
<div class="right">
|
|
© 2013–2016 Facebook Inc.<br>
|
|
Documentation licensed under <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
<div id="fb-root"></div>
|
|
|
|
<script>
|
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
|
ga('create', 'UA-41298772-1', 'facebook.github.io');
|
|
ga('send', 'pageview');
|
|
|
|
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
|
|
|
|
(function(d, s, id) {
|
|
var js, fjs = d.getElementsByTagName(s)[0];
|
|
if (d.getElementById(id)) return;
|
|
js = d.createElement(s); js.id = id;
|
|
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=623268441017527";
|
|
fjs.parentNode.insertBefore(js, fjs);
|
|
}(document, 'script', 'facebook-jssdk'));
|
|
|
|
docsearch({
|
|
apiKey: '36221914cce388c46d0420343e0bb32e',
|
|
indexName: 'react',
|
|
inputSelector: '#algolia-doc-search'
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|