Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translate React Without ES6 #29

Merged
merged 11 commits into from Mar 14, 2019
72 changes: 39 additions & 33 deletions content/docs/react-without-es6.md
@@ -1,10 +1,10 @@
---
id: react-without-es6
title: React Without ES6
title: ES6 없이 사용하는 리액트
ymin1103 marked this conversation as resolved.
Show resolved Hide resolved
permalink: docs/react-without-es6.html
---

Normally you would define a React component as a plain JavaScript class:
보통 리액트 컴포넌트를 정의할 때 JavaScript의 클래스만을 사용한다면 이와 같을 겁니다:

```javascript
class Greeting extends React.Component {
Expand All @@ -14,7 +14,7 @@ class Greeting extends React.Component {
}
```

If you don't use ES6 yet, you may use the `create-react-class` module instead:
아직 ES6를 사용하지 않는다면, 그 대신 `create-react-class` 모듈을 사용할 수도 있습니다:


```javascript
Expand All @@ -26,11 +26,11 @@ var Greeting = createReactClass({
});
```

The API of ES6 classes is similar to `createReactClass()` with a few exceptions.
ES6 클래스의 API는 몇몇 차이점을 제외하고는 `createReactClass()`와 유사합니다.
ymin1103 marked this conversation as resolved.
Show resolved Hide resolved

## Declaring Default Props {#declaring-default-props}
## 초기 Props 선언하기 {#declaring-default-props}
ymin1103 marked this conversation as resolved.
Show resolved Hide resolved

With functions and ES6 classes `defaultProps` is defined as a property on the component itself:
함수와 ES6의 클래스를 통해 `defaultProps`을 컴포넌트 그 자체의 속성으로서 정의할 수 있습니다:

```javascript
class Greeting extends React.Component {
Expand All @@ -42,7 +42,7 @@ Greeting.defaultProps = {
};
```

With `createReactClass()`, you need to define `getDefaultProps()` as a function on the passed object:
`createReactClass()`를 사용한다면, 인자로 넘겨지는 오브젝트 내에서 `getDefaultProps()`를 함수로 정의해야 합니다:

```javascript
var Greeting = createReactClass({
Expand All @@ -57,9 +57,9 @@ var Greeting = createReactClass({
});
```

## Setting the Initial State {#setting-the-initial-state}
## 초기 State 정의하기 {#setting-the-initial-state}

In ES6 classes, you can define the initial state by assigning `this.state` in the constructor:
ES6의 클래스에서, 생성자 내에서 `this.state`에 값을 할당함으로써 초기 state를 정의할 수 있습니다:
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

```javascript
class Counter extends React.Component {
Expand All @@ -71,7 +71,7 @@ class Counter extends React.Component {
}
```

With `createReactClass()`, you have to provide a separate `getInitialState` method that returns the initial state:
`createReactClass()`를 사용할 때마다 초기 state를 반환하는 `getInitialState` 메서드를 제공해야만 합니다:

```javascript
var Counter = createReactClass({
Expand All @@ -82,16 +82,16 @@ var Counter = createReactClass({
});
```

## Autobinding {#autobinding}
## 자동으로 바인딩하기 {#autobinding}
ymin1103 marked this conversation as resolved.
Show resolved Hide resolved

In React components declared as ES6 classes, methods follow the same semantics as regular ES6 classes. This means that they don't automatically bind `this` to the instance. You'll have to explicitly use `.bind(this)` in the constructor:
React 컴포넌트가 ES6의 클래스로서 선언된 경우에 내부의 메서드는 표준 ES6 클래스에서 메서드와 같은 의미를 가집니다. 이는 곧 메서드가 `this`를 인스턴스에 자동으로 바인딩하지 않는 다는 것을 의미합니다. 따라서 이 경우에는 생성자에서 별도로 `.bind(this)`를 사용해 주어야만 합니다:
ymin1103 marked this conversation as resolved.
Show resolved Hide resolved

