Skip to content

Add hooks-custom translation #230

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

Merged
merged 8 commits into from
Sep 8, 2020
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 35 additions & 34 deletions content/docs/hooks-custom.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
id: hooks-custom
title: Building Your Own Hooks
title: 자신만의 Hook 만들기
permalink: docs/hooks-custom.html
next: hooks-reference.html
prev: hooks-rules.html
---

*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.
*Hook*은 React 16.8버전에 새로 추가되었습니다. Hook은 클래스 컴포넌트를 작성하지 않아도 state와 같은 특징들을 사용할 수 있습니다.

Building your own Hooks lets you extract component logic into reusable functions.
자신만의 Hook을 만들면 컴포넌트 로직을 함수로 뽑아내어 재사용할 수 있습니다.

When we were learning about [using the Effect Hook](/docs/hooks-effect.html#example-using-hooks-1), we saw this component from a chat application that displays a message indicating whether a friend is online or offline:
[Effect Hook 사용하기](/docs/hooks-effect.html#example-using-hooks-1)를 배울 때, 채팅 애플리케이션에서 친구가 온라인 상태인지 아닌지에 대한 메시지를 표시하는 컴포넌트를 보았을 것입니다.

```js{4-15}
import React, { useState, useEffect } from 'react';
Expand All @@ -36,7 +36,7 @@ function FriendStatus(props) {
}
```

Now let's say that our chat application also has a contact list, and we want to render names of online users with a green color. We could copy and paste similar logic above into our `FriendListItem` component but it wouldn't be ideal:
이제 채팅 애플리케이션에 연락처 목록이 있으며 그중에서 온라인 상태인 사용자들의 이름을 초록색으로 표시하는 상황을 가정해 보겠습니다. 위의 코드와 비슷한 로직을 복사하여 `FriendListItem` 컴포넌트 안에 붙여넣을 수도 있지만, 가장 좋은 방법이라고 할 수는 없습니다.

```js{4-15}
import React, { useState, useEffect } from 'react';
Expand All @@ -63,15 +63,15 @@ function FriendListItem(props) {
}
```

Instead, we'd like to share this logic between `FriendStatus` and `FriendListItem`.
그 대신 이 로직을 `FriendStatus``FriendListItem`에서 공유하도록 하고 싶습니다.

Traditionally in React, we've had two popular ways to share stateful logic between components: [render props](/docs/render-props.html) and [higher-order components](/docs/higher-order-components.html). We will now look at how Hooks solve many of the same problems without forcing you to add more components to the tree.
리액트에는 상태 관련 로직을 컴포넌트에서 공유하는 두 가지 전통적인 방법이 있습니다. [render props](/docs/render-props.html)와 [고차 컴포넌트](/docs/higher-order-components.html)가 그것입니다. Hook을 사용하여 트리에 컴포넌트를 더하지 않고 위의 문제를 해결하는 방법을 보도록 하겠습니다.

## Extracting a Custom Hook {#extracting-a-custom-hook}
## 사용자 Hook 뽑아내기 {#extracting-a-custom-hook}

When we want to share logic between two JavaScript functions, we extract it to a third function. Both components and Hooks are functions, so this works for them too!
두 개의 자바스크립트 함수에서 같은 로직을 공유하고자 할 때는 또 다른 함수로 분리합니다. 컴포넌트와 Hook 또한 함수이기 때문에 같은 방법을 사용할 수 있습니다!

**A custom Hook is a JavaScript function whose name starts with "`use`" and that may call other Hooks.** For example, `useFriendStatus` below is our first custom Hook:
**사용자 Hook은 이름이 `use`로 시작하는 자바스크립트 함수입니다. 사용자 Hook은 다른 Hook을 호출할 수 있습니다.** 예를 들자면, 아래의 `useFriendStatus`가 우리의 첫 번째 사용자 Hook입니다.

```js{3}
import { useState, useEffect } from 'react';
Expand All @@ -94,11 +94,11 @@ function useFriendStatus(friendID) {
}
```

There's nothing new inside of it -- the logic is copied from the components above. Just like in a component, make sure to only call other Hooks unconditionally at the top level of your custom Hook.
딱히 새로운 것은 없습니다. 로직은 위의 컴포넌트로부터 복사해왔습니다. 다만 컴포넌트에서처럼 다른 Hook들은 사용자 Hook의 위로 놓여야 하며 사용자 Hook은 조건부 함수가 아니어야 합니다.

Unlike a React component, a custom Hook doesn't need to have a specific signature. We can decide what it takes as arguments, and what, if anything, it should return. In other words, it's just like a normal function. Its name should always start with `use` so that you can tell at a glance that the [rules of Hooks](/docs/hooks-rules.html) apply to it.
리액트 컴포넌트와는 다르게 사용자 Hook은 특정한 시그니처가 필요 없습니다. 무엇을 인수로 받아야 하며 필요하다면 무엇을 반환해야 하는 지를 사용자가 결정할 수 있습니다. 다시 말하지만, 보통의 함수와 마찬가지입니다. 이름은 반드시 `use`로 시작해야 하는데 그래야만 한눈에 보아도 [Hook 규칙](/docs/hooks-rules.html)이 적용되는지를 파악할 수 있기 때문입니다.

The purpose of our `useFriendStatus` Hook is to subscribe us to a friend's status. This is why it takes `friendID` as an argument, and returns whether this friend is online:
`useFriendStatus` Hook의 목표는 친구의 상태를 구독하기 위함입니다. 이를 위하여 `friendID`를 인수로 받고 온라인 상태의 여부를 반환합니다.

```js
function useFriendStatus(friendID) {
Expand All @@ -110,13 +110,13 @@ function useFriendStatus(friendID) {
}
```

Now let's see how we can use our custom Hook.
이제 사용자 Hook을 어떻게 이용하는지 보겠습니다.

## Using a Custom Hook {#using-a-custom-hook}
## 사용자 Hook 이용하기 {#using-a-custom-hook}

In the beginning, our stated goal was to remove the duplicated logic from the `FriendStatus` and `FriendListItem` components. Both of them want to know whether a friend is online.
처음 우리의 목표는 `FriendStatus``FriendListItem` 컴포넌트에 중복되어있는 로직을 제거하는 것이었습니다. 두 컴포넌트 모두 친구의 온라인 상태 여부를 알아야 하죠.

Now that we've extracted this logic to a `useFriendStatus` hook, we can *just use it:*
이제 이 로직을 `useFriendStatus` hook으로 뽑아내었으니, *바로 사용할 수 있습니다.*

```js{2}
function FriendStatus(props) {
Expand All @@ -141,19 +141,19 @@ function FriendListItem(props) {
}
```

**Is this code equivalent to the original examples?** Yes, it works in exactly the same way. If you look closely, you'll notice we didn't make any changes to the behavior. All we did was to extract some common code between two functions into a separate function. **Custom Hooks are a convention that naturally follows from the design of Hooks, rather than a React feature.**
**본래의 예시와 동일한 코드인가요?** 네 정확히 같은 방식으로 작동합니다. 자세히 보면 작동방식에 어떤 변화도 없다는 것을 알 수 있습니다. 바뀐 것은 오로지 공통의 코드를 뽑아내 새로운 함수로 만든 것뿐입니다. **사용자 Hook은 리액트의 특별한 기능이라기보다 기본적으로 Hook의 디자인을 따르는 관습입니다.**

**Do I have to name my custom Hooks starting with “`use`”?** Please do. This convention is very important. Without it, we wouldn't be able to automatically check for violations of [rules of Hooks](/docs/hooks-rules.html) because we couldn't tell if a certain function contains calls to Hooks inside of it.
**사용자 Hook의 이름은 “`use`”로 시작되어야 하나요?** 네 그렇습니다. 이 관습은 아주 중요합니다. 이를 따르지 않으면 특정한 함수가 그 안에서 Hook을 호출하는지를 알 수 없기 때문에 [Hook 규칙](/docs/hooks-rules.html)의 위반 여부를 자동으로 체크할 수 없습니다.

**Do two components using the same Hook share state?** No. Custom Hooks are a mechanism to reuse *stateful logic* (such as setting up a subscription and remembering the current value), but every time you use a custom Hook, all state and effects inside of it are fully isolated.
**같은 Hook을 사용하는 두 개의 컴포넌트는 state를 공유하나요?** 아니요. 사용자 Hook은 *상태 관련 로직*(구독을 설정하고 현재 변숫값을 기억하는 것)을 재사용하는 메커니즘이지만 사용자 Hook을 사용할 때마다 그 안의 state와 effect는 완전히 독립적입니다.

**How does a custom Hook get isolated state?** Each *call* to a Hook gets isolated state. Because we call `useFriendStatus` directly, from React's point of view our component just calls `useState` and `useEffect`. And as we [learned](/docs/hooks-state.html#tip-using-multiple-state-variables) [earlier](/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns), we can call `useState` and `useEffect` many times in one component, and they will be completely independent.
**사용자 Hook은 어떻게 독립된 state를 얻는 건가요?** 각각의 Hook에 대한 *호출*은 서로 독립된 state를 받습니다. `useFriendStatus`를 직접적으로 호출하기 때문에 리액트의 관점에서 이 컴포넌트는 `useState``useEffect`를 호출한 것과 다름없습니다. 또한 우리가 [이전에](/docs/hooks-effect.html#tip-use-multiple-effects-to-separate-concerns) [배웠듯이](/docs/hooks-state.html#tip-using-multiple-state-variables), 하나의 컴포넌트 안에서 `useState``useEffect`를 여러 번 부를 수 있고 이들은 모두 완전히 독립적입니다.

### Tip: Pass Information Between Hooks {#tip-pass-information-between-hooks}
### 팁: Hook에서 Hook으로 정보 전달하기 {#tip-pass-information-between-hooks}

Since Hooks are functions, we can pass information between them.
Hook은 함수이기 때문에 Hook 사이에서도 정보를 전달할 수 있습니다.

To illustrate this, we'll use another component from our hypothetical chat example. This is a chat message recipient picker that displays whether the currently selected friend is online:
상황설명을 위해 채팅 예시에 있는 다른 컴포넌트를 사용하겠습니다. 현재 선택된 친구가 온라인 상태인지를 표시하는 채팅 수신자 선택기입니다.

```js{8-9,13}
const friendList = [
Expand Down Expand Up @@ -184,24 +184,24 @@ function ChatRecipientPicker() {
}
```

We keep the currently chosen friend ID in the `recipientID` state variable, and update it if the user chooses a different friend in the `<select>` picker.
현재 선택된 친구의 ID를 `recipientID` state 변수에 저장하고 사용자가 `<select>` 선택기에 있는 다른 친구를 선택하면 이를 업데이트합니다.

Because the `useState` Hook call gives us the latest value of the `recipientID` state variable, we can pass it to our custom `useFriendStatus` Hook as an argument:
`useState` Hook 호출은 `recipientID` state 변수의 최신값을 돌려주기 때문에 이를 `useFriendStatus` Hook에 인수로 보낼 수 있습니다.

```js
const [recipientID, setRecipientID] = useState(1);
const isRecipientOnline = useFriendStatus(recipientID);
```

This lets us know whether the *currently selected* friend is online. If we pick a different friend and update the `recipientID` state variable, our `useFriendStatus` Hook will unsubscribe from the previously selected friend, and subscribe to the status of the newly selected one.
이를 통해 *지금 선택되어있는* 친구의 온라인 상태 여부를 알 수 있습니다. 만약 다른 친구를 선택하고 `recipientID` state 변수를 업데이트하면 `useFriendStatus` Hook은 이미 선택되어있는 친구의 구독을 해지하고 새로이 선택된 친구의 상태를 구독할 것입니다.

## `useYourImagination()` {#useyourimagination}

Custom Hooks offer the flexibility of sharing logic that wasn't possible in React components before. You can write custom Hooks that cover a wide range of use cases like form handling, animation, declarative subscriptions, timers, and probably many more we haven't considered. What's more, you can build Hooks that are just as easy to use as React's built-in features.
사용자 Hook은 이전 리액트 컴포넌트에서는 불가능했던 로직공유의 유연성을 제공합니다. 사용자 Hook을 만들어 폼 다루기, 애니메이션, 선언형 구독, 타이머, 그 외에 생각하지 않은 부분까지 훨씬 다양한 쓰임새에 적용할 수 있습니다. 또한 리액트의 내장된 기능만큼이나 사용하기 쉬운 Hook을 만들 수도 있습니다.

Try to resist adding abstraction too early. Now that function components can do more, it's likely that the average function component in your codebase will become longer. This is normal -- don't feel like you *have to* immediately split it into Hooks. But we also encourage you to start spotting cases where a custom Hook could hide complex logic behind a simple interface, or help untangle a messy component.
너무 이른 단계에서 로직을 뽑아내려고 하지는 않는 게 좋습니다. 함수 컴포넌트가 할 수 있는 일이 더 다양해졌기 때문에 여러분의 코드에 있는 함수 컴포넌트의 길이도 길어졌을 것입니다. 이는 지극히 평범한 일이며 지금 바로 Hook으로 *분리해야만 한다고* 느낄 필요는 없습니다. 하지만 동시에 사용자 Hook이 복잡한 로직을 단순한 인터페이스 속에 숨길 수 있도록 하거나 복잡하게 뒤엉킨 컴포넌트를 풀어내도록 돕는 경우들을 찾아내는 것을 권장합니다.

For example, maybe you have a complex component that contains a lot of local state that is managed in an ad-hoc way. `useState` doesn't make centralizing the update logic any easier so you might prefer to write it as a [Redux](https://redux.js.org/) reducer:
예를 들자면, 내부에 많은 state를 지니고 있지만, 이것들이 적절하게 관리되지 않는 컴포넌트가 있다고 가정하겠습니다. `useState`는 업데이트 로직을 모아주는 데에는 도움이 되지 않기 때문에 대신 [Redux](https://redux.js.org/) reducer의 이용을 선호할 수도 있겠지요.

```js
function todosReducer(state, action) {
Expand All @@ -218,9 +218,9 @@ function todosReducer(state, action) {
}
```

Reducers are very convenient to test in isolation, and scale to express complex update logic. You can further break them apart into smaller reducers if necessary. However, you might also enjoy the benefits of using React local state, or might not want to install another library.
reducer는 독립적으로 테스트하기에 편리하며 복잡한 업데이트 로직의 표현이 늘어나는 경우에도 잘 맞습니다. 필요하다면 더 작은 reducer로 나누는 것도 가능합니다. 하지만 리액트 state의 장점을 누리는 것은 선택일 뿐, 이 때문에 또 다른 라이브러리를 설치하고 싶지 않을 수도 있습니다.

So what if we could write a `useReducer` Hook that lets us manage the *local* state of our component with a reducer? A simplified version of it might look like this:
컴포넌트의 *안의* state를 reducer로 관리하는 `useReducer` Hook을 작성한다면 어떨까요? 이 Hook을 간단히 표현하면 다음과 같습니다.

```js
function useReducer(reducer, initialState) {
Expand All @@ -235,7 +235,7 @@ function useReducer(reducer, initialState) {
}
```

Now we could use it in our component, and let the reducer drive its state management:
컴포넌트 안에서 이 Hook을 사용하여 reducer가 state 관리를 합니다.

```js{2}
function Todos() {
Expand All @@ -249,4 +249,5 @@ function Todos() {
}
```

The need to manage local state with a reducer in a complex component is common enough that we've built the `useReducer` Hook right into React. You'll find it together with other built-in Hooks in the [Hooks API reference](/docs/hooks-reference.html).
복잡한 컴포넌트에서 내에서 state를 reducer로 관리해야 하는 보편적 필요성을 고려하여 리액트에는 `useReducer`가 내장되어 있습니다. 이는 [Hook API 참고서](/docs/hooks-reference.html)에서 다른 내장 Hook과 함께 찾아볼 수 있습니다.