Revise Korean translations

This commit is contained in:
Jay Jaeho Lee 2015-02-24 00:56:02 +09:00
parent 35293b5229
commit 3abeb52e6f
21 changed files with 117 additions and 118 deletions

View File

@ -73,12 +73,9 @@ var app = React.createElement(
);
```
[JSX 컴파일러](/react/jsx-compiler.html)를 사용해보면 JSX에서 어떻게 네이티브
JavaScript로 변환하는지(desugars) 볼 수 있고,
[HTML에서 JSX 변환기](/react/html-jsx.html)는 이미 있는 HTML을 JSX로 변환해
줍니다.
[JSX 컴파일러](/react/jsx-compiler.html)를 보면 JSX에서 어떻게 네이티브 JavaScript로 변환(desugars)하는지 볼 수 있고, [HTML-JSX 변환기](/react/html-jsx.html)는 이미 있는 HTML을 JSX로 변환해 줍니다.
JSX를 사용 하시려면, [시작하기](/react/docs/getting-started-ko-KR.html) 가이드에서 어떻게 컴파일을 설정하는지 보실 수 있습니다.
JSX를 사용 하시려면, [시작하기](/react/docs/getting-started-ko-KR.html) 가이드에서 어떻게 컴파일을 하기 위해 설정하는지 보실 수 있습니다.
> 주의:
>
@ -153,8 +150,7 @@ var App = (
### 어트리뷰트 표현식
JavaScript 표현식을 어트리뷰트 값으로 사용하려면, 표현식을 쌍따옴표(`""`)대신
중괄호(`{}`)로 감싸야 합니다.
JavaScript 표현식을 어트리뷰트 값으로 사용하려면, 표현식을 쌍따옴표(`""`)대신 중괄호(`{}`)로 감싸야 합니다.
```javascript
// 입력 (JSX):
@ -168,7 +164,7 @@ var person = React.createElement(
### 자식 표현식
비슷하게, JavaScript 표현식 자식을 표현하는 데 사용할 수 있습니다.
비슷하게, JavaScript 표현식 자식을 표현하는 데 사용할 수 있습니다.
```javascript
// 입력 (JSX):

View File

@ -28,7 +28,7 @@ next: jsx-gotchas-ko-KR.html
## 스프레드 어트리뷰트
이제 JSX 새로운 기능 스프레드 어트리뷰트를 사용하실 수 있습니다.
이제 JSX 새로운 기능 스프레드 어트리뷰트를 사용하실 수 있습니다.
```javascript
var props = {};
@ -39,7 +39,7 @@ next: jsx-gotchas-ko-KR.html
전달한 객체의 프로퍼티가 컴포넌트의 props에 복사됩니다.
것은 여러 번 사용하거나 다른 어트리뷰트와 조합해서 사용할 수 있습니다. 명세 순서는 중요합니다. 나중의 어트리뷰트가 이전 것보다 우선되기 때문입니다.
렇게 여러 번 사용하거나 다른 어트리뷰트와 조합해서 사용할 수 있습니다. 명세 순서는 중요합니다. 나중의 어트리뷰트가 이전 것보다 우선되기 때문입니다.
```javascript
var props = { foo: 'default' };

View File

@ -6,11 +6,11 @@ prev: jsx-spread-ko-KR.html
next: interactivity-and-dynamic-uis-ko-KR.html
---
JSX는 HTML처럼 보이지만 하다 보면 부딪히게 될 몇 가지 중요한 차이점이 있습니다.
JSX는 HTML처럼 보이지만, 작업하다 보면 마주치게 될 몇 가지 중요한 차이점이 있습니다.
> 주의:
>
> 인라인 `style` 어트리뷰트 같은 DOM 차이점은 [여기](/react/docs/dom-differences-ko-KR.html)를 보세요.
> 인라인 `style` 어트리뷰트 같은 DOM과의 차이점은 [여기](/react/docs/dom-differences-ko-KR.html)를 보세요.
## HTML 엔티티
@ -20,7 +20,7 @@ JSX의 리터럴 텍스트에 HTML 엔티티를 넣을 수 있습니다.
<div>First &middot; Second</div>
```
동적 콘텐츠 안에 HTML 엔티티를 표시하려 할 때, React에서는 XSS 공격을 광범위하게 막기 위해 기본적으로 모든 표시하는 문자열을 이스케이프 하기 때문에 더블 이스케이프 문제에 부딪히게 됩니다.
동적 콘텐츠 안에 HTML 엔티티를 표시하려 할 때, React에서는 XSS 공격을 광범위하게 막기 위해 기본적으로 모든 표시하는 문자열을 이스케이프 하기 때문에 더블 이스케이프 문제에 부딪히게 됩니다.
```javascript
// 나쁨: "First &middot; Second"를 표시
@ -46,7 +46,7 @@ JSX의 리터럴 텍스트에 HTML 엔티티를 넣을 수 있습니다.
<div>{['First ', <span>&middot;</span>, ' Second']}</div>
```
최후의 수단으로, 항상 [생 HTML을 삽입](/react/docs/dom-differences-ko-KR.html)할 수 있습니다.
최후의 수단으로, 항상 [생 HTML을 삽입](/react/docs/dom-differences-ko-KR.html)할 수 있습니다.
```javascript
<div dangerouslySetInnerHTML={{'{{'}}__html: 'First &middot; Second'}} />

View File

@ -40,16 +40,16 @@ React.render(
React에서의 이벤트 핸들러는 HTML에서 그러던 것처럼 간단히 카멜케이스 프로퍼티(camelCased prop)로 넘기면 됩니다. React의 모든 이벤트는 통합적인 이벤트 시스템의 구현으로 IE8 이상에서는 같은 행동이 보장됩니다. 즉, React는 사양에 따라 어떻게 이벤트를 일으키고(bubble) 잡는지 알고 있고, 당신이 사용하는 브라우저와 관계없이 이벤트 핸들러에 전달되는 이벤트는 [W3C 사양](http://www.w3.org/TR/DOM-Level-3-Events/)과 같도록 보장됩니다.
React를 폰이나 테블릿같은 터치 디바이스에서 사용하려 한다면, 간단히 `React.initializeTouchEvents(true);`로 터치 이벤트 핸들링을 켜면 됩니다.
React를 폰이나 테블릿같은 터치 디바이스에서 사용하려 한다면, 간단히 `React.initializeTouchEvents(true);`로 터치 이벤트 핸들링을 켜면 됩니다.
## 기본 구현: 오토바인딩과 이벤트 딜리게이션
## 기본 구현: 오토바인딩과 이벤트 델리게이션
코드를 고성능으로 유지하고 이해하기 쉽게 하기 위해 React는 보이는 곳에서 몇 가지 일을 합니다.
코드를 고성능으로 유지하고 이해하기 쉽게 하기 위해, React는 보이지 않는 곳에서 몇 가지 일을 수행합니다.
**오토바인딩:** 자바스크립트에서 콜백을 만들 때, 보통은 `this`의 값이 정확하도록 명시적으로 메서드를 인스턴스에 바인드해야 합니다. React에서는 모든 메서드가 자동으로 React의 컴포넌트 인스턴스에 바인드됩니다. React가 바인드 메서드를 캐시하기 때문에 매우 CPU와 메모리에 효율적입니다. 타이핑해야 할 것도 죠!
**오토바인딩:** 자바스크립트에서 콜백을 만들 때, 보통은 `this`의 값이 정확하도록 명시적으로 메서드를 인스턴스에 바인드해야 합니다. React에서는 모든 메서드가 자동으로 React의 컴포넌트 인스턴스에 바인드됩니다. React가 바인드 메서드를 캐시하기 때문에 매우 CPU와 메모리에 효율적입니다. 타이핑해야 할 것도 줄어들죠!
**이벤트 리게이션:** React는 실제로는 노드자신에게 이벤트 핸들러를 붙이지 않습니다. React가 시작되면 React는 탑 레벨의 단일 이벤트 리스너로 모든 이벤트를 리스닝하기 시작합니다. 컴포넌트가 마운트되거나 언마운트 될 때, 이벤트 핸들러는 그냥 내부 매핑에서 넣거나 뺄 뿐입니다. 이벤트가 발생하면, React는 이 매핑을 사용해서 어떻게 디스패치할 지를 알게 됩니다. 매핑에 이벤트 핸들러가 남아있지 않으면, React의 이벤트 핸들러는 그냥 아무것도 하지 않습니다. 왜 이 방식이 빠른지 더 알고 싶으시면, [David Walsh의 멋진 블로그 글](http://davidwalsh.name/event-delegate)을 읽어 보세요.
**이벤트 리게이션:** React는 실제로는 노드자신에게 이벤트 핸들러를 붙이지 않습니다. React가 시작되면 React는 탑 레벨의 단일 이벤트 리스너로 모든 이벤트를 리스닝하기 시작합니다. 컴포넌트가 마운트되거나 언마운트 될 때, 이벤트 핸들러는 그냥 내부 매핑에서 넣거나 뺄 뿐입니다. 이벤트가 발생하면, React는 이 매핑을 사용해서 어떻게 디스패치할 지를 알게 됩니다. 매핑에 이벤트 핸들러가 남아있지 않으면, React의 이벤트 핸들러는 그냥 아무것도 하지 않습니다. 왜 이 방식이 빠른지 더 알고 싶으시면, [David Walsh의 멋진 블로그 글](http://davidwalsh.name/event-delegate)을 읽어 보세요.
## 컴포넌트는 그냥 state 머신일 뿐
@ -61,7 +61,7 @@ React에서는, 간단히 컴포넌트의 state를 업데이트하고, 이 새
## state의 동작 원리
React에게 데이터의 변경을 알리는 일반적인 방법은 `setState(data, callback)`을 호출하는 것입니다. 이 메서드는 `this.state``data`를 머지하고 컴포넌트를 재 렌더링 합니다. 컴포넌트의 재 렌더링이 끝나면, 생략가능한 `callback`이 호출됩니다. 대부분의 경우 React가 UI를 최신상태로 유지해주기 때문에 `callback`을 사용할 필요가 없습니다.
React에게 데이터의 변경을 알리는 일반적인 방법은 `setState(data, callback)`을 호출하는 것입니다. 이 메서드는 `this.state``data`를 머지하고 컴포넌트를 다시 렌더링 합니다. 컴포넌트의 재-렌더링이 끝나면, 생략가능한 `callback`이 호출됩니다. 대부분의 경우 React가 UI를 최신상태로 유지해주기 때문에 `callback`을 사용할 필요가 없습니다.
## 어떤 컴포넌트가 state를 가져야 할까요?
@ -75,12 +75,12 @@ React에게 데이터의 변경을 알리는 일반적인 방법은 `setState(da
## state를 어떻게 *써야* 할까요?
**state는 컴포넌트의 이벤트 핸들러에 의해 UI 업데이트를 트리거할때 변경될 가능성이 있어, 그때 사용할 데이터를 가져야 합니다.** 실제 에서는 이 데이터는 매우 작고 JSON 직렬화 가능한 경향이 있습니다. 상태기반 컴포넌트를 만들때, 가능한 작게 state를 서술하고 `this.state`에만 저장하도록 해보세요. 그냥 `render()` 안에서 이 state를 기반으로 다른 모든 정보를 계산합니다. 이 방식으로 애플리케이션을 작성하고 생각하면 가장 최적의 애플리케이션으로 발전해가는 경향이 있다는 것을 발견하게 될것입니다. 장황하거나 계산된 값을 state에 추가하는 것은 렌더가 그것을 계산하는 대신에 명시적으로 그것들을 싱크해야 하는 것을 의미하기 때문이죠.
**state는 컴포넌트의 이벤트 핸들러에 의해 UI 업데이트를 트리거할때 변경될 가능성이 있어, 그때 사용할 데이터를 가져야 합니다.** 실제 에서는 이 데이터는 매우 작고 JSON 직렬화 가능한 경향이 있습니다. 상태기반 컴포넌트를 만들때, 가능한 작게 state를 서술하고 `this.state`에만 저장하도록 해보세요. 그냥 `render()` 안에서 이 state를 기반으로 다른 모든 정보를 계산합니다. 이 방식으로 애플리케이션을 작성하고 생각하면 가장 최적의 애플리케이션으로 발전해가는 경향이 있다는 것을 발견하게 될 것입니다. 꼭 필요하지 않은 값이나 계산된 값을 state에 추가하는 것은 render가 그것을 계산하는 대신에 명시적으로 그것들을 맞춰줘야 하는 것을 의미하기 때문이죠.
## state를 어떻게 *쓰지 말아야* 할까요?
`this.state`는 UI의 state를 표현할 최소한의 데이터만 가져야 합니다. 그래서 이런것을들 가지지 말아야 합니다.
`this.state`는 UI의 state를 표현할 최소한의 데이터만을 가져야 합니다. 그래서 이런 것들을 가지지 않게끔 해야 합니다.
* **계산된 데이터:** state에 따라 값을 미리 계산하는 것 염려하지 마세요. 계산은 모두 `render()`에서 하는 것이 UI의 일관성을 유지하기 쉽습니다. 예를 들어, state에서 list items 배열을 가지고 있고 문자열으로 카운트를 렌더링 할 경우, state에 저장하기보다는 그냥 `render()` 메서드안에서 `this.state.listItems.length + ' list items'`를 렌더하세요.
* **계산된 데이터:** state에 따라 값을 미리 계산하는 것에 대해 염려하지 마세요. 계산은 모두 `render()`에서 하는 것이 UI의 일관성을 유지하기 쉽습니다. 예를 들어, state에서 list items 배열을 가지고 있고 문자열으로 카운트를 렌더링 할 경우, state에 저장하기보다는 그냥 `render()` 메서드안에서 `this.state.listItems.length + ' list items'`를 렌더하세요.
* **React 컴포넌트:** 가지고 있는 props와 state로 `render()`안에서 만드세요.
* **props에서 복사한 데이터:** 가능한한 원래의 소스로 props를 사용하도록 해보세요. props를 state에 저장하는 단하나의 올바른 사용법은 이전 값을 알고 싶을 때입니다. props는 시간이 지나면 변경될 수도 있기 때문이죠.
* **props에서 복사한 데이터:** 가능한 한 원래의 소스로 props를 사용하도록 해보세요. props를 state에 저장하는 단 하나의 올바른 사용법은 이전 값을 알고 싶을 때입니다. props는 시간이 지나면 변경될 수도 있기 때문이죠.

View File

@ -57,7 +57,7 @@ React.render(
## 소유권(Ownership)
위의 예제에서, `Avatar` 인스턴스는 `ProfilePic``ProfileLink`인스턴스를 *가지고* 있습니다. React에서 **소유자는 다른 컴포넌트의 `props`를 설정하는 컴포넌트입니다**. 더 정식으로 말하면, `X` 컴포넌트가 `Y` 컴포넌트의 `render()` 메서드 안에서 만들어졌다면, `Y``X`*소유하고* 있다고 합니다. 앞에서 설명한 바와 같이, 컴포넌트는 자신의 `props`를 변경할 수 없습니다. `props`는 언제나 소유자가 설정한 것과 일치합니다. 이와 같은 중요한 성질 UI가 일관성 있도록 해줍니다.
위의 예제에서, `Avatar` 인스턴스는 `ProfilePic``ProfileLink`인스턴스를 *가지고* 있습니다. React에서 **소유자는 다른 컴포넌트의 `props`를 설정하는 컴포넌트입니다**. 더 정식으로 말하면, `X` 컴포넌트가 `Y` 컴포넌트의 `render()` 메서드 안에서 만들어졌다면, `Y``X`*소유하고* 있다고 합니다. 앞에서 설명한 바와 같이, 컴포넌트는 자신의 `props`를 변경할 수 없습니다. `props`는 언제나 소유자가 설정한 것과 일치합니다. 이와 같은 중요한 성질 UI가 일관성 있도록 해줍니다.
소유(owner-ownee)관계와 부모·자식 관계를 구별하는 것은 중요합니다. 부모·자식 관계가 DOM에서부터 쓰던 익숙하고 이미 알고있던 단순한 것인 한편, 소유관계는 React 고유의 것입니다. 위의 예제에서, `Avatar``div`, `ProfilePic`, `ProfileLink`인스턴스를 소유하고, `div``ProfilePic``ProfileLink`인스턴스의 (소유자가 아닌) **부모**입니다.
@ -73,9 +73,9 @@ React 컴포넌트 인스턴스를 만들 때, 추가적인 React 컴포넌트
`Parent``this.props.children`라는 특수 prop으로 자식들을 읽을 수 있습니다. **`this.props.children` 는 불투명한 데이터 구조이며,** [React.Children 유틸리티](/react/docs/top-level-api-ko-KR.html#react.children)를 사용해 자식들을 관리합니다.
### 자식 Reconciliation
### 자식 Reconciliation (비교조정)
**Reconciliation은 React가 DOM을 각각 새로운 렌더 패스에 업데이트하는 과정입니다.** 일반적으로, 자식은 렌더하는 순서에 따라 비교조정됩니다. 예를 들어, 각각의 마크업을 생성하는 두 랜더 패스가 있다고 해봅시다.
**Reconciliation은 React가 DOM을 각각 새로운 렌더 패스에 업데이트하는 과정입니다.** 일반적으로, 자식은 렌더하는 순서에 따라 비교조정됩니다. 예를 들어, 각각의 마크업을 생성하는 두 개의 랜더 패스가 있다고 해봅시다.
```html
// Render Pass 1
@ -114,7 +114,7 @@ React 컴포넌트 인스턴스를 만들 때, 추가적인 React 컴포넌트
### 동적 자식
자식들이 섞이거나(검색의 결과같은 경우) 새로운 컴포넌트가 리스트의 앞에 추가(스트림같은 경우)된다면 상황은 점점 더 까다로워집니다. 이런 때에의 동일성과 각 자식의 상태는 반드시 랜더 패스 간에 유지돼야 합니다. 각 자식에 `key`를 할당 함으로써 독자적으로 식별할 수 있습니다.
자식들이 섞이거나(검색의 결과같은 경우) 새로운 컴포넌트가 리스트의 앞에 추가(스트림같은 경우)된다면 상황은 점점 더 까다로워집니다. 이런 때에의 동일성과 각 자식의 상태는 반드시 랜더 패스 간에 유지돼야 합니다. 각 자식에 `key`를 할당 함으로써 독자적으로 식별할 수 있습니다.
```javascript
render: function() {
@ -171,7 +171,7 @@ var MyComponent = React.createClass({
});
```
객체를 넘기는 것으로 자식에 키를 할당할 수도 있습니다. 객체 키는 각 값의 `key`로 사용될 것입니다. 하지만 JavaScript가 프로퍼티의 순서의 유지를 보장하지 않는 것을 기억해 두셔야 합니다. 실제 브라우저에서는 32비트의 양의 정수로 해석할 수 있는 프로퍼티를 **제외**하고 프로퍼티의 순서를 유지합니다. 숫자 프로퍼티는 다른 프로퍼티보다 먼저 순차정렬 됩니다. 이런 경우 React는 순서없이 컴포넌트를 렌더합니다. 키에 스트링 접두사를 붙여서 이를 막을 수 있습니다.
객체를 넘기는 것으로 자식에 키를 할당할 수도 있습니다. 객체 키는 각 값의 `key`로 사용될 것입니다. 하지만 JavaScript가 프로퍼티의 순서의 유지를 보장하지 않는 것을 기억해 두셔야 합니다. 실제 브라우저에서는 32비트의 양의 정수로 해석할 수 있는 프로퍼티를 **제외**하고 프로퍼티의 순서를 유지합니다. 숫자 프로퍼티는 다른 프로퍼티보다 먼저 순차정렬 됩니다. 이런 경우 React는 순서없이 컴포넌트를 렌더합니다. 키에 스트링 접두사를 붙여서 이를 막을 수 있습니다.
```javascript
render: function() {
@ -199,10 +199,10 @@ React에서 데이터는 위에서 말한 것처럼 `props`를 통해 소유자
## 성능의 주의점
소유자가 가지고 있는 노드의 수가 많아지면 데이터의 변화에 반응하는 비용이 증가할 것으로 생각할 수도 있습니다. 좋은 소식은 JavaScript 빠르고 `render()` 메서드는 꽤 간단한 경향이 있어, 대부분 애플리케이션에서 매우 빠르다는 점입니다. 덧붙여, 대부분의 병목 현상은 JS 실행이 아닌 DOM 변경에서 일어나고, React는 배치와 탐지 변경을 이용해 최적화해 줍니다.
소유자가 가지고 있는 노드의 수가 많아지면 데이터의 변화에 반응하는 비용이 증가할 것으로 생각할 수도 있습니다. 좋은 소식은 JavaScript의 속도는 빠르고 `render()` 메서드는 꽤 간단한 경향이 있어, 대부분 애플리케이션에서 매우 빠르다는 점입니다. 덧붙여, 대부분의 병목 현상은 JS 실행이 아닌 DOM 변경에서 일어나고, React는 배치와 탐지 변경을 이용해 최적화해 줍니다.
하지만, 가끔 성능을 위해 정교하게 제어해야 할 때도 있습니다. 이런 경우,React가 서브트리의 처리를 건너 뛰도록 간단히 `shouldComponentUpdate()`를 오버라이드해 false를 리턴하게 할 수 있습니다. 좀 더 자세한 정보는 [React 참조 문서](/react/docs/component-specs-ko-KR.html)를 보세요.
하지만, 가끔 성능을 위해 정교하게 제어해야 할 때도 있습니다. 이런 경우, React가 서브트리의 처리를 건너 뛰도록 간단히 `shouldComponentUpdate()`를 오버라이드해 false를 리턴하게 할 수 있습니다. 좀 더 자세한 정보는 [React 참조 문서](/react/docs/component-specs-ko-KR.html)를 보세요.
> 주의:
>
> 데이터가 실제로는 변경되었지만 `shouldComponentUpdate()`가 false를 리턴한다면 React는 UI를 싱크시킬수 없습니다. 이 기능을 사용할 때에는 지금 무엇을 하고 있는지 알고있고, 눈에 띄는 성능 문제가 있을경우에만 사용하세요. JavaScript는 DOM에 비교하여 빠릅니다. 과소평가하지 마세요.
> 데이터가 실제로는 변경되었지만 `shouldComponentUpdate()`가 false를 리턴한다면 React는 UI를 싱크시킬수 없습니다. 이 기능을 사용할 때에는 자신이 지금 무엇을 하고 있는지 알고 있고, 눈에 띄는 성능 문제가 있을 경우에만 사용하세요. JavaScript는 DOM에 비 빠릅니다. 과소평가하지 마세요.

View File

@ -101,10 +101,9 @@ React에서 `<input>`같은 폼 컴포넌트를 사용하면, 전통적인 폼 H
<input type="text" name="title" value="Untitled" />
```
이렇게 하면 input은 `Untitled` 값으로 *초기화* 됩니다. 사용자가 input을 업데이트할 때, 노드의 value *프로퍼티*가 변경될 것입니다. 하지만, `node.getAttribute('value')`은 여전히 초기화 때 사용했던 값인 `Untitled`를 리턴합니다.
이렇게 하면 input은 `Untitled` 값으로 *초기화* 됩니다. 사용자가 input을 업데이트할 때, 노드의 value *프로퍼티*가 변경될 것입니다. 하지만, `node.getAttribute('value')`은 여전히 초기화 때 사용했던 값인 `Untitled`를 리턴합니다.
HTML과 다르게, React 컴포넌트는 초기화 시점 뿐만 아니라, 어떤 시점이라도 반드시
뷰의 state를 나타내야 합니다. 예를 들어 React에서
HTML과 다르게, React 컴포넌트는 초기화 시점 뿐만 아니라, 어떤 시점이라도 반드시 뷰의 state를 나타내야 합니다. 예를 들어 React에서
```javascript
render: function() {

View File

@ -23,11 +23,11 @@ next: addons-ko-KR.html
### 브라우저에서 JSX 변환
JSX를 사용하신다면, [다운로드 페이지](/react/downloads.html)에서 브라우저 JSX 변환기를 제공합니다. 간단히 `<script type="text/jsx">`인클루드하면 JSX 변환기가 작동합니다.
JSX를 사용하신다면, [다운로드 페이지](/react/downloads.html)에서 브라우저 JSX 변환기를 제공합니다. 간단히 `<script type="text/jsx">`넣으면 JSX 변환기가 작동합니다.
> 주의:
>
> 브라우저 JSX 변환기는 꽤 크고 안 할 수도 있는 클라이언트 측 연산을 하게 됩니다. 프로덕션에서 사용하지 마시고, 다음 단락을 보세요.
> 브라우저 JSX 변환기는 꽤 크고 안 할 수도 있는 클라이언트 측 연산을 하게 됩니다. 프로덕션 환경에서 사용하지 마시고, 다음 단락을 보세요.
### 상용화하기: 미리 컴파일된 JSX

View File

@ -8,18 +8,18 @@ next: animation-ko-KR.html
`React.addons`은 React 앱을 만드는 데 유용한 유틸리티를 두는 곳입니다. **실험적인 기능으로 취급해야 하지만** 결국 코어나 유틸리티 라이브러리에 포함될 예정입니다.
- [`TransitionGroup` 과 `CSSTransitionGroup`](animation-ko-KR.html)은 예를들면 컴포넌트 삭제 이전 처럼, 구현하기 까다로운 애니메이션과 트랜지션을 다룹니다.
- [`TransitionGroup` 과 `CSSTransitionGroup`](animation-ko-KR.html)은 예를 들면 컴포넌트 삭제 직전의 트랜지션 처럼, 구현하기 까다로운 애니메이션과 트랜지션을 다룹니다.
- [`LinkedStateMixin`](two-way-binding-helpers-ko-KR.html)는 사용자 입력과 컴포넌트의 state사이의 조정(coordination)을 단순화 합니다.
- [`classSet`](class-name-manipulation-ko-KR.html)는 좀 더 알기 쉽게 DOM `class` 스트링을 다룹니다.
- [`cloneWithProps`](clone-with-props-ko-KR.html)는 React 컴포넌트를 얕은 복사를 하고 props를 변경합니다.
- [`update`](update-ko-KR.html)는 JavaScript안에서 불변 데이터를 다루기 쉽게하는 퍼 함수입니다.
- [`update`](update-ko-KR.html)는 JavaScript안에서 불변 데이터를 다루기 쉽게하는 퍼 함수입니다.
- [`PureRenderMixin`](pure-render-mixin-ko-KR.html)는 특정 상황에서 성능을 향상시켜 줍니다.
밑에 있는 애드온은 React 개발 (압축되지 않은) 버전에서만 사용가능 합니다.
- [`TestUtils`](test-utils-ko-KR.html)는 테스트 케이스를 적기위한 간단한 헬퍼입니다. (압축되지않은 빌드에서만 사용가능)
- [`TestUtils`](test-utils-ko-KR.html)는 테스트 케이스를 적기 위한 간단한 헬퍼입니다. (압축되지 않은 빌드에서만 사용가능)
- [`Perf`](perf-ko-KR.html)는 성능을 측정하고, 최적화를 위한 힌트를 제공합니다.
애드온을 쓰려면, 보통 `react.js` 대신 `react-with-addons.js`(혹은 압축판)을 사용해야 합니다.
npm을 이용해 React 패키지를 설치해 사용한다면, 그냥 `require('react')` 대신 `require('react/addons')`을 사용해 모든 드온을 쓸 수 있습니다.
npm을 이용해 React 패키지를 설치해 사용한다면, 그냥 `require('react')` 대신 `require('react/addons')`을 사용해 모든 드온을 쓸 수 있습니다.

View File

@ -8,7 +8,7 @@ next: pure-render-mixin-ko-KR.html
React에서는 mutation을 포함해 어떤 데이터 관리 방식도 사용하실 수 있습니다. 하지만 애플리케이션의 성능이 중요한 부분에서 불변의(immutable) 데이터를 사용할 수 있다면, 쉽게 빠른 `shouldComponentUpdate()` 메서드를 구현해 애플리케이션의 속도를 크게 향상시킬 수 있습니다.
JavaScript에서 변할 수 없는 데이터를 다루는것은 [Clojure](http://clojure.org/)처럼 그것을 위해 디자인된 언어보다 어렵습니다. 하지만, React는 간단한 불변성 헬퍼를 제공합니다. `update()`는 이런 종류의 데이터를 근본적인 변화 *없이* 쉽게 다루도록 해줍니다.
JavaScript에서 불변성의 데이터를 다루는 것은 [Clojure](http://clojure.org/)같이 그것을 위해 디자인된 언어로 다루는 것보다는 어렵습니다. 하지만, React는 간단한 불변성 헬퍼를 제공합니다. `update()`는 이런 종류의 데이터를 근본적인 변화 *없이* 쉽게 다루도록 해줍니다.
## 주요 아이디어
@ -28,7 +28,7 @@ newData.x.y.z = 7;
newData.a.b.push(9);
```
하지만 깊은 복사는 비싸고, 가끔은 불가능하기도 합니다. 변화가 필요한 객체만 복제하고, 변화 없는 객체를 다시 사용함으로써 완화를 시킬수는 있습니다. 안타깝지만 오늘날의 JavaScript에서는 성가실 수 있습니다:
하지만 깊은 복사는 비싸고, 가끔은 불가능하기도 합니다. 변화가 필요한 객체만 복제하고, 변화가 없는 객체는 다시 사용하는 방법으로만 비용을 줄일 수 있습니다. 안타깝지만 오늘날의 JavaScript에서는 그 방법이 성가실 수 있습니다:
```js
var newData = extend(myData, {
@ -39,9 +39,9 @@ var newData = extend(myData, {
});
```
이것은 꽤 성능이 좋긴 하지만 (`log n`개의 객체만 얕은 복사하고, 나머지는 재사용하기 때문에), 쓰기엔 큰 고통이 따릅니다. 이 반복들을 보세요! 이건 짜증날 뿐만 아니라 버그들을 야기할수도 있습니다.
이것은 꽤 성능이 좋긴 하지만 (`log n`개의 객체만 얕은 복사하고, 나머지는 재사용하기 때문에), 일일히 쓰기엔 큰 고통이 따릅니다. 이 반복들을 보세요! 이건 짜증날 뿐만 아니라 버그들을 야기할수도 있습니다.
`update()`는 이런 패턴 속에서 코드를 더 쉽게 쓸 수 있도록 편의문법을 제공합니다. 코드는 이렇게 됩니다:
`update()`는 이런 패턴 속에서 코드를 더 쉽게 쓸 수 있도록 편의 문법을 제공합니다. 코드는 이렇습니다:
```js
var newData = React.addons.update(myData, {
@ -50,7 +50,7 @@ var newData = React.addons.update(myData, {
});
```
([MongoDB 쿼리 언어](http://docs.mongodb.org/manual/core/crud-introduction/#query)에서 영감을 받은) 이 문법에 익숙해지기에는 시간이 조금 걸리긴 하지만, 쓸모 없는 반복이 없고 정적분석이 가능할 뿐더러 변할 수 있는 버전보다 더 많은 타이핑이 필요하지도 않습니다.
([MongoDB 쿼리 언어](http://docs.mongodb.org/manual/core/crud-introduction/#query)에서 영감을 받은) 이 문법에 익숙해지기에는 시간이 조금 걸리긴 하지만, 쓸모 없는 반복이 없고 정적분석이 가능할 뿐더러 변할 수 있는(mutative) 버전보다 더 많은 타이핑이 필요하지도 않습니다.
`$`가 앞에 붙어있는 키들은 *커맨드* 라고 불립니다. "변하는" 자료 구조는 *타겟* 이라고 불립니다.

View File

@ -1,8 +1,8 @@
---
id: examples-ko-KR
title: 예제
title: 예제
permalink: examples-ko-KR.html
prev: complementary-tools-ko-KR.html
---
이 페이지는 이동 되었습니다. [GitHub wiki](https://github.com/facebook/react/wiki/Examples).
이 페이지는 이동되었습니다. [GitHub wiki](https://github.com/facebook/react/wiki/Examples).

View File

@ -1,6 +1,7 @@
---
id: flux-overview-ko-KR
title: Flux 애플리케이션 아키텍쳐
permalink: flux-overview-ko-KR.html
---
이 페이지는 Flux 웹사이트로 이동하였습니다. [거기서 보세요](http://facebook.github.io/flux/docs/overview.html).
이 페이지는 Flux 웹사이트로 이동되었습니다. [거기서 보세요](http://facebook.github.io/flux/docs/overview.html).

View File

@ -1,6 +1,7 @@
---
id: flux-overview
title: Flux Application Architecture
permalink: flux-overview.html
---
This page has been moved to the Flux website. [View it there](http://facebook.github.io/flux/docs/overview.html).

View File

@ -1,6 +1,7 @@
---
id: flux-todo-list-ko-KR
title: Flux TodoMVC 튜토리얼
permalink: flux-todo-list-ko-KR.html
---
이 페이지는 Flux 웹사이트로 이동하였습니다. [거기서 보세요](http://facebook.github.io/flux/docs/todo-list.html).
이 페이지는 Flux 웹사이트로 이동되었습니다. [거기서 보세요](http://facebook.github.io/flux/docs/todo-list.html).

View File

@ -1,6 +1,7 @@
---
id: flux-todo-list
title: Flux TodoMVC Tutorial
permalink: flux-todo-list.html
---
This page has been moved to the Flux website. [View it there](http://facebook.github.io/flux/docs/todo-list.html).

View File

@ -12,7 +12,7 @@ React는 모든 공통 엘리먼트를 지원하려 합니다. 필요한 엘리
### HTML 엘리먼트
이런 HTML 엘리먼트가 지원됩니다.
다음의 HTML 엘리먼트가 지원됩니다.
```
a abbr address area article aside audio b base bdi bdo big blockquote body br
@ -27,7 +27,7 @@ thead time title tr track u ul var video wbr
### SVG 엘리먼트
이런 SVG 엘리먼트가 지원됩니다.
다음의 SVG 엘리먼트가 지원됩니다.
```
circle defs ellipse g line linearGradient mask path pattern polygon polyline

View File

@ -8,9 +8,9 @@ next: dom-differences-ko-KR.html
## 통합적인(Synthetic) 이벤트
이벤트 핸들러는 브라우저의 네이티브 이벤트의 크로스 브라우저 래퍼인`SyntheticEvent`의 인스턴스에 전달됩니다. 모든 브라우저에서 동작한다는 점을 제외하면, `SyntheticEvent``stopPropagation()``preventDefault()`를 포함해, 브라우저의 네이티브 이벤트와 같은 인터페이스를 가지고 있습니다.
이벤트 핸들러는 브라우저의 네이티브 이벤트의 크로스 브라우저 래퍼(wrapper)인`SyntheticEvent`의 인스턴스에 전달됩니다. 모든 브라우저에서 동작한다는 점을 제외하면, `SyntheticEvent``stopPropagation()``preventDefault()`를 포함해, 브라우저의 네이티브 이벤트와 같은 인터페이스를 가지고 있습니다.
어떤 이유로 기본 브라우저 이벤트가 필요하다면, 그냥 `nativeEvent`를 사용해 할 수 있습니다. 모든 `SyntheticEvent` 객체는 이런 어트리뷰트를 가집니다.
어떤 이유로 기본 브라우저 이벤트가 필요하다면, 그냥 `nativeEvent`를 사용해 할 수 있습니다. 모든 `SyntheticEvent` 객체는 이런 어트리뷰트를 가집니다.
```javascript
boolean bubbles
@ -36,7 +36,7 @@ string type
React는 다른 브라우저에서 일관된 특성을 가지도록 이벤트를 일반화합니다.
밑에 있는 이벤트 핸들러들은 일으키는(bubbling) 단계에서 이벤트를 트리거합니다. 이벤트 핸들러를 캡처 단계로 등록하려면, 이벤트 이름에 `Capture`를 붙이면 됩니다. 예를 들어, 캡처 단계의 클릭 이벤트를 다루려면 `onClick`를 사용하는 대신에 `onClickCapture`를 사용해야 합니다.
밑에 있는 이벤트 핸들러들은 일으키는(bubbling) 단계에서 이벤트를 트리거합니다. 이벤트 핸들러를 캡처 단계로 등록하려면, 이벤트 이름에 `Capture`를 붙이면 됩니다. 예를 들어, 캡처 단계의 클릭 이벤트를 다루려면 `onClick`를 사용하는 대신에 `onClickCapture`를 사용해야 합니다.
### 클립보드 이벤트

View File

@ -1,12 +1,12 @@
---
id: dom-differences-ko-KR
title: DOM 차이점
title: DOM과의 차이점
permalink: dom-differences-ko-KR.html
prev: events-ko-KR.html
next: special-non-dom-attributes-ko-KR.html
---
React는 성능과 크로스 브라우저 호환성을 이유로 브라우저에 독립적인 이벤트와 DOM 시스템으로 구현되었습니다. 브라우저 DOM 구현의 거친 부분을 정리할 기회를 가졌습니다.
React는 성능과 크로스 브라우저 호환성을 이유로 브라우저에 독립적인 이벤트와 DOM 시스템으로 구현되었습니다. 브라우저 DOM 구현의 일관성없는 부분들을 정리할 기회를 가졌습니다.
* 모든 DOM 프로퍼티와 어트리뷰트는 (이벤트 핸들러를 포함해) 표준 JavaScript 스타일과 일치하도록 카멜케이스를 사용해야 합니다. **하지만**, `data-*``aria-*` 어트리뷰트는 [사양을 준수해](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes#data-*) 소문자만 사용해야 합니다.
* `style` 어트리뷰트는 CSS 문자열 대신에 카멜케이스로 된 프로퍼티를 가지는 JavaScript 객체를 받습니다. 이는 DOM `style` JavaScript 프로퍼티와 일치하면서도 좀 더 효율적이며, XSS 보안 취약점을 예방할 수 있습니다.

View File

@ -5,7 +5,7 @@ permalink: glossary-ko-KR.html
prev: reconciliation-ko-KR.html
---
다음은 React에서 사용되는 용어들로, 이 다섯 가지 타입을 구별하는 것은 중요합니다.
다음은 React에서 사용되는 용어들로, 이 다섯 가지 타입을 구별하는 것은 중요합니다.
- [ReactElement / ReactElement 팩토리](#react-elements)
- [ReactNode](#react-nodes)
@ -62,7 +62,7 @@ var root = div({ className: 'my-div' });
React.render(root, document.body);
```
React에는 이미 보통 HTML 태그를 위한 팩토리가 내장되어 있습니다:
React에는 이미 보통 HTML 태그를 위한 팩토리가 내장되어 있습니다:
```javascript
var root = React.DOM.ul({ className: 'my-list' },

View File

@ -33,15 +33,15 @@ React의 많은 뛰어난 점들 중 하나는 생각을 하면서 애플리케
## 1단계: UI를 계층 구조의 컴포넌트로 분쇄하세요.
당신이 하고싶은 첫번째는 모형에 있는 모든 컴포넌트 (그리고 자식요소) 주위에 상자를 그리고, 이름을 부여하는 것입니다. 만약 당신이 디자이너와 같이 작업중이라면, 그들은 이미 이 작업을 해놨을지도 모릅니다. 당장 가서 이야기해보세요. 그들의 포토샵 레이어 이름이 결국 당신의 React 컴포넌트들의 이름이 될것입니다.
당신이 하고싶은 첫번째는 모형에 있는 모든 컴포넌트 (그리고 자식요소) 주위에 상자를 그리고, 이름을 부여하는 것입니다. 만약 당신이 디자이너와 같이 작업중이라면, 그들은 이미 이 작업을 해놨을지도 모릅니다. 당장 가서 이야기해보세요. 그들의 포토샵 레이어 이름이 결국 당신의 React 컴포넌트들의 이름이 될 것입니다.
그런데 무엇이 컴포넌트가 되어야 할까요? 당신이 새로운 함수나 객체를 만들어야만 한다면, 똑같이 적용하세요. 한가지 방법은 [단일 책임의 원칙](http://ko.wikipedia.org/wiki/%EB%8B%A8%EC%9D%BC_%EC%B1%85%EC%9E%84_%EC%9B%90%EC%B9%99) 입니다. 즉 하나의 컴포넌트는 이상적으로 한가지 작업만 수행해야합니다. 컴포넌트가 결국 커진다면 작은 자식 컴포넌트로 쪼개져야 합니다.
그런데 무엇이 컴포넌트가 되어야 할까요? 당신이 새로운 함수나 객체를 만들어야만 한다면, 똑같이 적용하세요. 한가지 방법은 [단일 책임의 원칙](http://ko.wikipedia.org/wiki/%EB%8B%A8%EC%9D%BC_%EC%B1%85%EC%9E%84_%EC%9B%90%EC%B9%99) 입니다. 즉 하나의 컴포넌트는 이상적으로 한가지 작업만 수행해야 합니다. 컴포넌트가 결국 커진다면 작은 자식 컴포넌트로 쪼개져야 합니다.
주로 JSON 데이터 모델을 사용자에게 보여주기 때문에, 자료 모델이 잘 설계 되었다면 UI(혹은 컴포넌트 구조)가 잘 맞아떨어진다는 것을 알게될겁니다. UI와 자료 모델은 같은 *정보 설계구조*로 따라가는 경향이 있기 때문입니다. 즉, UI를 컴포넌트들로 쪼개는 작업은 크게 어렵지 않습니다. 확실하게 각각 하나의 부분이 되도록 쪼개세요.
주로 JSON 데이터 모델을 사용자에게 보여주기 때문에, 자료 모델이 잘 설계 되었다면 UI(혹은 컴포넌트 구조)가 잘 맞아 떨어진다는 것을 알게 겁니다. UI와 자료 모델은 같은 *정보 설계구조*로 따라가는 경향이 있기 때문입니다. 즉, UI를 컴포넌트들로 쪼개는 작업은 크게 어렵지 않습니다. 확실하게 각각 하나의 부분이 되도록 쪼개세요.
![Component diagram](/react/img/blog/thinking-in-react-components.png)
이 간단한 애플리케이션에는 다섯개의 컴포넌트가 있습니다. 각 컴포넌트들이 대표하는 자료를 이탤릭체로 표기했습니다.
이 간단한 애플리케이션에는 다섯개의 컴포넌트가 있습니다. 각 컴포넌트들이 대표하는 자료를 기울여 표기했습니다.
1. **`FilterableProductTable` (오렌지):** 예제 전부를 포함합니다.
2. **`SearchBar` (파랑):** 모든 *사용자 입력* 을 받습니다.
@ -49,9 +49,9 @@ React의 많은 뛰어난 점들 중 하나는 생각을 하면서 애플리케
4. **`ProductCategoryRow` (청록):** 각 *카테고리*의 제목을 보여줍니다.
5. **`ProductRow` (빨강):** 각 *프로덕트*를 보여줍니다.
`ProductTable`을 보면 테이블 제목("Name", "Price" 라벨들을 포함한)은 컴포넌트가 아닌것을 알 수 있습니다. 이건 기호의 문제이고, 어느쪽으로 만들던 논쟁거리입니다. 예를들어 저는 *자료 모음*을 그리는 `ProductTable`의 의무라고 생각했기 때문에 남겨 두었습니다. 하지만 이 제목이 복잡해진다면 (예를들어 정렬을 추가할 여유가 있다거나 하는), 이건 확실히 `ProductTableHeader` 컴포넌트로 만드는게 맞을겁니다.
`ProductTable`을 보면 테이블 제목("Name", "Price" 라벨들을 포함한)은 컴포넌트가 아닌것을 알 수 있습니다. 이건 기호의 문제이고, 어느쪽으로 만들던 논쟁거리입니다. 예를 들어 저는 *자료 모음*을 그리는 `ProductTable`의 의무라고 생각했기 때문에 남겨 두었습니다. 하지만 이 제목이 복잡해진다면 (예를 들어 정렬을 추가할 여유가 있다거나 하는), 이건 확실히 `ProductTableHeader` 컴포넌트로 만드는 것이 맞을 겁니다.
이제 모형에 들어있는 컴포넌트들에 대해 알아보았으니, 계층 구조로 만들어 봅시다. 이건 쉽습니다. 다른 컴포넌트 속에 들어있는 컴포넌트를 그저 자식으로 나타내면 됩니다.
이제 모형에 들어있는 컴포넌트들에 대해 알아보았으니, 계층 구조로 만들어 봅시다. 이건 쉽습니다. 다른 컴포넌트 속에 들어있는 컴포넌트를 자식으로 나타내기만 하면 됩니다.
* `FilterableProductTable`
* `SearchBar`
@ -63,32 +63,32 @@ React의 많은 뛰어난 점들 중 하나는 생각을 하면서 애플리케
<iframe width="100%" height="300" src="https://jsfiddle.net/reactjs/yun1vgqb/embedded/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
계층구조의 컴포넌트들을 가지고 있으니, 이젠 애플리케이션을 구현할 시간입니다. 가장 쉬운 방법은 상호작용을 하지 않는채로 자료 모델을 이용해 UI를 그리는 것입니다. 정적 버전을 만드는데는 적은 생각과 많은 노동이 필요하고, 상호작용을 추가하는데는 많은 생각과 적은 노동이 필요하기때문에 둘을 분리하는게 쉽습니다. 왜그런지 봅시다.
계층구조의 컴포넌트들을 가지고 있으니, 이젠 애플리케이션을 구현할 시간입니다. 가장 쉬운 방법은 상호작용을 하지 않는 채로 자료 모델을 이용해 UI를 그리는 것입니다. 정적 버전을 만드는 는 적은 생각과 많은 노동이 필요하고, 상호작용을 추가하는 는 많은 생각과 적은 노동이 필요하기 때문에 둘을 분리하는 것은 쉽습니다. 왜 그런지 봅시다.
자료 모델을 그리는 애플리케이션의 정적버전을 만들기 위해서, 다른 컴포넌트에 재사용할 컴포넌트를 만들고 자료 전달을 위해 *props*를 사용하고 싶을 것입니다. 만약 *상태*라는 개념에 익숙하다면, 정적 버전을 만들때 **절대 상태를 사용하지 마세요**. 상태는 오직 상호작용, 즉 가변적인 자료를 위해서만 준비되어 있습니다. 정적 버전을 만들때는 필요가 없다는 겁니다.
자료 모델을 그리는 애플리케이션의 정적버전을 만들기 위해서, 다른 컴포넌트에 재사용할 컴포넌트를 만들고 자료 전달을 위해 *props*를 사용하고 싶을 것입니다. 만약 *상태*라는 개념에 익숙하다면, 정적 버전을 만들때 **절대 상태를 사용하지 마세요**. 상태는 오직 상호작용, 즉 가변적인 자료를 위해서만 준비되어 있습니다. 정적 버전을 만들 때는 필요가 없습니다.
껍데기부터 혹은 속알맹이부터 만들 수 있습니다. 즉 계층구조상 위에서부터 (`FilterableProductTable` 부터) 혹은 아래에서부터 (`ProductRow`), 어느 방향에서든 시작해도 됩니다. 통상 큰 프로젝트에서는 계층구조상 위에서부터 시작하는게 쉽고, 테스트를 작성할때는 아래에서부터 시작하는게 쉽습니다.
껍데기부터 혹은 속알맹이부터 만들 수 있습니다. 즉 계층구조상 위에서부터 (`FilterableProductTable` 부터) 혹은 아래에서부터 (`ProductRow`), 어느 방향에서든 시작해도 됩니다. 통상 큰 프로젝트에서는 계층구조상 위에서부터 시작하는 것이 쉽고, 테스트를 작성할때는 아래에서부터 시작하는 것이 쉽습니다.
이 단계의 결과, 자료 모델을 그리는 재활용 가능한 컴포넌트의 라이브러리를 갖게 되었습니다. 정적버전 이후로 컴포넌트들은 오직 `render()` 메서드만 갖고 있습니다. 계층구조상 가장 위의 컴포넌트 (`FilterableProductTable`)은 자료 모델을 prop으로 취할 것입니다. 자료 모델이 변했을 때, `React.render()`를 다시 부르면 업데이트 됩니다. 어떻게 UI가 업데이트 되는지 참 알기 쉽습니다. 자료가 바뀌어도 처리해야 할 복잡한 일이 아무것도 없습니다. React의 **단일 방향 자료 흐름** (혹은 *단일방향 바인딩*)이 모든것을 모듈식으로, 추론하기 쉽게, 그리고 빠르게 유지해줍니다.
이 단계를 진행하는데 도움이 필요하시다면, [React 문서](http://facebook.github.io/react/docs/)를 참조하세요.
이 단계를 진행하는 도움이 필요하시다면, [React 문서](http://facebook.github.io/react/docs/)를 참조하세요.
### 잠시만: props vs state
React 에는 두가지 타입의 자료 "모델"이 있습니다: props 와 state. 두가지의 구분점을 이해하는데 매우 중요합니다; 혹시 차이점을 확신하지 못한다면 걷어내세요 [공식 문서](http://facebook.github.io/react/docs/interactivity-and-dynamic-uis-ko-KR.html).
React 에는 두가지 타입의 자료 "모델"이 있습니다: props 와 state. 두가지의 구분점을 이해하는데 매우 중요합니다; 혹시 차이점을 확신하지 못한다면 걷어내세요 [공식 문서](/react/docs/interactivity-and-dynamic-uis-ko-KR.html).
## 3단계: UI state 의 표현을 작지만 완전하도록 확인하세요.
상호적인 UI를 만들기 위해서는 자료 모델 변화에 반응할 수 있어야 합니다. React는 **state**로 이걸 쉽게 만들어주죠.
올바르게 애플리케이션을 만들기 위해서는 첫째로 애플리케이션에 필요한 변할 수 있는 state 들의 최소한의 집합에 대해서 생각해볼 필요가 있습니다. 여기 방법이 있습니다: *스스로 반복하지 마세요*. 애플리케이션의 상태를 나타낼 수 있는 가장 최소한의 표현 방식을 찾고, 그 밖의 것은 필요할 때 계산합니다. 예를들어 TODO 리스트를 만든다고 칩시다. TODO 아이템들의 배열만 유지하세요; 갯수를 표현하기 위한 state 변수를 분리하지 마세요. 대신 TODO 아이템들 배열의 길이를 이용하세요.
올바르게 애플리케이션을 만들기 위해서는 첫째로 애플리케이션에 필요한 변할 수 있는 state 들의 최소한의 집합에 대해서 생각해볼 필요가 있습니다. 여기 방법이 있습니다: *스스로 반복하지 마세요* (DRY). 애플리케이션의 상태를 나타낼 수 있는 가장 최소한의 표현 방식을 찾고, 그 밖의 것은 필요할 때 계산합니다. 예를들어 TODO 리스트를 만든다고 칩시다. TODO 아이템들의 배열만 유지하세요; 갯수를 표현하기 위한 state 변수를 분리하지 마세요. 대신 TODO 아이템들 배열의 길이를 이용하세요.
예제 애플리케이션에서의 모든 자료유형에 대해 생각해 봅시다:
* product 들의 원본 리스트
* 사용자가 입력한 검색어
* 체크박스의 값
* product 들의 걸러진 리스트
* product 들의 필터된 리스트
어느것이 state 가 될지 따져봅시다. 간단하게 각 자료에 대해 세가지만 생각해 보세요.
@ -96,7 +96,7 @@ React 에는 두가지 타입의 자료 "모델"이 있습니다: props 와 stat
2. 종종 바뀝니까? 아니라면 이것 역시 state가 아닙니다.
3. 컴포넌트에 있는 다른 state나 props를 통해서 계산되어질 수 있습니까? 역시 state가 아닙니다.
product 들의 원본 리스트는 props를 통해서 전달되기 때문에, state가 아닙니다. 검색어와 체크박스의 값은 다른것에 의해 계산될 수 있는 값이 아니고, 시시각각 변하기때문에 state가 맞습니다. 마지막으로 product 들의 걸러진 리스트 역시 state가 아닙니다. 원본 리스트와 검색어, 체크박스의 값등에 의해 연산되어지는 값이기 때문이죠.
product 들의 원본 리스트는 props를 통해서 전달되기 때문에, state가 아닙니다. 검색어와 체크박스의 값은 다른것에 의해 계산될 수 있는 값이 아니고, 시시각각 변하기때문에 state가 맞습니다. 마지막으로 product 들의 걸러진 리스트 역시 state가 아닙니다. 원본 리스트와 검색어, 체크박스의 값 등에 의해 연산되어지는 값이기 때문이죠.
결국, state는 다음과 같습니다:
@ -107,26 +107,26 @@ product 들의 원본 리스트는 props를 통해서 전달되기 때문에, st
<iframe width="100%" height="300" src="https://jsfiddle.net/reactjs/zafjbw1e/embedded/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
이제 최소한의 state가 무엇인지 알아 내었습니다. 다음은 어떤 컴포넌트가 이 state를 변형하거나 만들어 낼지 알아내야합니다.
이제 최소한의 state가 무엇인지 알아습니다. 다음은 어떤 컴포넌트가 이 state를 변형하거나 만들어낼지 알아내야 합니다.
기억하세요: React는 계층적 아래 컴포넌트로만 향하는 단일방향성 자료 흐름을 가집니다. 지금당장은 어떤 컴포넌트가 자기 자신의 state를 가져야 할지 명확하지 않을겁니다. **이것이 처음 접하는 사람이 가장 이해하기 어려운 부분입니다**. 이제 명확히 하기 위해 다음을 따라봅시다:
기억하세요: React는 계층적 아래 컴포넌트로만 향하는 단일방향성 자료 흐름을 가집니다. 지금당장은 어떤 컴포넌트가 자기 자신의 state를 가져야 할지 명확하지 않을 것입니다. **이것이 초심자가 가장 이해하기 어려운 부분입니다**. 이제 개념을 명확히 하기 위해 다음으로 따라가 봅시다:
애플리케이션에서 state의 경우:
* 모든 컴포넌트가 state를 통해 무언가를 그려냅니다.
* 대표 컴포넌트가 뭔지 찾으세요 (계층적으로 다른 컴포넌트들의 단일 상위 컴포넌트는 state를 가질 필요가 있습니다).
* 대표 컴포넌트 혹은 또다른 컴포넌트는 가능한 상위의 컴포넌트가 state를 소유해야합니다.
* 만약 state를 가져야할 컴포넌트가 어느것인지 모르겠으면, 새로운 컴포넌트를 만들어 state를 부여하고 기존의 대표 컴포넌트 위에 추가하세요.
* 대표 컴포넌트 혹은 또다른 컴포넌트는 가능한 상위의 컴포넌트가 state를 소유해야 합니다.
* 만약 state를 가져야할 컴포넌트가 어느 것인지 모르겠으면, 새로운 컴포넌트를 만들어 state를 부여하고 기존의 대표 컴포넌트 위에 추가하세요.
이 전략을 우리 애플리케이션에 적용해 봅시다.
* `ProductTable`은 state에 대해 걸러질 필요가 있고, `SearchBar` 역시 검색어 state와 체크박스 state를 보여줄 필요가 있습니다.
* 대표 컴포넌트는 `FilterableProductTable` 입니다.
* 개념적으로 검색어와 체크박스 값은 `FilterableProductTable`에 있어야 한다는 명확합니다.
* 개념적으로 검색어와 체크박스 값은 `FilterableProductTable`에 있어야 한다는 것이 명확합니다.
좋습니다. state를 `FilterableProductTable`에서 관리하도록 결정했습니다. 먼저 `getInitialState()` 메서드를 `FilterableProductTable`에 추가하세요. 이 메서드는 애플리케이션의 초기 state를 갖도록 `{filterText: '', inStockOnly: false}`를 반환하면 됩니다. 그리고 `filterText``inStockOnly``ProductTable``SearchBar`에 prop으로 전달하세요. 마지막으로 이 prop들을 `ProductTable`을 걸러내는데, 그리고 `SearchBar` form fields의 값을 세팅하는데 사용하세요.
좋습니다. state를 `FilterableProductTable`에서 관리하도록 결정했습니다. 먼저 `getInitialState()` 메서드를 `FilterableProductTable`에 추가하세요. 이 메서드는 애플리케이션의 초기 state를 갖도록 `{filterText: '', inStockOnly: false}`를 반환하면 됩니다. 그리고 `filterText``inStockOnly``ProductTable``SearchBar`에 prop으로 전달하세요. 마지막으로 이 prop들을 `ProductTable`을 걸러내는 데, 그리고 `SearchBar` form fields의 값을 세팅하는데 사용하세요.
이제 어떻게 애플리케이션이 동작하는지 볼 수 있습니다: `filterText``"ball"`로 설정하고 갱신합니다. 자료 테이블이 제대로 업데이트 되는것을 볼 수 있을겁니다.
이제 어떻게 애플리케이션이 동작하는지 볼 수 있습니다: `filterText``"ball"`로 설정하고 갱신합니다. 자료 테이블이 제대로 업데이트 되는 것을 볼 수 있을 겁니다.
## 5단계: 반대방향 자료 흐름을 추가하세요.
@ -138,10 +138,10 @@ React는 어떻게 이 프로그램이 동작하는지 이해하기 쉽게 이
지금 예제에 문자열을 입력하거나 체크박스를 체크하더라도 React가 입력을 무시하는것을 볼 수 있습니다. 의도적으로 `input`의 prop에 `value`를 세팅하면 항상 `state``FilterableProductTable`로부터 전달되어야 합니다.
우리가 원하는게 뭔지 생각해 봅시다. 사용자가 form을 바꿀때마다 사용자 입력을 반영하기 위해 업데이트 하기를 원하죠. 컴포넌트들이 오직 자기 자신의 state만 업데이트 하더라도 `FilterableProductTable`은 state가 변할때마다 반영되어야할 `SearchBar`에 콜백을 전달할것입니다. 이 알림을 위해서 `onChange`이벤트를 사용할 수 있습니다. 그리고 `FilterableProductTable`으로부터 전달된 콜백은 `setState()`를 호출할 것이고, 애플리케이션은 업데이트 될겁니다.
우리가 원하는 것이 무엇인지 생각해 봅시다. 사용자가 form을 바꿀때마다 사용자 입력을 반영하기 위해 업데이트 하기를 원하죠. 컴포넌트들이 오직 자기 자신의 state만 업데이트 하더라도 `FilterableProductTable`은 state가 변할때마다 반영되어야할 `SearchBar`에 콜백을 전달할 것입니다. 이 알림을 위해서 `onChange`이벤트를 사용할 수 있습니다. 그리고 `FilterableProductTable`으로부터 전달된 콜백은 `setState()`를 호출할 것이고, 애플리케이션은 업데이트될 것입니다.
많은 코드가 필요한 것 같이 들릴 수 있지만 실제로는 몇 줄 되지 않습니다. 그리고 애플리케이션의 구석구석을 데이터가 어떻게 흘러가는지 매우 명확해집니다.
많은 코드가 필요한 것 같이 들릴 수 있지만 실제로는 몇 줄 되지 않습니다. 그리고 애플리케이션의 구석구석에서 데이터가 어떻게 흐르는지 매우 명확해집니다.
## 그리고
이 글이 컴포넌트와 React로 애플리케이션을 어떻게 만들지에 대한 아이디어가 되길 바랍니다. 원래 하던 것 보다 조금 더 타이핑이 많을진 모르지만, 코드는 쓰는 경우보다 읽히는 경우가 많고 이 코드는 매우 읽기 편하고 명시적인 코드임을 기억하세요. 컴포넌트로 큰 라이브러리를 만들기 시작했다고 할 때, 이 명시성과 모듈성에 감사하게 되고 쓴 줄을 재사용함에 따라 코드의 양도 줄 것입니다. :)
이 글이 컴포넌트와 React로 애플리케이션을 어떻게 만들지에 대한 아이디어가 되길 바랍니다. 원래 하던 방식보다 조금 타이핑을 더 해야할지도 모르지만, 코드는 쓰는 경우보다 읽히는 경우가 많다는 점, 매우 읽기 편하고 명시적인 코드를 썼다는 점을 기억하세요. 컴포넌트로 큰 라이브러리를 만들기 시작할 때, 이 명시성과 모듈성에 감사하게 될 것이며 재사용함에 따라 코드의 양도 줄어들 것입니다. :)

View File

@ -26,13 +26,13 @@ next: thinking-in-react-ko-KR.html
### 서버 구동하기
이 튜토리얼을 시작할 때 필요한 건 아니지만, 나중에 실행 중인 서버에 `POST` 요청을 하는 기능을 추가하게 될 것입니다. 서버를 구성하는 것이 익숙하다면, 본인이 편한 방식대로 서버를 구성해 주세요. 서버사이드에 대한 고민없이 React의 학습 그 자체에 집중하고 싶은 분들을 위해서, 몇 가지 언어로 간단한 서버코드를 작성해 놓았습니다 - JavaScript (Node.js), Python, Ruby 버전이 있고, GitHub에서 찾아보실 있습니다. [소스를 확인](https://github.com/reactjs/react-tutorial/)하거나 [zip 파일을 다운로드](https://github.com/reactjs/react-tutorial/archive/master.zip)하고 시작하세요.
이 튜토리얼을 시작할 때 필요한 건 아니지만, 나중에 실행 중인 서버에 `POST` 요청을 하는 기능을 추가하게 될 것입니다. 서버를 구성하는 것이 익숙하다면, 본인이 편한 방식대로 서버를 구성해 주세요. 서버사이드에 대한 고민없이 React의 학습 그 자체에 집중하고 싶은 분들을 위해서, 몇 가지 언어로 간단한 서버코드를 작성해 놓았습니다 - JavaScript (Node.js), Python, Ruby 버전이 있고, GitHub에서 찾아보실 있습니다. [소스를 확인](https://github.com/reactjs/react-tutorial/)하거나 [zip 파일을 다운로드](https://github.com/reactjs/react-tutorial/archive/master.zip)하고 시작하세요.
튜토리얼을 다운로드 받아 시작한다면, `public/index.html`을 열고 바로 시작하세요.
### 시작하기
이 튜토리얼에서는 CDN에 있는 미리 빌드된 JavaScript 파일들을 사용합니다. 좋아하는 에디터를 열고, 새로운 HTML 문서를 만드세요:
이 튜토리얼에서는 CDN에 있는 미리 빌드된 JavaScript 파일들을 사용합니다. 선호하는 에디터를 열어, 새로운 HTML 문서를 만드세요:
```html
<!-- index.html -->
@ -90,7 +90,7 @@ React.render(
#### JSX 문법
JavsScript 안의 유사 XML 구문이 먼저 눈에 띌 것입니다. 우리에겐 이를 일반 JavaScript로 변환해주는 간단한 프리컴파일러(precompiler)가 있습니다.
JavsScript 안의 유사 XML 구문이 먼저 눈에 띌 것입니다. 우리에겐 이를 JavaScript로 변환해주는 간단한 프리컴파일러(precompiler)가 있습니다.
```javascript
// tutorial1-raw.js
@ -115,9 +115,9 @@ JSX의 사용은 선택적이지만 JSX 문법이 일반 JavsScript보다 사용
우리는 새로운 React 컴포넌트를 만들기 위해 `React.createClass()`로 JavaScript 객체에 몇 개의 메소드를 담아 넘겼습니다. 이 중 가장 중요한것은 `render` 메소드인데, 이는 React 컴포넌트 트리를 반환해서 최종적으로 실제 HTML을 그려주게 됩니다.
`<div>` 태그들은 실제 DOM 노드가 아니라 React `div` 컴포넌트의 인스턴스입니다. 이것은 React가 다룰 수 있는 데이터의 표자(markers)나 조각이라 생각하셔도 됩니다. React는 **안전합니다**. 생(raw) HTML 문자열을 생성하는것이 아니기 때문에 XSS을 기본적으로 방지합니다.
`<div>` 태그들은 실제 DOM 노드가 아니라 React `div` 컴포넌트의 인스턴스입니다. 이것은 React가 다룰 수 있는 데이터의 표자(markers)나 조각이라 생각하셔도 됩니다. React는 **안전합니다**. 생(raw) HTML 문자열을 생성하는 것이 아니기 때문에 XSS을 기본적으로 방지합니다.
일반적인 HTML만 리턴할 수 있는 것은 아닙니다. 여러분이 직접 만든 (또는 다른 사람들이 만들어 놓은) 컴포넌트의 트리를 리턴할 수도 있습니다. 이것이 React를 **조합가능(composable)하게 만듭니다**: 유지보수 가능한 프론트엔드를 위한 핵심교리(key tenet)지요.
일반적인 HTML만 리턴할 수 있는 것은 아닙니다. 여러분이 직접 만든 (또는 다른 사람들이 만들어 놓은) 컴포넌트의 트리를 리턴할 수도 있습니다. 이것이 React를 **조합가능(composable)하게 만듭니다**: 유지보수 가능한 프론트엔드를 위한 핵심 교리(key tenet)지요.
`React.render()`는 최상위 컴포넌트의 인스턴스를 만들고, 두 번째 인수로 전달받은 DOM 엘리먼트에 마크업을 삽입해 프레임워크를 시작합니다.
@ -141,7 +141,7 @@ var CommentForm = React.createClass({
render: function() {
return (
<div className="commentForm">
안녕! 난 댓글폼이야.
안녕! 난 댓글 폼이야.
</div>
);
}
@ -165,7 +165,7 @@ var CommentBox = React.createClass({
});
```
방금 만든 컴포넌트들을 어떤방식으로 HTML 태그들과 섞어 사용하는지 살펴보세요. HTML 컴포넌트들도 한가지 차이만 제외한다면 우리가 정의한 것과 같은 표준적인 React 컴포넌트입니다. JSX 컴파일러가 자동으로 HTML 태그들을 `React.createElement(tagName)` 표현식으로 재작성하고 나머지는 그대로 둘 것입니다. 이는 전역 네임스페이스가 오염되는 것을 막아줍니다.
방금 만든 컴포넌트들을 어떻게 HTML 태그들과 섞어 사용하는지 살펴보세요. HTML 컴포넌트들도 한가지 차이만 제외한다면 우리가 정의한 것과 같은 표준적인 React 컴포넌트입니다. JSX 컴파일러가 자동으로 HTML 태그들을 `React.createElement(tagName)` 표현식으로 재작성하고 나머지는 그대로 둘 것입니다. 이는 전역 네임스페이스가 오염되는 것을 막아줍니다.
### props 사용하기
@ -286,7 +286,7 @@ var data = [
];
```
이 데이터를 모듈화된 방식으로 `CommentList`에 넣어야 합니다. props을 이용해 데이터를 넘기도록 `CommentBox``React.render()` 호출을 수정합시다.
이 데이터를 모듈화된 방식으로 `CommentList`에 넣어야 합니다. props을 이용해 데이터를 넘기도록 `CommentBox``React.render()` 호출 코드를 수정합시다.
```javascript{7,15}
// tutorial9.js
@ -330,7 +330,7 @@ var CommentList = React.createClass({
});
```
이게 니다!
이게 전부입니다!
### 서버에서 가져오기(Fetching)
@ -483,7 +483,7 @@ var CommentForm = React.createClass({
});
```
이제 폼의 상호작용을 만들어 보겠습니다. 사용자가 폼을 섭밋하는 시점에 우리는 폼을 초기화하고 서버에 요청을 전송하고 댓글목록을 갱신해야 합니다. 폼의 섭밋 이벤트를 감시하고 초기화 해주는 부분부터 시작해 보죠.
이제 폼의 상호작용을 만들어 보겠습니다. 사용자가 폼을 전송하는 시점에 우리는 폼을 초기화하고 서버에 요청을 전송하고 댓글목록을 갱신해야 합니다. 폼의 submit 이벤트를 감시하고 초기화 해주는 부분부터 시작해 보죠.
```javascript{3-13,16-19}
// tutorial16.js
@ -513,9 +513,9 @@ var CommentForm = React.createClass({
##### 이벤트
React는 카멜케이스 네이밍 컨벤션으로 컴포넌트에 이벤트 핸들러를 등록합니다. 폼이 유효한 값으로 섭밋되었을 때 폼필드들을 초기화하도록 `onSubmit` 핸들러를 등록합니다.
React는 카멜케이스 네이밍 컨벤션으로 컴포넌트에 이벤트 핸들러를 등록합니다. 폼이 유효한 값으로 submit되었을 때 폼필드들을 초기화하도록 `onSubmit` 핸들러를 등록합니다.
섭밋에 대한 브라우저의 기본동작을 막기 위해 이벤트시점에 `preventDefault()`를 호출합니다.
submit에 대한 브라우저의 기본동작을 막기 위해 이벤트시점에 `preventDefault()`를 호출합니다.
##### Refs
@ -525,7 +525,7 @@ React는 카멜케이스 네이밍 컨벤션으로 컴포넌트에 이벤트 핸
사용자가 댓글을 등록할 때, 새로운 댓글을 추가하기 위해 댓글목록을 갱신해주어야 합니다. `CommentBox`가 댓글목록의 state를 소유하고 있기 때문에 이 로직 또한 `CommentBox`에 있는것이 타당합니다.
자식 컴포넌트가 그의 부모에게 데이터를 넘겨줄 필요가 있습니다. 부모의 `render` 메소드에서 새로운 콜백(`handleCommentSubmit`)을 자식에게 넘겨주고, 자식의 `onCommentSubmit` 이벤트에 그것을 바인딩해주는 식으로 구현합니다. 이벤트가 작동될때(triggerd)마다, 콜백이 호출됩니다:
자식 컴포넌트가 그의 부모에게 데이터를 넘겨줄 필요가 있습니다. 부모의 `render` 메소드에서 새로운 콜백(`handleCommentSubmit`)을 자식에게 넘겨주고, 자식의 `onCommentSubmit` 이벤트에 그것을 바인딩해주는 식으로 구현합니다. 이벤트가 작동될때(triggered)마다, 콜백이 호출됩니다:
```javascript{15-17,30}
// tutorial17.js
@ -564,7 +564,7 @@ var CommentBox = React.createClass({
});
```
사용자가 폼을 섭밋할 때, `CommentForm`에서 콜백을 호출해 봅시다:
사용자가 폼을 전송할 때, `CommentForm`에서 콜백을 호출해 봅시다:
```javascript{10}
// tutorial18.js
@ -592,7 +592,7 @@ var CommentForm = React.createClass({
});
```
이제 콜백이 제자리를 찾았습니다. 우리가 할일은 서버에 요청을 날리고 목록을 갱신하는 것 뿐입니다:
이제 콜백이 제자리를 찾았습니다. 우리가 할 일은 서버에 요청을 날리고 목록을 갱신하는 것 뿐입니다:
```javascript{16-27}
// tutorial19.js
@ -699,4 +699,4 @@ var CommentBox = React.createClass({
### 축하합니다!
몇 단계를 거쳐 간단하게 댓글상자를 만들어 보았습니다. [왜 React인가](/react/docs/why-react.html)에서 더 알아보거나, 혹은 [API 레퍼런스](/react/docs/top-level-api.html)에 뛰어들어 해킹을 시작하세요! 행운을 빕니다!
몇 단계를 거쳐 간단하게 댓글창을 만들어 보았습니다. [왜 React인가](/react/docs/why-react-ko-KR.html)에서 더 알아보거나, 혹은 [API 레퍼런스](/react/docs/top-level-api-ko-KR.html)에 뛰어들어 해킹을 시작하세요! 행운을 빕니다!

View File

@ -14,7 +14,7 @@ next: complementary-tools-ko-KR.html
### Thinking in react - tagtree.tv
[tagtree.tv](http://tagtree.tv/)의 비디오는 간단한 어플리케이션을 구성하면서 [Thinking in React](/react/docs/thinking-in-react.html) 의 원리들을 전달합니다.
[tagtree.tv](http://tagtree.tv/)의 비디오는 간단한 어플리케이션을 구성하면서 [Thinking in React](/react/docs/thinking-in-react-ko-KR.html)의 원리들을 전달합니다.
<figure>[![](/react/img/docs/thinking-in-react-tagtree.png)](http://tagtree.tv/thinking-in-react)</figure>