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 FAQ > Passing Functions to Components #105

Merged
merged 9 commits into from Jul 27, 2019
119 changes: 60 additions & 59 deletions content/docs/faq-functions.md
@@ -1,26 +1,26 @@
---
id: faq-functions
title: Passing Functions to Components
title: 컴포넌트에 함수 전달하기
permalink: docs/faq-functions.html
layout: docs
category: FAQ
---

### How do I pass an event handler (like onClick) to a component? {#how-do-i-pass-an-event-handler-like-onclick-to-a-component}
### 컴포넌트로 onClick과 같은 이벤트 핸들러를 전달하는 방법 {#how-do-i-pass-an-event-handler-like-onclick-to-a-component}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

Pass event handlers and other functions as props to child components:
하위 컴포넌트에 프로퍼티로 이벤트 핸들러와 다른 함수들을 전달합니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

```jsx
<button onClick={this.handleClick}>
```

If you need to have access to the parent component in the handler, you also need to bind the function to the component instance (see below).
핸들러 안에서 상위 컴포넌트에 접근할 필요가 있으면 컴포넌트 인스턴스에 함수를 바인딩해 주어야 합니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

### How do I bind a function to a component instance? {#how-do-i-bind-a-function-to-a-component-instance}
### 컴포넌트 인스턴스로 함수를 바인딩하는 방법 {#how-do-i-bind-a-function-to-a-component-instance}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

There are several ways to make sure functions have access to component attributes like `this.props` and `this.state`, depending on which syntax and build steps you are using.
사용하고 있는 문법과 빌드 스탭(build steps)에 따라 `this.props`, `this.state`와 같은 컴포넌트의 어트리뷰트에 함수들이 확실히 접근할 수 있도록 만드는 방법은 여러 가지가 있습니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

#### Bind in Constructor (ES2015) {#bind-in-constructor-es2015}
#### 생성자에서 바인딩하기 (ES2015) {#bind-in-constructor-es2015}

```jsx
class Foo extends Component {
Expand All @@ -37,11 +37,11 @@ class Foo extends Component {
}
```

#### Class Properties (Stage 3 Proposal) {#class-properties-stage-3-proposal}
#### 클래스 프로퍼티 (Stage 3 Proposal) {#class-properties-stage-3-proposal}

```jsx
class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
// 주의 : 이 문법은 실험단계이며 아직 표준이 아닙니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved
handleClick = () => {
console.log('Click happened');
}
Expand All @@ -51,7 +51,7 @@ class Foo extends Component {
}
```

#### Bind in Render {#bind-in-render}
#### render 메소드 안에서 바인딩하기 {#bind-in-render}

```jsx
class Foo extends Component {
Expand All @@ -64,11 +64,11 @@ class Foo extends Component {
}
```

>**Note:**
>**주의:**
taehwanno marked this conversation as resolved.
Show resolved Hide resolved
>
>Using `Function.prototype.bind` in render creates a new function each time the component renders, which may have performance implications (see below).
>`Function.prototype.bind`render 메소드에서 사용하면 컴포넌트가 렌더링할 때마다 새로운 함수를 생성하기 때문에 성능에 영향을 줄 수 있습니다.

#### Arrow Function in Render {#arrow-function-in-render}
#### render 메소드 안에서 화살표 함수 사용(arrow function) {#arrow-function-in-render}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

```jsx
class Foo extends Component {
Expand All @@ -81,19 +81,19 @@ class Foo extends Component {
}
```

>**Note:**
>**주의:**
taehwanno marked this conversation as resolved.
Show resolved Hide resolved
>
>Using an arrow function in render creates a new function each time the component renders, which may break optimizations based on strict identity comparison.
> render 메소드 안에서 화살표 함수를 사용하면 컴포넌트가 렌더링할 때마다 새로운 함수를 만들기 때문에 엄격한 비교에 의해 최적화가 깨질 수 있습니다.

### Is it OK to use arrow functions in render methods? {#is-it-ok-to-use-arrow-functions-in-render-methods}
### render 메소드 안에서 화살표 함수를 사용해도 괜찮을까? {#is-it-ok-to-use-arrow-functions-in-render-methods}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

Generally speaking, yes, it is OK, and it is often the easiest way to pass parameters to callback functions.
이 방법은 대체로 사용해도 괜찮고, 콜백 함수로 매개변수를 전달해 주는 가장 쉬운 방법입니다.

If you do have performance issues, by all means, optimize!
성능 문제가 있다면 반드시 최적화를 해야 합니다.

### Why is binding necessary at all? {#why-is-binding-necessary-at-all}
### 바인딩을 하는 이유 {#why-is-binding-necessary-at-all}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