```javascript
class SayHello extends React.Component {
constructor(props) {
super(props);
this.state = {message: 'Hello!'};
// This line is important!
// 이 부분이 중요합니다!
this.handleClick = this.handleClick.bind(this);
}

Expand All @@ -100,7 +100,7 @@ class SayHello extends React.Component {
}

render() {
// Because `this.handleClick` is bound, we can use it as an event handler.
// `this.handleClick`이 바인딩 되었기 때문에, 이를 이벤트 핸들러로 사용할 수 있습니다.
return (
<button onClick={this.handleClick}>
Say hello
Expand All @@ -110,7 +110,7 @@ class SayHello extends React.Component {
}
```

With `createReactClass()`, this is not necessary because it binds all methods:
반면에 `createReactClass()`를 사용한다면, 알아서 모든 메서드를 바인딩하기 때문에 위의 과정이 반드시 필요하지는 않습니다:

```javascript
var SayHello = createReactClass({
Expand All @@ -132,9 +132,10 @@ var SayHello = createReactClass({
});
```

This means writing ES6 classes comes with a little more boilerplate code for event handlers, but the upside is slightly better performance in large applications.
이는 ES6의 클래스를 사용하는 것이 이벤트 핸들러를 만들기 위해 더 많은 boilerplate code가 필요하게 된다는 것을 의미합니다. 하지만 클래스를 사용하는 것이 규모가 큰 애플리케이션에서 조금 더 좋은 성능을 보입니다.

