Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions src/content/blog/2024/12/05/react-19.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function UpdateName({}) {

액션은 데이터 제출을 자동으로 관리합니다.

- **대기 상태**: 액션은 요청 시작 시 대기 상태를 활성화하고 최종 상태가 커밋되었을때 자동으로 초기화합니다.
- **대기 상태**: 액션은 요청 시작 시 대기 상태를 활성화하고 최종 상태가 커밋되었을 때 자동으로 초기화합니다.
- **낙관적 업데이트**: 액션은 새로운 [`useOptimistic`](#new-hook-optimistic-updates)훅을 통해 사용자가 요청을 제출하는 동안 즉각적인 피드백을 표시할 수 있습니다.
- **에러 처리**: 액션은 요청 실패 시 Error Boundary를 보여주고 낙관적 업데이트를 원래 값으로, 자동으로 돌려놓습니다.
- **폼**: `<form>` 엘리먼트는 `action` 및 `formAction` props에 함수를 전달하는 것을 지원합니다. `action` props에 함수가 전달되면 기본적으로 액션을 사용하며 제출 후 폼을 자동으로 초기화합니다.
Expand Down Expand Up @@ -320,7 +320,7 @@ function Heading({children}) {
}
```

`use` API는 Hook과 유사하게 오직 렌더링 중일때만 호출됩니다. 훅과 달리 `use`는 조건적으로 호출됩니다. 앞으로 `use`를 사용하여 렌더링 중일 때 리소스들을 소비하도록 더 많은 방법을 지원할 계획입니다.
`use` API는 Hook과 유사하게 오직 렌더링 중일 때만 호출됩니다. 훅과 달리 `use`는 조건적으로 호출됩니다. 앞으로 `use`를 사용하여 렌더링 중일 때 리소스들을 소비하도록 더 많은 방법을 지원할 계획입니다.

더 많은 정보는 [`use`](/reference/react/use)문서를 참고하세요.

Expand Down Expand Up @@ -691,7 +691,7 @@ function MyComponent() {
preinit('https://.../path/to/some/script.js', {as: 'script' }) // 스크립트 즉시 로드 실행
preload('https://.../path/to/font.woff', { as: 'font' }) // 폰트 사전로드
preload('https://.../path/to/stylesheet.css', { as: 'style' }) // 스타일시트 사전로드
prefetchDNS('https://...') // 실제로 이 호스트에서 아무것도 요청하지 않을때
prefetchDNS('https://...') // 실제로 이 호스트에서 아무것도 요청하지 않을 때
preconnect('https://...') // 어떤 것을 요청할지 확신하지 못할 때
}
```
Expand Down
6 changes: 3 additions & 3 deletions src/content/learn/extracting-state-logic-into-a-reducer.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ function handleDeleteTask(taskId) {
}
```

이 객체는 일반적인 자바스크립트 객체입니다. 이 안에 어떤 것이든 자유롭게 넣을 수 있지만, 일반적으로 *어떤 상황이 발생하는지*에 대한 최소한의 정보를 담고 있어야합니다. (`dispatch` 함수 자체에 대한 부분은 이후 단계에서 다룰 예정입니다.)
이 객체는 일반적인 자바스크립트 객체입니다. 이 안에 어떤 것이든 자유롭게 넣을 수 있지만, 일반적으로 *어떤 상황이 발생하는지*에 대한 최소한의 정보를 담고 있어야 합니다. (`dispatch` 함수 자체에 대한 부분은 이후 단계에서 다룰 예정입니다.)

<Note>

Expand Down Expand Up @@ -359,7 +359,7 @@ function tasksReducer(tasks, action) {
}
```

각자 다른 `case` 속에서 선언된 변수들이 서로 충돌하지 않도록 `case` 블록을 중괄호인 `{`와 `}`로 감싸는 걸 추천합니다. 또 `case`는 일반적인 경우라면 `return`으로 끝나야합니다. `return` 하는 것을 잊으면 코드가 다음 `case`로 "떨어져" 실수할 수 있습니다!
각자 다른 `case` 속에서 선언된 변수들이 서로 충돌하지 않도록 `case` 블록을 중괄호인 `{`와 `}`로 감싸는 걸 추천합니다. 또 `case`는 일반적인 경우라면 `return`으로 끝나야 합니다. `return` 하는 것을 잊으면 코드가 다음 `case`로 "떨어져" 실수할 수 있습니다!

아직 `switch` 문에 익숙하지 않다면, `if`/`else` 문을 사용해도 괜찮습니다.

Expand Down Expand Up @@ -2152,7 +2152,7 @@ textarea {

<Solution>

reducer는 각 연락처마다 별도의 message 초기 값을 저장하고 업데이트할 수 있도록 바꿔야합니다.
reducer는 각 연락처마다 별도의 message 초기 값을 저장하고 업데이트할 수 있도록 바꿔야 합니다.

```js
// input 텍스트 값이 수정될 때
Expand Down
2 changes: 1 addition & 1 deletion src/content/learn/referencing-values-with-refs.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ function useRef(initialValue) {

첫 번째 렌더링 중에 `useRef`는 `{ current: initialValue }`를 반환합니다. 이 객체는 React에 의해 저장되므로 다음 렌더링 중에 같은 객체를 반환합니다. 이 예시에서는 State Setter를 사용하지 않는 점에 주목하세요. `useRef`는 항상 동일한 객체를 반환해야 하므로 필요하지 않습니다!

React는 `useRef`가 실제로 충분히 일반적이기 때문에 built-in 버전을 제공합니다. setter가 없는 일반적인 state 변수라고 생각할 수 있습니다. 객체 지향 프로그래밍에 익숙하다면 Ref는 인스턴스 필드를 상기시킬 수 있습니다. 하지만 `this.something` 대신에 `somethingRef.current` 처럼 써야합니다.
React는 `useRef`가 실제로 충분히 일반적이기 때문에 built-in 버전을 제공합니다. setter가 없는 일반적인 state 변수라고 생각할 수 있습니다. 객체 지향 프로그래밍에 익숙하다면 Ref는 인스턴스 필드를 상기시킬 수 있습니다. 하지만 `this.something` 대신에 `somethingRef.current` 처럼 써야 합니다.

</DeepDive>

Expand Down
2 changes: 1 addition & 1 deletion src/content/learn/removing-effect-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ function Form() {
}
```

나중에 현재 테마에 따라 알림 메시지의 스타일을 지정하고 싶으므로 현재 테마를 읽습니다. `theme`는 컴포넌트 본문에서 선언되었기때문에 이는 반응형 값이므로 의존성으로 추가합니다.
나중에 현재 테마에 따라 알림 메시지의 스타일을 지정하고 싶으므로 현재 테마를 읽습니다. `theme`는 컴포넌트 본문에서 선언되었기 때문에 이는 반응형 값이므로 의존성으로 추가합니다.

```js {3,9,11}
function Form() {
Expand Down
2 changes: 1 addition & 1 deletion src/content/learn/synchronizing-with-effects.md
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,7 @@ import { useEffect, useRef } from 'react';
export default function MyInput({ shouldFocus, value, onChange }) {
const ref = useRef(null);

// TODO: shouldFocus가 true일때만 호출되도록
// TODO: shouldFocus가 true일 때만 호출되도록
useEffect(() => {
ref.current.focus();
}, []);
Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react-dom/components/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ function Form() {
</button>
```

제어되는 컴포넌트에 전달되는 `value`는 `undefined`나 `null`이 되어서는 안됩니다. 아래의 `firstName` 필드처럼 초기값을 비워두어야 하는 경우 State 변수를 빈 문자열(`''`)로 초기화 하세요.
제어되는 컴포넌트에 전달되는 `value`는 `undefined`나 `null`이 되어서는 안 됩니다. 아래의 `firstName` 필드처럼 초기값을 비워두어야 하는 경우 State 변수를 빈 문자열(`''`)로 초기화 하세요.

<Sandpack>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ async function handler(request) {
}
```

<CodeStep step={1}>root 컴포넌트</CodeStep>와 함께, <CodeStep step={2}>bootstrap `<script>` 경로</CodeStep> 리스트를 제공해야합니다. 제공된 root 컴포넌트는 **최상위 `<html>` 태그를 포함한 모든 문서를 포함해서** 반환되어야 합니다.
<CodeStep step={1}>root 컴포넌트</CodeStep>와 함께, <CodeStep step={2}>bootstrap `<script>` 경로</CodeStep> 리스트를 제공해야 합니다. 제공된 root 컴포넌트는 **최상위 `<html>` 태그를 포함한 모든 문서를 포함해서** 반환되어야 합니다.

예를 들어, 다음과 같은 형태가 되어야 합니다.

Expand Down Expand Up @@ -124,7 +124,7 @@ React는 [doctype](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)과
<script src="/main.js" async=""></script>
```

클라이언트에선, 추가된 bootstrap 스크립트는 [`hydrateRoot`를 호출해 `document` 전체를 hydrate 해야합니다](/reference/react-dom/client/hydrateRoot#hydrating-an-entire-document).
클라이언트에선, 추가된 bootstrap 스크립트는 [`hydrateRoot`를 호출해 `document` 전체를 hydrate 해야 합니다](/reference/react-dom/client/hydrateRoot#hydrating-an-entire-document).

```js [[1, 4, "<App />"]]
import { hydrateRoot } from 'react-dom/client';
Expand All @@ -141,7 +141,7 @@ hydrateRoot(document, <App />);

JS와 CSS같은 최종 에셋들에 대한 URL들은 종종 빌드 후에 해시됩니다. 예를 들어, `styles.css` 대신 `styles.123456.css`와 같은 형태로 끝날 수 있습니다. 에셋들의 파일명을 해시하는 것은 모든 빌드의 결과물이 각각 다른 파일명을 가지도록 보장합니다. 이는 정적 에셋들에 대한 장기 캐싱을 안전하게 활성화할 수 있도록 해줍니다. 즉, 특정 이름의 파일 내용은 절대 바뀌지 않는 다는 것을 보장합니다.

하지만, 빌드 후에 에셋들의 URL을 알 수 없다면, 소스 코드에 URL을 넣을 수 없습니다. 예를 들어, JSX에 `"/styles.css"`를 하드코딩하는 것은 작동하지 않습니다. 소스 코드에 URL을 넣지 않으려면, 루트 컴포넌트는 props로 전달된 맵에서 실제 파일명을 읽어야합니다.
하지만, 빌드 후에 에셋들의 URL을 알 수 없다면, 소스 코드에 URL을 넣을 수 없습니다. 예를 들어, JSX에 `"/styles.css"`를 하드코딩하는 것은 작동하지 않습니다. 소스 코드에 URL을 넣지 않으려면, 루트 컴포넌트는 props로 전달된 맵에서 실제 파일명을 읽어야 합니다.

```js {1,6}
export default function App({ assetMap }) {
Expand All @@ -160,7 +160,7 @@ export default function App({ assetMap }) {
서버에선 `<App assetMap={assetMap} />`을 렌더링하고, 에셋 URL들과 함께 `assetMap`을 전달합니다.

```js {1-5,8,9}
// 빌드 도구로부터 이 JSON을 얻어야합니다. 예를 들어, 빌드 결과물에서 읽어올 수 있습니다.
// 빌드 도구로부터 이 JSON을 얻어야 합니다. 예를 들어, 빌드 결과물에서 읽어올 수 있습니다.
const assetMap = {
'styles.css': '/styles.123456.css',
'main.js': '/main.123456.js'
Expand All @@ -176,10 +176,10 @@ async function handler(request) {
}
```

서버가 `<App assetMap={assetMap} />`를 렌더링한 이후엔, 클라이언트에서도 hydration 오류를 피하기 위해 `assetMap`과 함께 렌더링해야합니다. `assetMap`을 직렬화하고 클라이언트에 전달하기 위해 다음과 같이 할 수 있습니다.
서버가 `<App assetMap={assetMap} />`를 렌더링한 이후엔, 클라이언트에서도 hydration 오류를 피하기 위해 `assetMap`과 함께 렌더링해야 합니다. `assetMap`을 직렬화하고 클라이언트에 전달하기 위해 다음과 같이 할 수 있습니다.

```js {9-10}
// 빌드 도구로부터 이 JSON을 얻어야합니다.
// 빌드 도구로부터 이 JSON을 얻어야 합니다.
const assetMap = {
'styles.css': '/styles.123456.css',
'main.js': '/main.123456.js'
Expand Down
4 changes: 2 additions & 2 deletions src/content/reference/react/Component.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class Greeting extends Component {

### `state` {/*state*/}

클래스 컴포넌트의 state는 `this.state`로 사용할 수 있습니다. `state` 필드는 반드시 객체여야합니다. state를 직접 변경하지 마세요. state를 변경하려면 새 state로 `setState`를 호출하세요.
클래스 컴포넌트의 state는 `this.state`로 사용할 수 있습니다. `state` 필드는 반드시 객체여야 합니다. state를 직접 변경하지 마세요. state를 변경하려면 새 state로 `setState`를 호출하세요.

```js {2-4,7-9,18}
class Counter extends Component {
Expand Down Expand Up @@ -172,7 +172,7 @@ class Counter extends Component {
}
```

constructor는 부수 효과 또는 구독을 포함하면 안됩니다.
constructor는 부수 효과 또는 구독을 포함하면 안 됩니다.

#### 매개변수 {/*constructor-parameters*/}

Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react/ViewTransition.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import {ViewTransition} from 'react';

내부적으로 React는 `<ViewTransition>` 컴포넌트 내부에 중첩된 가장 가까운 DOM 노드의 인라인 스타일에 `view-transition-name`을 적용합니다. `<ViewTransition><div /><div /></ViewTransition>`처럼 여러 형제 DOM 노드가 있을 경우, React는 각 노드의 이름이 고유하도록 접미사를 추가하지만, 개념적으로는 동일한 전환에 속하는 것으로 간주합니다.

React는 내부적으로 `startViewTransition`을 자체적으로 호출하므로 직접 호출해서는 안됩니다. 실제로 페이지에서 다른 스크립트나 코드가 ViewTransition을 실행하고 있다면 React가 이를 중단합니다. 따라서 React 자체를 사용하여 이를 조정하는 것을 권장합니다. 과거에 ViewTransition을 트리거하는 다른 방법이 있었다면 내장 방법으로 마이그레이션하는 것을 권장합니다.
React는 내부적으로 `startViewTransition`을 자체적으로 호출하므로 직접 호출해서는 안 됩니다. 실제로 페이지에서 다른 스크립트나 코드가 ViewTransition을 실행하고 있다면 React가 이를 중단합니다. 따라서 React 자체를 사용하여 이를 조정하는 것을 권장합니다. 과거에 ViewTransition을 트리거하는 다른 방법이 있었다면 내장 방법으로 마이그레이션하는 것을 권장합니다.

다른 React ViewTransition이 이미 실행 중이라면, React는 그것들을 완료할 때까지 다음 전환을 시작하지 않습니다. 그러나 중요한 점은 첫 번째 전환이 진행되는 동안 여러 업데이트가 발생하면, 그 업데이트들은 모두 하나로 묶여 처리된다는 것입니다. 예를 들어 A에서 B로 이동하는 전환을 시작했다고 가정합시다. 그 사이에 C로 가는 업데이트가 발생하고 다시 D로 가는 업데이트가 발생한다면, 첫 번째 A->B 애니메이션이 끝난 후 다음 애니메이션은 B에서 D로 전환됩니다.

Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react/captureOwnerStack.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ at Component

`Navigation`과 `legend`는 `<SubComponent />`를 포함하는 노드의 형제 요소이기 때문에 스택에 전혀 포함되지 않습니다.

`SubComponent`는 이미 호출 스택에 포함되어 있기 떄문에 Owner Stack에 나타나지 않습니다.
`SubComponent`는 이미 호출 스택에 포함되어 있기 때문에 Owner Stack에 나타나지 않습니다.

</DeepDive>

Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react/isValidElement.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ console.log(isValidElement(MyComponent)); // false

```js
function MyComponent() {
// ... React 노드를 반환할수 있습니다. ...
// ... React 노드를 반환할 수 있습니다. ...
}
```

Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react/useCallback.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const ShippingForm = memo(function ShippingForm({ onSubmit }) {

```js {2,3,8,12-13}
function ProductPage({ productId, referrer, theme }) {
// theme이 바뀔때마다 다른 함수가 될 것입니다...
// theme이 바뀔 때마다 다른 함수가 될 것입니다...
function handleSubmit(orderDetails) {
post('/product/' + productId + '/buy', {
referrer,
Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react/useEffect.md
Original file line number Diff line number Diff line change
Expand Up @@ -1327,7 +1327,7 @@ useEffect(() => {
}); // 항상 다시 실행됨
```

이 예시에서 Effect는 `serverUrl`과 `roomId`를 변경할 때 다시 실행하는 것은 합리적입니다. 그러나 `message`를 변경할때도 다시 실행되므로 바람직하지 않습니다. 보통은 이런 이슈를 방지하고자 의존성 배열을 명시합니다.
이 예시에서 Effect는 `serverUrl`과 `roomId`를 변경할 때 다시 실행하는 것은 합리적입니다. 그러나 `message`를 변경할 때도 다시 실행되므로 바람직하지 않습니다. 보통은 이런 이슈를 방지하고자 의존성 배열을 명시합니다.

<Sandpack>

Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react/useInsertionEffect.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function useCSS(rule) {
* 이펙트는 클라이언트에서만 실행됩니다. 서버 렌더링 중에는 실행되지 않습니다.
* `useInsertionEffect` 내부에서는 상태를 업데이트할 수 없습니다.
* `useInsertionEffect`가 실행되는 시점에 ref는 아직 연결되지 않습니다.
* `useInsertionEffect` 는 DOM 의 업데이트 전 또는 후에 실행됩니다. DOM 이 업데이트 되는 특정시점에 의존해서는 안됩니다.
* `useInsertionEffect` 는 DOM 의 업데이트 전 또는 후에 실행됩니다. DOM 이 업데이트 되는 특정시점에 의존해서는 안 됩니다.
* 매번 모든 cleanup 을 실행하고 setup 하는 다른 Effects 와 달리, `useInsertionEffect` 는 하나의 컴포넌트에 대해 cleanup 과 setup 을 모두 실행합니다. 그 결과 cleanup 과 setup 이 'interleaving' 됩니다.

---
Expand Down
6 changes: 3 additions & 3 deletions src/content/reference/react/useMemo.md
Original file line number Diff line number Diff line change
Expand Up @@ -1103,13 +1103,13 @@ function ChatRoom({ roomId }) {
serverUrl: 'https://localhost:1234',
roomId: roomId
};
}, [roomId]); // ✅ roomId가 변경될때만 실행됩니다.
}, [roomId]); // ✅ roomId가 변경될 때만 실행됩니다.

useEffect(() => {
const connection = createConnection(options);
connection.connect();
return () => connection.disconnect();
}, [options]); // ✅ options가 변경될때만 실행됩니다.
}, [options]); // ✅ options가 변경될 때만 실행됩니다.
// ...
```

Expand All @@ -1131,7 +1131,7 @@ function ChatRoom({ roomId }) {
const connection = createConnection(options);
connection.connect();
return () => connection.disconnect();
}, [roomId]); // ✅ roomId가 변경될때에만 실행됩니다.
}, [roomId]); // ✅ roomId가 변경될 때에만 실행됩니다.
// ...
```

Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/react/useReducer.md
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ export default function TodoList({ username }) {

#### 초기 state 직접 전달 {/*passing-the-initial-state-directly*/}

이 예시에서는 초기화 함수를 **전달하지 않으므로**, `createInitialState` 함수는 인풋에 입력을 할때 발생하는 리렌더링에서도 매번 호출됩니다. 이 코드는 동작에는 큰 차이가 없을 수 있지만, 효율성이 떨어집니다.
이 예시에서는 초기화 함수를 **전달하지 않으므로**, `createInitialState` 함수는 인풋에 입력을 할 때 발생하는 리렌더링에서도 매번 호출됩니다. 이 코드는 동작에는 큰 차이가 없을 수 있지만, 효율성이 떨어집니다.

<Sandpack>

Expand Down
2 changes: 1 addition & 1 deletion src/content/reference/rsc/use-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,4 @@ export default async function incrementLike() {
}
```

서버 함수의 반환 값을 읽으려면 반환된 Promise를 `await` 해야합니다.
서버 함수의 반환 값을 읽으려면 반환된 Promise를 `await` 해야 합니다.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Hook은 컴포넌트에 React 기능을 추가할 수 있게 합니다. Hook은

### Hook을 동적으로 변경하지 마세요 {/*dont-dynamically-mutate-a-hook*/}

Hook은 가능한 한 "정적"으로 유지되어야 합니다. 이는 Hook을 동적으로 변경해서는 안 된다는 의미입니다. 예를 들어 고차 Hook을 작성하면 안됩니다.
Hook은 가능한 한 "정적"으로 유지되어야 합니다. 이는 Hook을 동적으로 변경해서는 안 된다는 의미입니다. 예를 들어 고차 Hook을 작성하면 안 됩니다.

```js {2}
function ChatInput() {
Expand Down
Loading