@samitouri / QOS-React-2 / commits / 7eabccc214

Translate 04 to Korean

- Up to e4352ef

Shim Won committed Jan 30, 2015 at 12:20 UTC 7eabccc214c96e74ee049a0f026f43be403e86bb
1 file changed +208
docs/docs/04-multiple-components.ko-KR.md new
+208
@@ -0,0 +1,208 @@
1 +---
2 +id: multiple-components-ko-KR
3 +title: 복합 컴포넌트
4 +permalink: multiple-components.ko-KR.html
5 +prev: interactivity-and-dynamic-uis.ko-KR.html
6 +next: reusable-components.html
7 +---
8 +
9 +지금까지, 단일 컴포넌트에서 데이터를 표시하고 유저 입력을 다루는 것을 살펴보았습니다. 다음엔 React의 최고의 기능 중 하나인 조합가능성(composability)을 살펴봅시다.
10 +
11 +
12 +## 동기: 관심의 분리
13 +
14 +명확히 정의된 인터페이스와 다른 컴포넌트를 재사용해 모듈러 컴포넌트를 구축하면, 함수와 클래스를 이용했을 때 얻을 수 있는 이점 대부분을 얻을 수 있습니다. 특히 앱에서 *다른 관심을 분리*할 수 있습니다.아무리 간단히 새 컴포넌트를 만들었다고 해도 말이죠. 당신의 애플리케이션에서 쓸 커스텀 컴포넌트 라이브러리를 만들어서, 당신의 도메인에 최적화된 방법으로 UI를 표현할 수 있게 됩니다.
15 +
16 +
17 +## 조합(Composition) 예제
18 +
19 +간단히 페이스북 그래프 API를 사용해 프로필 사진과 유저이름을 보여주는 아바타 컴포넌트를 만든다고 합시다.
20 +
21 +```javascript
22 +var Avatar = React.createClass({
23 + render: function() {
24 + return (
25 + <div>
26 + <ProfilePic username={this.props.username} />
27 + <ProfileLink username={this.props.username} />
28 + </div>
29 + );
30 + }
31 +});
32 +
33 +var ProfilePic = React.createClass({
34 + render: function() {
35 + return (
36 + <img src={'http://graph.facebook.com/' + this.props.username + '/picture'} />
37 + );
38 + }
39 +});
40 +
41 +var ProfileLink = React.createClass({
42 + render: function() {
43 + return (
44 + <a href={'http://www.facebook.com/' + this.props.username}>
45 + {this.props.username}
46 + </a>
47 + );
48 + }
49 +});
50 +
51 +React.render(
52 + <Avatar username="pwh" />,
53 + document.getElementById('example')
54 +);
55 +```
56 +
57 +
58 +## 소유권(Ownership)
59 +
60 +위의 예제에서, `Avatar` 인스턴스는 `ProfilePic`과 `ProfileLink`인스턴스를 *가지고* 있습니다. React에서 **소유자는 다른 컴포넌트의 `props`를 설정하는 컴포넌트입니다**. 더 정식으로 말하면, `X` 컴포넌트가 `Y` 컴포넌트의 `render()` 메서드 안에서 만들어졌다면, `Y`가 `X`를 *소유하고* 있다고 합니다. 앞에서 설명한 바와 같이, 컴포넌트는 자신의 `props`를 변경할 수 없습니다. `props`는 언제나 소유자가 설정한 것과 일치합니다. 이와 같은 중요한 성질이 UI가 일관성 있도록 해줍니다.
61 +
62 +소유(owner-ownee)관계와 부모·자식 관계를 구별하는 것은 중요합니다. 부모·자식 관계가 DOM에서부터 쓰던 익숙하고 이미 알고있던 단순한 것인 한편, 소유관계는 React 고유의 것입니다. 위의 예제에서, `Avatar`는 `div`, `ProfilePic`, `ProfileLink`인스턴스를 소유하고, `div`는 `ProfilePic`과 `ProfileLink`인스턴스의 (소유자가 아닌) **부모**입니다.
63 +
64 +
65 +## 자식
66 +
67 +React 컴포넌트 인스턴스를 만들 때, 추가적인 React 컴포넌트나 JavaScript 표현식을 시작과 끝 태그 사이에 넣을 수 있습니다. 이렇게 말이죠.
68 +
69 +```javascript
70 +<Parent><Child /></Parent>
71 +```
72 +
73 +`Parent`는 `this.props.children`라는 특수 prop으로 자식들을 읽을 수 있습니다. **`this.props.children` 는 불투명한 데이터 구조이며,** [React.Children 유틸리티](/react/docs/top-level-api.html#react.children)를 사용해 자식들을 관리합니다.
74 +
75 +
76 +### 자식 Reconciliation
77 +
78 +**Reconciliation은 React가 DOM을 각각 새로운 렌더 패스에 업데이트하는 과정입니다.** 일반적으로, 자식은 렌더하는 순서에 따라 비교조정됩니다. 예를 들어, 각각의 마크업을 생성하는 두 랜더 패스가 있다고 해봅시다.
79 +
80 +```html
81 +// Render Pass 1
82 +<Card>
83 + <p>Paragraph 1</p>
84 + <p>Paragraph 2</p>
85 +</Card>
86 +// Render Pass 2
87 +<Card>
88 + <p>Paragraph 2</p>
89 +</Card>
90 +```
91 +
92 +직관적으로 보면, `<p>Paragraph 1</p>`가 없어졌습니다만 그러는 대신에, React는 첫 번째 자식의 텍스트를 비교조정하고 마지막 자식을 파괴하도록 DOM을 비교조정할 것입니다. React는 자식들의 *순서*에 따라 비교조정합니다.
93 +
94 +
95 +### 상태기반(Stateful) 자식
96 +
97 +대부분의 컴포넌트에서는, 이것은 큰 문제가 아닙니다. 하지만 렌더 패스 간에 `this.state`를 유지하는 상태기반의 컴포넌트에서는 매우 문제가 될 수 있습니다.
98 +
99 +대부분의 경우, 이 문제는 엘리먼트를 파괴하지 않고 숨김으로써 피해갈 수 있습니다.
100 +
101 +```html
102 +// Render Pass 1
103 +<Card>
104 + <p>Paragraph 1</p>
105 + <p>Paragraph 2</p>
106 +</Card>
107 +// Render Pass 2
108 +<Card>
109 + <p style={{'{{'}}display: 'none'}}>Paragraph 1</p>
110 + <p>Paragraph 2</p>
111 +</Card>
112 +```
113 +
114 +
115 +### 동적 자식
116 +
117 +자식들이 섞이거나(검색의 결과같은 경우) 새로운 컴포넌트가 리스트의 앞에 추가(스트림같은 경우)된다면 상황은 점점 더 까다로워집니다. 이런 때에의 동일성과 각 자식의 상태는 반드시 랜더 패스 간에 유지돼야 합니다. 각 자식에 `key`를 할당 함으로써 독자적으로 식별할 수 있습니다.
118 +
119 +```javascript
120 + render: function() {
121 + var results = this.props.results;
122 + return (
123 + <ol>
124 + {results.map(function(result) {
125 + return <li key={result.id}>{result.text}</li>;
126 + })}
127 + </ol>
128 + );
129 + }
130 +```
131 +
132 +React가 키가 있는 자식들을 비교조정할 때, React는 `key`가 있는 자식이 (오염(clobbered)되는 대신) 재배치되고 (재사용되는 대신) 파괴되도록 보장할 것입니다.
133 +
134 +`key`는 *항상* 배열 안의 각 컴포넌트의 컨테이너 HTML 자식이 아닌 컴포넌트에게 직접 주어져야 합니다.
135 +
136 +```javascript
137 +// 틀림!
138 +var ListItemWrapper = React.createClass({
139 + render: function() {
140 + return <li key={this.props.data.id}>{this.props.data.text}</li>;
141 + }
142 +});
143 +var MyComponent = React.createClass({
144 + render: function() {
145 + return (
146 + <ul>
147 + {this.props.results.map(function(result) {
148 + return <ListItemWrapper data={result}/>;
149 + })}
150 + </ul>
151 + );
152 + }
153 +});
154 +
155 +// 맞음 :)
156 +var ListItemWrapper = React.createClass({
157 + render: function() {
158 + return <li>{this.props.data.text}</li>;
159 + }
160 +});
161 +var MyComponent = React.createClass({
162 + render: function() {
163 + return (
164 + <ul>
165 + {this.props.results.map(function(result) {
166 + return <ListItemWrapper key={result.id} data={result}/>;
167 + })}
168 + </ul>
169 + );
170 + }
171 +});
172 +```
173 +
174 +객체를 넘기는 것으로 자식에 키를 할당할 수도 있습니다. 객체 키는 각 값의 `key`로 사용될 것입니다. 하지만 JavaScript가 프로퍼티의 순서의 유지를 보장하지 않는 것을 기억해 두셔야 합니다. 실제 브라우저에서는 32비트의 양의 정수로 해석할 수 있는 프로퍼티를 **제외**하고 프로퍼티의 순서를 유지합니다. 숫자 프로퍼티는 다른 프로퍼티보다 먼저 순차정렬 됩니다. 이런 경우 React는 순서없이 컴포넌트를 렌더합니다. 키에 스트링 접두사를 붙여서 이를 막을 수 있습니다.
175 +
176 +```javascript
177 + render: function() {
178 + var items = {};
179 +
180 + this.props.results.forEach(function(result) {
181 + // result.id가 (짧은 해시처럼) 숫자로 보일 수 있다면,
182 + // 객체의 반복순서는 보장되지 않습니다. 이 경우, 프리픽스를 넣어
183 + // 키가 스트링임을 보장합니다.
184 + items['result-' + result.id] = <li>{result.text}</li>;
185 + });
186 +
187 + return (
188 + <ol>
189 + {items}
190 + </ol>
191 + );
192 + }
193 +```
194 +
195 +## 데이터 흐름
196 +
197 +React에서 데이터는 위에서 말한 것처럼 `props`를 통해 소유자로부터 소유한 컴포넌트로 흐릅니다. 이것은 사실상 단방향 데이터 바인딩입니다. 소유자는 `props`나 `state`를 기준으로 계산한 어떤 값으로 소유한 컴포넌트의 props를 바인드합니다. 이 과정은 재귀적으로 발생하므로, 데이터의 변경은 자동으로 모든 곳에 반영됩니다.
198 +
199 +
200 +## 성능의 주의점
201 +
202 +소유자가 가지고 있는 노드의 수가 많아지면 데이터의 변화에 반응하는 비용이 증가할 것으로 생각할 수도 있습니다. 좋은 소식은 JavaScript가 빠르고 `render()` 메서드는 꽤 간단한 경향이 있어, 대부분 애플리케이션에서 매우 빠르다는 점입니다. 덧붙여, 대부분의 병목 현상은 JS 실행이 아닌 DOM 변경에서 일어나고, React는 배치와 탐지 변경을 이용해 최적화해 줍니다.
203 +
204 +하지만, 가끔 성능을 위해 정교하게 제어해야 할 때도 있습니다. 이런 경우,React가 서브트리의 처리를 건너 뛰도록 간단히 `shouldComponentUpdate()`를 오버라이드해 false를 리턴하게 할 수 있습니다. 좀 더 자세한 정보는 [React 참조 문서](/react/docs/component-specs.html)를 보세요.
205 +
206 +> 주의:
207 +>
208 +> 데이터가 실제로는 변경되었지만 `shouldComponentUpdate()`가 false를 리턴한다면 React는 UI를 싱크시킬수 없습니다. 이 기능을 사용할 때에는 지금 무엇을 하고 있는지 알고있고, 눈에 띄는 성능 문제가 있을경우에만 사용하세요. JavaScript는 DOM에 비교하여 빠릅니다. 과소평가하지 마세요.