If the boilerplate code is too unattractive to you, you may enable the **experimental** [Class Properties](https://babeljs.io/docs/plugins/transform-class-properties/) syntax proposal with Babel:

boilerplate code가 정 쓰기 싫다면, **실험적인** [클래스 프로퍼티](https://babeljs.io/docs/plugins/transform-class-properties/) 문법을 Babel을 통해 사용할 수도 있습니다:
taehwanno marked this conversation as resolved.
Show resolved Hide resolved


```javascript
Expand All @@ -143,8 +144,8 @@ class SayHello extends React.Component {
super(props);
this.state = {message: 'Hello!'};
}
// WARNING: this syntax is experimental!
// Using an arrow here binds the method:
// 경고: 이 문법은 실험적입니다!
// 화살표 함수를 통해 메서드를 바인딩합니다:
taehwanno marked this conversation as resolved.
Show resolved Hide resolved
handleClick = () => {
alert(this.state.message);
}
Expand All @@ -159,27 +160,32 @@ class SayHello extends React.Component {
}
```

Please note that the syntax above is **experimental** and the syntax may change, or the proposal might not make it into the language.
위 코드에서 쓰인 문법은 **실험적인** 상태이므로 그 내용이 변할 수 있거나, JavaScript에 반영되지 않을 수 있습니다.


If you'd rather play it safe, you have a few options:
안전한 길을 원한다면 몇 가지 선택지가 있습니다:
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

* Bind methods in the constructor.
* Use arrow functions, e.g. `onClick={(e) => this.handleClick(e)}`.
* Keep using `createReactClass`.
* 생성자에서 메서드들을 바인딩합니다.
* `onClick={(e) => this.handleClick(e)}`와 같이 화살표 함수를 사용합니다.
* `createReactClass`를 계속 사용합니다.

## Mixins {#mixins}

>**Note:**
>**주목:**
>
>ES6 launched without any mixin support. Therefore, there is no support for mixins when you use React with ES6 classes.
>ES6는 처음부터 mixin에 대한 어떠한 지원도 없었습니다. 따라서, 리액트에서 ES6 클래스를 사용하고자 하는 경우에도 mixin에 대한 별도의 지원은 없습니다.
ymin1103 marked this conversation as resolved.
Show resolved Hide resolved
>
>**We also found numerous issues in codebases using mixins, [and don't recommend using them in the new code](/blog/2016/07/13/mixins-considered-harmful.html).**
>
>This section exists only for the reference.
>**또한 저희 팀은 mixin을 사용한 Codebase에서 수 많은 문제점들을 발견했습니다. 이에 따라 저희는 [새로 작성하는 코드에서는 mixin을 사용하지 않는 것을 추천드립니다.](/blog/2016/07/13/mixins-considered-harmful.html)**

>
>본 문단은 참고목적으로만 보시길 바랍니다.
ymin1103 marked this conversation as resolved.
Show resolved Hide resolved

가끔은 전혀 다른 컴포넌트들이 어느 정도 유사한 기능을 공유할 수도 있습니다. 간혹 발생하는 이러한 경우를 [cross-cutting concerns](https://en.wikipedia.org/wiki/Cross-cutting_concern)라고 부릅니다.
ymin1103 marked this conversation as resolved.
Show resolved Hide resolved
이 문제에 대한 대처법으로서 `createReactClass`를 통해 레거시 코드인 `mixins`을 사용할 수 있습니다.

Sometimes very different components may share some common functionality. These are sometimes called [cross-cutting concerns](https://en.wikipedia.org/wiki/Cross-cutting_concern). `createReactClass` lets you use a legacy `mixins` system for that.
mixin을 사용하는 흔한 예로는 시간 간격을 두고 반복적으로 스스로 내용을 갱신하는 컴포넌트를 만들고자 할 경우가 있습니다. 이는 `setInterval()`을 사용하면 간단하게 만들 수 있지만, 메모리를 절약하기 위해서 컴포넌트를 더 이상 사용하지 않을 때 이를 취소하는 것이 중요합니다. 리액트는 [생애주기 메서드](/docs/react-component.html#the-component-lifecycle)를 제공합니다. 생애주기 메서드는 컴포넌트가 생성되거나 파괴되기 직전에 이를 알려주는 역할을 합니다. 생애주기 메서드를 이용하는 간단한 mixin을 만들어 보겠습니다. 이 mixin은 컴포넌트가 파괴될 때 스스로 삭제되는 `setInterval()` 함수 기능을 제공해 줍니다.

One common use case is a component wanting to update itself on a time interval. It's easy to use `setInterval()`, but it's important to cancel your interval when you don't need it anymore to save memory. React provides [lifecycle methods](/docs/react-component.html#the-component-lifecycle) that let you know when a component is about to be created or destroyed. Let's create a simple mixin that uses these methods to provide an easy `setInterval()` function that will automatically get cleaned up when your component is destroyed.

```javascript
var SetIntervalMixin = {
Expand All @@ -197,12 +203,12 @@ var SetIntervalMixin = {
var createReactClass = require('create-react-class');

var TickTock = createReactClass({
mixins: [SetIntervalMixin], // Use the mixin
mixins: [SetIntervalMixin], // mixin을 사용
getInitialState: function() {
return {seconds: 0};
},
componentDidMount: function() {
this.setInterval(this.tick, 1000); // Call a method on the mixin
this.setInterval(this.tick, 1000); // mixin에서 메서드를 호출
},
tick: function() {
this.setState({seconds: this.state.seconds + 1});
Expand All @@ -222,4 +228,4 @@ ReactDOM.render(
);
```

If a component is using multiple mixins and several mixins define the same lifecycle method (i.e. several mixins want to do some cleanup when the component is destroyed), all of the lifecycle methods are guaranteed to be called. Methods defined on mixins run in the order mixins were listed, followed by a method call on the component.
하나의 컴포넌트가 여러 개의 mixin을 사용하고 그것들이 같은 생명주기 메서드를 정의한다면, (예를 들자면, 그 mixin들이 컴포넌트가 파괴될 때 어떠한 없애는 기능을 수행하고자 하는 경우가 있습니다) 모든 생명주기 메서드가 호출되는 것이 보장됩니다. mixin에서 정의된 메서드들은 mixin이 나열된 순서대로 구동되며 그 뒤에 컴포넌트에서 메서드가 호출됩니다.