diff --git a/src/content/learn/escape-hatches.md b/src/content/learn/escape-hatches.md index 69e733521..7f78ed89e 100644 --- a/src/content/learn/escape-hatches.md +++ b/src/content/learn/escape-hatches.md @@ -1,35 +1,35 @@ --- -title: Escape Hatches +title: 탈출구 --- -Some of your components may need to control and synchronize with systems outside of React. For example, you might need to focus an input using the browser API, play and pause a video player implemented without React, or connect and listen to messages from a remote server. In this chapter, you'll learn the escape hatches that let you "step outside" React and connect to external systems. Most of your application logic and data flow should not rely on these features. +일부 컴포넌트는 React 외부의 시스템을 제어하고 동기화해야 할 수 있습니다. 예를 들어 브라우저 API를 사용해 input에 초점을 맞추거나, React 없이 구현된 비디오 플레이어를 재생 및 일시 정지하거나, 원격 서버에 연결해서 메시지를 수신해야 할 수 있습니다. 이 장에서는 React의 "외부"로 나가서 외부 시스템에 연결할 수 있는 탈출구를 배웁니다. 대부분의 애플리케이션 로직과 데이터 흐름은 이러한 기능에 의존해서는 안 됩니다. -* [How to "remember" information without re-rendering](/learn/referencing-values-with-refs) -* [How to access DOM elements managed by React](/learn/manipulating-the-dom-with-refs) -* [How to synchronize components with external systems](/learn/synchronizing-with-effects) -* [How to remove unnecessary Effects from your components](/learn/you-might-not-need-an-effect) -* [How an Effect's lifecycle is different from a component's](/learn/lifecycle-of-reactive-effects) -* [How to prevent some values from re-triggering Effects](/learn/separating-events-from-effects) -* [How to make your Effect re-run less often](/learn/removing-effect-dependencies) -* [How to share logic between components](/learn/reusing-logic-with-custom-hooks) +* [다시 렌더링하지 않고 정보를 "기억"하는 방법](/learn/referencing-values-with-refs) +* [React가 관리하는 DOM 엘리먼트에 접근하는 방법](/learn/manipulating-the-dom-with-refs) +* [컴포넌트를 외부 시스템과 동기화하는 방법](/learn/synchronizing-with-effects) +* [컴포넌트에서 불필요한 Effect를 제거하는 방법](/learn/you-might-not-need-an-effect) +* [Effect의 생명주기가 컴포넌트와 어떻게 다른지](/learn/lifecycle-of-reactive-effects) +* [일부 값이 Effect를 다시 발생시키는 것을 막는 방법](/learn/separating-events-from-effects) +* [Effect 재실행을 줄이는 방법](/learn/removing-effect-dependencies) +* [컴포넌트 간 로직을 공유하는 방법](/learn/reusing-logic-with-custom-hooks) -## Referencing values with refs {/*referencing-values-with-refs*/} +## Ref로 값 참조하기 {/*referencing-values-with-refs*/} -When you want a component to "remember" some information, but you don't want that information to [trigger new renders](/learn/render-and-commit), you can use a *ref*: +컴포넌트가 일부 정보를 “기억”하고 싶지만, 해당 정보가 [렌더링을 유발](/learn/render-and-commit)하지 않도록 하려면 ref를 사용하세요. ```js const ref = useRef(0); ``` -Like state, refs are retained by React between re-renders. However, setting state re-renders a component. Changing a ref does not! You can access the current value of that ref through the `ref.current` property. +state처럼 ref는 다시 렌더링하는 사이에 React에 의해 유지됩니다. 다만 state의 설정은 컴포넌트가 다시 렌더링 되지만, ref의 변경은 그렇지 않습니다! `ref.current` 프로퍼티를 통해 해당 ref의 현재 값에 접근할 수 있습니다. @@ -54,17 +54,17 @@ export default function Counter() { -A ref is like a secret pocket of your component that React doesn't track. For example, you can use refs to store [timeout IDs](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#return_value), [DOM elements](https://developer.mozilla.org/en-US/docs/Web/API/Element), and other objects that don't impact the component's rendering output. +ref는 React가 추적하지 않는 컴포넌트의 비밀 주머니와 같습니다. 예를 들어 ref를 사용하여 컴포넌트의 렌더링 출력에 영향을 주지 않는 [timeout ID](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#return_value), [DOM 엘리먼트](https://developer.mozilla.org/en-US/docs/Web/API/Element) 및 기타 객체를 저장할 수 있습니다. -Read **[Referencing Values with Refs](/learn/referencing-values-with-refs)** to learn how to use refs to remember information. +ref를 사용하여 정보를 기억하는 방법을 배우려면 **[Ref로 값 참조하기](/learn/referencing-values-with-refs)** 를 읽어보세요. -## Manipulating the DOM with refs {/*manipulating-the-dom-with-refs*/} +## Ref로 DOM 조작하기 {/*manipulating-the-dom-with-refs*/} -React automatically updates the DOM to match your render output, so your components won't often need to manipulate it. However, sometimes you might need access to the DOM elements managed by React—for example, to focus a node, scroll to it, or measure its size and position. There is no built-in way to do those things in React, so you will need a ref to the DOM node. For example, clicking the button will focus the input using a ref: +React는 렌더링 결과물에 맞춰 DOM 변경을 자동으로 처리하기 때문에 컴포넌트에서 자주 DOM을 조작해야 할 필요는 없습니다. 하지만 가끔 특정 노드에 포커스를 옮기거나, 스크롤 위치를 옮기거나, 위치와 크기를 측정하기 위해서 React가 관리하는 DOM 요소에 접근해야 할 때가 있습니다. React는 이런 작업을 수행하는 내장 방법을 제공하지 않기 때문에 DOM 노드에 접근하기 위한 ref가 필요할 것입니다. 예를 들어 버튼을 클릭하면 ref를 사용해 input에 포커스를 옮길 것입니다. @@ -93,15 +93,15 @@ export default function Form() { -Read **[Manipulating the DOM with Refs](/learn/manipulating-the-dom-with-refs)** to learn how to access DOM elements managed by React. +React가 관리하는 DOM 엘리먼트에 접근하는 방법을 배우려면 **[Ref로 DOM 조작하기](/learn/manipulating-the-dom-with-refs)** 를 읽어보세요. -## Synchronizing with Effects {/*synchronizing-with-effects*/} +## Effect로 값 동기화하기 {/*synchronizing-with-effects*/} -Some components need to synchronize with external systems. For example, you might want to control a non-React component based on the React state, set up a server connection, or send an analytics log when a component appears on the screen. Unlike event handlers, which let you handle particular events, *Effects* let you run some code after rendering. Use them to synchronize your component with a system outside of React. +일부 컴포넌트는 외부 시스템과 동기화해야 합니다. 예를 들어 React state에 따라 React가 아닌 컴포넌트를 제어하거나, 채팅 서버에 대한 연결을 설정하거나, 컴포넌트가 화면에 나타났을 때 분석 로그를 보낼 수 있습니다. 특정 이벤트를 처리하는 이벤트 핸들러와 달리 Effect는 렌더링 후 일부 코드를 실행합니다. 컴포넌트를 React 외부 시스템과 동기화할 때 이를 사용하세요. -Press Play/Pause a few times and see how the video player stays synchronized to the `isPlaying` prop value: +Play/Pause를 몇 번 누르고 비디오 플레이어가 `isPlaying` prop 값에 어떻게 동기화되는지 확인하세요. @@ -145,7 +145,7 @@ video { width: 250px; } -Many Effects also "clean up" after themselves. For example, an Effect that sets up a connection to a chat server should return a *cleanup function* that tells React how to disconnect your component from that server: +많은 Effect는 스스로 "클린업"하기도 합니다. 예를 들어 채팅 서버에 대한 연결을 설정하는 Effect는 해당 서버에서 컴포넌트의 연결을 끊는 방법을 React에 알려주는 *클린업 함수* 를 반환해야 합니다. @@ -183,23 +183,23 @@ input { display: block; margin-bottom: 20px; } -In development, React will immediately run and clean up your Effect one extra time. This is why you see `"✅ Connecting..."` printed twice. This ensures that you don't forget to implement the cleanup function. +개발 모드에서 React는 즉시 실행되고 Effect를 한 번 더 클린업합니다. 그래서 `"✅ Connecting..."`이 두 번 인쇄되는 것입니다. 이렇게 하여 클린업 함수를 구현하는 것을 잊지 않도록 합니다. -Read **[Synchronizing with Effects](/learn/synchronizing-with-effects)** to learn how to synchronize components with external systems. +컴포넌트를 외부 시스템과 동기화하는 방법을 배우려면 **[Effect로 값 동기화하기](/learn/synchronizing-with-effects)** 를 읽어보세요. -## You Might Not Need An Effect {/*you-might-not-need-an-effect*/} +## Effect가 필요하지 않은 경우 {/*you-might-not-need-an-effect*/} -Effects are an escape hatch from the React paradigm. They let you "step outside" of React and synchronize your components with some external system. If there is no external system involved (for example, if you want to update a component's state when some props or state change), you shouldn't need an Effect. Removing unnecessary Effects will make your code easier to follow, faster to run, and less error-prone. +Effect는 React 패러다임에서 벗어날 수 있는 탈출구입니다. Effect를 사용하면 React를 “벗어나” 컴포넌트를 외부 시스템과 동기화할 수 있습니다. 외부 시스템이 관여하지 않는 경우 (예를 들어 일부 props 또는 state가 변경될 때 컴포넌트의 state를 업데이트하려는 경우) Effect가 필요하지 않습니다. 불필요한 Effect를 제거하면 코드를 더 쉽게 따라갈 수 있고, 실행 속도가 빨라지며, 에러 발생 가능성이 줄어듭니다. -There are two common cases in which you don't need Effects: -- **You don't need Effects to transform data for rendering.** -- **You don't need Effects to handle user events.** +Effect가 필요하지 않은 두 가지 일반적인 경우가 있습니다. +- **렌더링을 위해 데이터를 변환하는 데 Effect가 필요하지 않습니다.** +- **사용자 이벤트를 핸들링하는 데 Effect가 필요하지 않습니다.** -For example, you don't need an Effect to adjust some state based on other state: +예를 들어 다른 state에 따라 일부 state를 조정하는 데는 Effect가 필요하지 않습니다. ```js {5-9} function Form() { @@ -215,7 +215,7 @@ function Form() { } ``` -Instead, calculate as much as you can while rendering: +대신에 렌더링하는 동안 가능한 한 많이 계산하세요. ```js {4-5} function Form() { @@ -227,19 +227,19 @@ function Form() { } ``` -However, you *do* need Effects to synchronize with external systems. +그러나 외부 시스템과 동기화하려면 Effects가 *필요* 합니다. -Read **[You Might Not Need an Effect](/learn/you-might-not-need-an-effect)** to learn how to remove unnecessary Effects. +불필요한 Effect를 제거하는 방법을 배우려면 **[Effect가 필요하지 않은 경우](/learn/you-might-not-need-an-effect)** 를 읽어보세요. -## Lifecycle of reactive effects {/*lifecycle-of-reactive-effects*/} +## React Effect의 생명주기 {/*lifecycle-of-reactive-effects*/} -Effects have a different lifecycle from components. Components may mount, update, or unmount. An Effect can only do two things: to start synchronizing something, and later to stop synchronizing it. This cycle can happen multiple times if your Effect depends on props and state that change over time. +Effect는 컴포넌트와 다른 생명주기를 가집니다. 컴포넌트는 마운트, 업데이트 또는 언마운트할 수 있습니다. 반면 Effect는 동기화를 시작하거나 후에 동기화를 중지하는 두 가지 작업만 할 수 있습니다. Effect가 시간에 따라 변하는 props와 state에 의존하는 경우 이 주기는 여러 번 발생할 수 있습니다. -This Effect depends on the value of the `roomId` prop. Props are *reactive values,* which means they can change on a re-render. Notice that the Effect *re-synchronizes* (and re-connects to the server) if `roomId` changes: +다음 Effect는 `roomId` prop의 값에 의존합니다. Props는 다시 렌더링할 때 변할 수 있는 *반응형 값* 입니다. `roomId`가 변경되면 Effect가 *다시 동기화* (및 서버에 다시 연결)합니다. @@ -302,25 +302,25 @@ button { margin-left: 10px; } -React provides a linter rule to check that you've specified your Effect's dependencies correctly. If you forget to specify `roomId` in the list of dependencies in the above example, the linter will find that bug automatically. +React는 Effect의 의존성을 올바르게 명시했는지 확인하는 린터 규칙을 제공합니다. 위의 예시에서 의존성 목록에 `roomId`를 명시하는 것을 잊어버렸다면, 린터가 해당 버그를 자동으로 찾아낼 것입니다. -Read **[Lifecycle of Reactive Events](/learn/lifecycle-of-reactive-effects)** to learn how an Effect's lifecycle is different from a component's. +Effect의 생명주기가 컴포넌트와 어떻게 다른지를 배우려면 **[React Effect의 생명주기](/learn/lifecycle-of-reactive-effects)** 를 읽어보세요. -## Separating events from Effects {/*separating-events-from-effects*/} +## Effect에서 이벤트 분리하기 {/*separating-events-from-effects*/} -This section describes an **experimental API that has not yet been released** in a stable version of React. +이 섹션에서는 아직 안정된 버전의 React로 **출시되지 않은 실험적인 API**에 대해 설명합니다. -Event handlers only re-run when you perform the same interaction again. Unlike event handlers, Effects re-synchronize if any of the values they read, like props or state, are different than during last render. Sometimes, you want a mix of both behaviors: an Effect that re-runs in response to some values but not others. +이벤트 핸들러는 같은 상호작용을 반복하는 경우에만 다시 실행됩니다. Effect는 이벤트 핸들러와 달리 prop이나 state 변수 등 읽은 값이 마지막 렌더링 때와 다르면 다시 동기화합니다. 때로는 두 동작이 섞여서 어떤 값에는 반응해 다시 실행되지만, 다른 값에는 그러지 않는 Effect를 원할 때도 있습니다. 이 페이지에서 그 방법을 알려드리겠습니다. -All code inside Effects is *reactive.* It will run again if some reactive value it reads has changed due to a re-render. For example, this Effect will re-connect to the chat if either `roomId` or `theme` have changed: +Effect 내의 모든 코드는 *반응형* 이며, 읽은 반응형 값이 다시 렌더링되는 것으로 인해 변경되면 다시 실행됩니다. 예를 들어 다음의 Effect는 `roomId` 또는 `theme`이 변경되면 채팅에 다시 연결됩니다: @@ -448,7 +448,7 @@ label { display: block; margin-top: 10px; } -This is not ideal. You want to re-connect to the chat only if the `roomId` has changed. Switching the `theme` shouldn't re-connect to the chat! Move the code reading `theme` out of your Effect into an *Effect Event*: +이것은 이상적이지 않습니다. `roomId`가 변경된 경우에만 채팅에 다시 연결하고 싶습니다. `theme`를 전환해도 채팅에 다시 연결되지 않아야 합니다! `theme`를 읽는 코드를 Effect에서 *Effect Event* 로 옮기세요. @@ -581,19 +581,19 @@ label { display: block; margin-top: 10px; } -Code inside Effect Events isn't reactive, so changing the `theme` no longer makes your Effect re-connect. +Effect Event 내부의 코드는 반응이 아니므로 `theme`를 변경해도 더 이상 Effect가 다시 연결하지 않습니다. -Read **[Separating Events from Effects](/learn/separating-events-from-effects)** to learn how to prevent some values from re-triggering Effects. +일부 값이 Effect를 다시 발생시키는 것을 막는 방법을 배우려면 **[Effect에서 이벤트 분리하기](/learn/separating-events-from-effects)** 를 읽어보세요. -## Removing Effect dependencies {/*removing-effect-dependencies*/} +## Effect의 의존성 제거하기 {/*removing-effect-dependencies*/} -When you write an Effect, the linter will verify that you've included every reactive value (like props and state) that the Effect reads in the list of your Effect's dependencies. This ensures that your Effect remains synchronized with the latest props and state of your component. Unnecessary dependencies may cause your Effect to run too often, or even create an infinite loop. The way you remove them depends on the case. +Effect를 작성하면 린터는 Effect의 의존성 목록에 Effect가 읽는 모든 반응형 값(예를 들어 props 및 State)을 포함했는지 확인합니다. 이렇게 하면 Effect가 컴포넌트의 최신 props 및 State와 동기화 상태를 유지할 수 있습니다. 불필요한 의존성으로 인해 Effect가 너무 자주 실행되거나 무한 루프를 생성할 수도 있습니다. 이 가이드를 따라 Effect에서 불필요한 의존성을 검토하고 제거하세요. -For example, this Effect depends on the `options` object which gets re-created every time you edit the input: +예를 들어 다음 Effect는 사용자가 input을 편집할 때마다 다시 생성되는 `options` 객체에 의존합니다. @@ -668,7 +668,7 @@ button { margin-left: 10px; } -You don't want the chat to re-connect every time you start typing a message in that chat. To fix this problem, move creation of the `options` object inside the Effect so that the Effect only depends on the `roomId` string: +해당 채팅에 메시지를 입력할 때마다 채팅이 다시 연결되는 것을 원치 않을 것입니다. 이 문제를 해결하려면 Effect 내에서 `options` 객체를 생성하여 Effect가 `roomId` 문자열에만 의존하도록 하세요. @@ -742,19 +742,19 @@ button { margin-left: 10px; } -Notice that you didn't start by editing the dependency list to remove the `options` dependency. That would be wrong. Instead, you changed the surrounding code so that the dependency became *unnecessary.* Think of the dependency list as a list of all the reactive values used by your Effect's code. You don't intentionally choose what to put on that list. The list describes your code. To change the dependency list, change the code. +의존성 목록을 편집하여 `options` 의존성을 제거하지 않았음을 알 수 있습니다. 그것은 잘못된 방법일 것입니다. 대신 주변 코드를 변경함으로써 의존성을 *불필요* 하게 만들었습니다. 의존성 목록을 Effect의 코드에서 사용하는 모든 반응형 값의 목록으로 생각하세요. 이 목록에 무엇을 넣을 것인지 의도적으로 선택하는 것이 아닙니다. 이 목록은 당신의 코드를 설명합니다. 의존성 목록을 변경하려면, 코드를 변경하세요. -Read **[Removing Effect Dependencies](/learn/removing-effect-dependencies)** to learn how to make your Effect re-run less often. +Effect 재실행을 줄이는 방법을 배우려면 **[Effect의 의존성 제거하기](/learn/removing-effect-dependencies)** 를 읽어보세요. -## Reusing logic with custom Hooks {/*reusing-logic-with-custom-hooks*/} +## 커스텀 Hook으로 로직 재사용하기 {/*reusing-logic-with-custom-hooks*/} -React comes with built-in Hooks like `useState`, `useContext`, and `useEffect`. Sometimes, you’ll wish that there was a Hook for some more specific purpose: for example, to fetch data, to keep track of whether the user is online, or to connect to a chat room. To do this, you can create your own Hooks for your application's needs. +React는 `useState`, `useContext`, 그리고 `useEffect`같은 Hook들이 내장되어 있습니다. 때로는 데이터를 가져오거나 사용자가 온라인 상태인지 여부를 추적하거나 대화방에 연결하는 등 조금 더 구체적인 목적을 가진 Hook이 존재하길 바랄 수도 있습니다. 이를 위해 애플리케이션의 필요에 따라 자신만의 Hook을 만들 수 있습니다. -In this example, the `usePointerPosition` custom Hook tracks the cursor position, while `useDelayedValue` custom Hook returns a value that's "lagging behind" the value you passed by a certain number of milliseconds. Move the cursor over the sandbox preview area to see a moving trail of dots following the cursor: +이번 예제에서는 `usePointerPosition` 커스텀 Hook은 커서 위치를 추적하는 반면 `useDelayedValue` 커스텀 Hook은 전달한 값보다 특정 밀리초만큼 "지연"된 값을 반환합니다. 샌드박스 미리보기 영역 위로 커서를 이동하면 커서를 따라 움직이는 점의 흔적을 확인할 수 있습니다. @@ -835,14 +835,14 @@ body { min-height: 300px; } -You can create custom Hooks, compose them together, pass data between them, and reuse them between components. As your app grows, you will write fewer Effects by hand because you'll be able to reuse custom Hooks you already wrote. There are also many excellent custom Hooks maintained by the React community. +커스텀 Hook을 생성하고, 함께 구성하고, 서로 데이터를 전달하고, 컴포넌트 사이에서 재사용할 수 있습니다. 앱이 성장함에 따라 이미 작성한 커스텀 Hook을 재사용할 수 있으므로 직접 작성하는 Effect의 수가 줄어들 것입니다. 또한 React 커뮤니티에서 관리하는 훌륭한 커스텀 Hook이 많습니다. -Read **[Reusing Logic with Custom Hooks](/learn/reusing-logic-with-custom-hooks)** to learn how to share logic between components. +컴포넌트 간 로직을 공유하는 방법을 배우려면 **[커스텀 Hook으로 로직 재사용하기](/learn/reusing-logic-with-custom-hooks)** 를 읽어보세요. -## What's next? {/*whats-next*/} +## 다음은 무엇인가요? {/*whats-next*/} -Head over to [Referencing Values with Refs](/learn/referencing-values-with-refs) to start reading this chapter page by page! +이 장을 한 페이지씩 읽어보려면 [Ref로 값 참조하기](/learn/referencing-values-with-refs)로 이동하세요! diff --git a/src/sidebarLearn.json b/src/sidebarLearn.json index 3c4e1a548..7cef2a488 100644 --- a/src/sidebarLearn.json +++ b/src/sidebarLearn.json @@ -160,7 +160,7 @@ ] }, { - "title": "Escape Hatches", + "title": "탈출구", "path": "/learn/escape-hatches", "tags": ["advanced"], "routes": [