In JavaScript, these two code snippets are **not** equivalent:
자바스크립트에서 아래 두 개의 코드 조각은 **동일하지 않습니다**.

```js
obj.method();
Expand All @@ -104,47 +104,47 @@ var method = obj.method;
method();
```

Binding methods helps ensure that the second snippet works the same way as the first one.
바인딩 메소드는 두 번째 코드 조각이 첫 번째 코드조각과 같은 방식으로 작동하도록 만들어 줍니다.

With React, typically you only need to bind the methods you *pass* to other components. For example, `<button onClick={this.handleClick}>` passes `this.handleClick` so you want to bind it. However, it is unnecessary to bind the `render` method or the lifecycle methods: we don't pass them to other components.
일반적으로 React에서 다른 컴포넌트에 메소드를 **전달**해 줄 때만 바인딩해 주면 됩니다. 예를 들어 `<button onClick={this.handleClick}>``this.handleClick`을 전달하여 바인딩합니다. 그렇지만 `render` 메소드나 생명주기 메소드는 다른 컴포넌트로 전달하지 않기 때문에 바인딩할 필요가 없습니다.

[This post by Yehuda Katz](https://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/) explains what binding is, and how functions work in JavaScript, in detail.
[Yehuda Katz의 글](https://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/)에서 바인딩이 무엇인지, Javascript에서 어떻게 함수가 작동하는지에 대해 상세히 알 수 있습니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

### Why is my function being called every time the component renders? {#why-is-my-function-being-called-every-time-the-component-renders}
### 컴포넌트가 렌더링할 때마다 함수가 호출되는 이유 {#why-is-my-function-being-called-every-time-the-component-renders}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

Make sure you aren't _calling the function_ when you pass it to the component:
컴포넌트로 함수를 전달할 때 _호출하지 않는지_ 확인합니다.

```jsx
render() {
// Wrong: handleClick is called instead of passed as a reference!
// 잘못된 방법: handleClidck은 레퍼런스로 전달되지 않고 호출되었습니다!
return <button onClick={this.handleClick()}>Click Me</button>
}
```

Instead, *pass the function itself* (without parens):
위와 같은 방식이 아니라 괄호 없이 _함수 그 자체를 전달해야 합니다._

```jsx
render() {
// Correct: handleClick is passed as a reference!
// 올바른 방법 : handleClick이 레퍼런스로 전달되었습니다.
return <button onClick={this.handleClick}>Click Me</button>
}
```

### How do I pass a parameter to an event handler or callback? {#how-do-i-pass-a-parameter-to-an-event-handler-or-callback}
### 이벤트 핸들러나 콜백에 매개변수를 전달하는 방법 {#how-do-i-pass-a-parameter-to-an-event-handler-or-callback}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

You can use an arrow function to wrap around an event handler and pass parameters:
이벤드 핸들러에 화살표 함수를 사용하여 감싼 다음에 매개변수를 넘겨주면 됩니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

```jsx
<button onClick={() => this.handleClick(id)} />
```

This is equivalent to calling `.bind`:
`.bind`를 부른 것과 같습니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

```jsx
<button onClick={this.handleClick.bind(this, id)} />
```

#### Example: Passing params using arrow functions {#example-passing-params-using-arrow-functions}
#### 예시: 화살표 함수를 이용하여 매개변수 전달하기 {#example-passing-params-using-arrow-functions}

```jsx
const A = 65 // ASCII character code
Expand Down Expand Up @@ -178,9 +178,9 @@ class Alphabet extends React.Component {
}
```

#### Example: Passing params using data-attributes {#example-passing-params-using-data-attributes}
#### 예시: data-attributes를 사용해서 매개변수 전달하기 {#example-passing-params-using-data-attributes}

Alternately, you can use DOM APIs to store data needed for event handlers. Consider this approach if you need to optimize a large number of elements or have a render tree that relies on React.PureComponent equality checks.
다른 방법으로 이벤트 핸들러에 필요한 데이터를 저장하기 위해 DOM API를 사용할 수 있습니다. 이 방법은 아주 많은 요소를 최적화하거나 React.PureComponent equality checks에 의존하는 렌더링 트리를 사용할 때 고려해 볼 만합니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

```jsx
const A = 65 // ASCII character code
Expand Down Expand Up @@ -218,23 +218,23 @@ class Alphabet extends React.Component {
}
```

### How can I prevent a function from being called too quickly or too many times in a row? {#how-can-i-prevent-a-function-from-being-called-too-quickly-or-too-many-times-in-a-row}
### 함수가 너무 빨리 또는 너무 많이 호출되는 것을 막는 방법 {#how-can-i-prevent-a-function-from-being-called-too-quickly-or-too-many-times-in-a-row}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

If you have an event handler such as `onClick` or `onScroll` and want to prevent the callback from being fired too quickly, then you can limit the rate at which callback is executed. This can be done by using:
`onClick` 또는 `onScroll`과 같은 이벤트 핸들러를 사용하고 있을 때 콜백이 너무 빠르게 호출되지 않도록 콜백이 실행되는 속도를 제어할 수 있습니다. 다음의 함수들을 사용하면 됩니다.

- **throttling**: sample changes based on a time based frequency (eg [`_.throttle`](https://lodash.com/docs#throttle))
- **debouncing**: publish changes after a period of inactivity (eg [`_.debounce`](https://lodash.com/docs#debounce))
- **`requestAnimationFrame` throttling**: sample changes based on [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) (eg [`raf-schd`](https://github.com/alexreardon/raf-schd))
- **스로틀링**: 시간 기반 빈도에 따른 변경 샘플링 (예시 [`_.throttle`](https://lodash.com/docs#throttle))
- **디바운싱**: 비활성 주기 이후에 변경 적용 (예시 [`_.debounce`](https://lodash.com/docs#debounce))
- **`requestAnimationFrame` 스로틀링**: [`requestAnimationFrame`](https://developer.mozilla.org/ko/docs/Web/API/window/requestAnimationFrame) (예시 [`raf-schd`](https://github.com/alexreardon/raf-schd))을 기반으로 한 변경 샘플링
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

See [this visualization](http://demo.nimius.net/debounce_throttle/) for a comparison of `throttle` and `debounce` functions.
`throttle`과 `debounce` 함수를 비교하고 싶으면 [시각화](http://demo.nimius.net/debounce_throttle/)를 확인하면 됩니다.

> Note:
> 주의:
taehwanno marked this conversation as resolved.
Show resolved Hide resolved
>
> `_.debounce`, `_.throttle` and `raf-schd` provide a `cancel` method to cancel delayed callbacks. You should either call this method from `componentWillUnmount` _or_ check to ensure that the component is still mounted within the delayed function.
> `_.debounce`, `_.throttle`, `raf-schd`는 지연되는 콜백을 취소하는 메소드 `cancel`을 제공합니다. `componentWillUnmount`에서 이 함수를 사용하거나 또는 함수가 지연된 동안에 컴포넌트가 마운트가 되어있음을 확인해야 합니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

#### Throttle {#throttle}
#### 스로틀 {#throttle}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

Throttling prevents a function from being called more than once in a given window of time. The example below throttles a "click" handler to prevent calling it more than once per second.
스로틀링은 함수가 주어진 시간 동안에 한 번 이상 불리는 것을 막습니다. 아래는 "click" 핸들러에 스로틀링을 사용하여 초당 한 번만 불리도록 한 예제입니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

```jsx
import throttle from 'lodash.throttle';
Expand All @@ -260,9 +260,9 @@ class LoadMoreButton extends React.Component {
}
```

#### Debounce {#debounce}
#### 디바운스 {#debounce}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

Debouncing ensures that a function will not be executed until after a certain amount of time has passed since it was last called. This can be useful when you have to perform some expensive calculation in response to an event that might dispatch rapidly (eg scroll or keyboard events). The example below debounces text input with a 250ms delay.
디바운싱은 함수가 마지막으로 불린 후 특정 시간까지 실행되지 않도록 해줍니다. 빠르게 디스패치 하는 이벤트(예시 스크롤, 키보드 이벤트)의 응답으로 어떤 비싼 계산을 수행해야 할 때 사용하면 좋습니다. 아래의 예시는 250밀리초 이내의 텍스트 입력을 디바운싱했습니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

```jsx
import debounce from 'lodash.debounce';
Expand Down Expand Up @@ -290,9 +290,9 @@ class Searchbox extends React.Component {
}

handleChange(e) {
// React pools events, so we read the value before debounce.
// Alternately we could call `event.persist()` and pass the entire event.
// For more info see reactjs.org/docs/events.html#event-pooling
// React는 이벤트를 모으기 때문에, 디바운스 하기 전에 값을 읽습니다.
// `event.persist()`를 호출한 후 전체 이벤트를 전달하는 방법도 있습니다.
// 더 상세한 내용은 reactjs.org/docs/events.html#event-pooling에 있습니다.
this.emitChangeDebounced(e.target.value);
}

Expand All @@ -302,13 +302,13 @@ class Searchbox extends React.Component {
}
```

#### `requestAnimationFrame` throttling {#requestanimationframe-throttling}
#### `requestAnimationFrame` 스로틀링 {#requestanimationframe-throttling}
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

[`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) is a way of queuing a function to be executed in the browser at the optimal time for rendering performance. A function that is queued with `requestAnimationFrame` will fire in the next frame. The browser will work hard to ensure that there are 60 frames per second (60 fps). However, if the browser is unable to it will naturally *limit* the amount of frames in a second. For example, a device might only be able to handle 30 fps and so you will only get 30 frames in that second. Using `requestAnimationFrame` for throttling is a useful technique in that it prevents you from doing more than 60 updates in a second. If you are doing 100 updates in a second this creates additional work for the browser that the user will not see anyway.
[`requestAnimationFrame`](https://developer.mozilla.org/ko/docs/Web/API/window/requestAnimationFrame)은 렌더링 성능을 위해 브라우저에서 최적화된 시간에 함수가 실행되도록 함수를 큐잉하는 방법입니다. `requestAnimationFrame`의 큐로 들어간 함수는 다음 프레임에서 실행됩니다. 브라우저는 1초당 60프레임(60 fpt)을 보장하기 위해 열심히 일합니다. 하지만 만약에 브라우저가 이를 하지 못할때 저절로 프레임을 *제한*합니다. 예를 들면 한 기기가 30fps만 처리할 수 있다면 1초 동안 30프레임만 얻을 수 있습니다. 스로틀링을 위해 `requestAnimationFrame`을 사용하면 1초에 60번 이상 업데이트하는 것을 막을 수 있습니다. 1초당 100번 업데이트하도록 브라우저에 일을 만들어 주어도, 유저는 이를 확인할 수 없습니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

>**Note:**
>**주의:**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주의: -> 주의

>
>Using this technique will only capture the last published value in a frame. You can see an example of how this optimization works on [`MDN`](https://developer.mozilla.org/en-US/docs/Web/Events/scroll)
>이 기법을 사용하면, 프레임에 가장 마지막으로 게재된 값만 사용하게 됩니다. 최적화가 어떻게 작동하는지에 대한 예제는 [`MDN`](https://developer.mozilla.org/ko/docs/Web/Events/scroll)에서 확인할 수 있습니다.
taehwanno marked this conversation as resolved.
Show resolved Hide resolved

```jsx
import rafSchedule from 'raf-schd';
Expand All @@ -319,20 +319,20 @@ class ScrollListener extends React.Component {

this.handleScroll = this.handleScroll.bind(this);

// Create a new function to schedule updates.
// 업데이트 일정을 정하는 함수를 만듭니다.
this.scheduleUpdate = rafSchedule(
point => this.props.onScroll(point)
);
}

handleScroll(e) {
// When we receive a scroll event, schedule an update.
// If we receive many updates within a frame, we'll only publish the latest value.
// 스크롤 이벤트를 받게 되면 업데이트를 일정에 추가합니다.
// 한 프레임 안에 많은 업데이트를 받으면 오직 마지막 값만 게재합니다.
this.scheduleUpdate({ x: e.clientX, y: e.clientY });
}

componentWillUnmount() {
// Cancel any pending updates since we're unmounting.
// 마운트 해제 중에 임시상태의 업데이트들을 모두 취소합니다.
this.scheduleUpdate.cancel();
}

Expand All @@ -349,6 +349,7 @@ class ScrollListener extends React.Component {
}
```

#### Testing your rate limiting {#testing-your-rate-limiting}
#### 속도 제한 테스트 방법 {#testing-your-rate-limiting}

When testing your rate limiting code works correctly it is helpful to have the ability to fast forward time. If you are using [`jest`](https://facebook.github.io/jest/) then you can use [`mock timers`](https://facebook.github.io/jest/docs/en/timer-mocks.html) to fast forward time. If you are using `requestAnimationFrame` throttling then you may find [`raf-stub`](https://github.com/alexreardon/raf-stub) to be a useful tool to control the ticking of animation frames.
속도 제한 코드가 잘 작동하는지 테스트할 때, 빨리 감기 기능을 사용하는 것이 좋습니다. [`jest`](https://facebook.github.io/jest/)를 사용한다면 [`mock timers`](https://facebook.github.io/jest/docs/en/timer-mocks.html)를 빨리 감기 도구로 사용할 수 있습니다. `requestAnimationFrame` 스로틀링을 사용한다면 애니메이션 프레임의 틱을 제어하기 위한 툴로
[`raf-stub`](https://github.com/alexreardon/raf-stub)를 보면 좋습니다.