From 5aaaea5348eb25f9ec66f0c5db069bc54e54f1d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sat, 16 May 2026 18:28:13 +0900 Subject: [PATCH 1/3] wip --- src/content/reference/react/index.md | 14 +- src/content/reference/react/useId.md | 4 +- src/content/reference/react/useOptimistic.md | 156 +++++++++---------- 3 files changed, 87 insertions(+), 87 deletions(-) diff --git a/src/content/reference/react/index.md b/src/content/reference/react/index.md index 12ba85950..0add7722e 100644 --- a/src/content/reference/react/index.md +++ b/src/content/reference/react/index.md @@ -17,7 +17,7 @@ React의 프로그래밍 기능. * [Hook](/reference/react/hooks) - 컴포넌트에서 다양한 React 기능을 사용하세요. * [컴포넌트](/reference/react/components) - JSX에서 사용할 수 있는 내장 컴포넌트입니다. * [API](/reference/react/apis) - 컴포넌트 정의에 유용한 API들을 다룹니다. -* [지시어](/reference/rsc/directives) - React 서버 컴포넌트와 호환되는 번들러에게 지시를 제공합니다. +* [지시어](/reference/rsc/directives) - React 서버 컴포넌트와 호환되는 번들러에게 지시사항을 제공합니다. ## React DOM {/*react-dom*/} @@ -31,17 +31,17 @@ React DOM은 브라우저 DOM 환경에서 실행되는 웹 애플리케이션 ## React Compiler {/*react-compiler*/} -The React Compiler is a build-time optimization tool that automatically memoizes your React components and values: +React 컴파일러는 React 컴포넌트와 값을 자동으로 메모이제이션하는 빌드 타임 최적화 도구입니다. -* [Configuration](/reference/react-compiler/configuration) - Configuration options for React Compiler. -* [Directives](/reference/react-compiler/directives) - Function-level directives to control compilation. -* [라이브러리 컴파일](/reference/react-compiler/compiling-libraries) - Guide for shipping pre-compiled library code. +* [설정](/reference/react-compiler/configuration) - React 컴파일러의 설정 옵션입니다. +* [지시어](/reference/react-compiler/directives) - 컴파일을 제어하는 함수 수준 지시어입니다. +* [라이브러리 컴파일](/reference/react-compiler/compiling-libraries) - 사전 컴파일된 라이브러리 코드를 배포하는 방법을 안내합니다. ## ESLint Plugin React Hooks {/*eslint-plugin-react-hooks*/} -The [ESLint plugin for React Hooks](/reference/eslint-plugin-react-hooks) helps enforce the Rules of React: +[React Hooks용 ESLint 플러그인](/reference/eslint-plugin-react-hooks)은 React의 규칙을 적용하는 데 도움을 줍니다. -* [린트](/reference/eslint-plugin-react-hooks) - Detailed documentation for each lint with examples. +* [린트](/reference/eslint-plugin-react-hooks) - 각 린트에 대한 자세한 문서와 예시를 제공합니다. ## Rules of React {/*rules-of-react*/} diff --git a/src/content/reference/react/useId.md b/src/content/reference/react/useId.md index 6f1ceaa47..d838146c8 100644 --- a/src/content/reference/react/useId.md +++ b/src/content/reference/react/useId.md @@ -175,7 +175,7 @@ input { margin: 5px; } -#### useId를 사용하는 것이 카운터를 증가하는 것보다 나은 이유는 무엇일까요? {/*why-is-useid-better-than-an-incrementing-counter*/} +#### `useId`를 사용하는 것이 카운터를 증가하는 것보다 나은 이유는 무엇일까요? {/*why-is-useid-better-than-an-incrementing-counter*/} `useId`를 사용하는 것이 `nextId++`처럼 전역 변수를 증가하는 것보다 나은 이유에 대해 궁금할 수 있습니다. @@ -309,7 +309,7 @@ input { margin: 5px; } ### 클라이언트와 서버에서 동일한 ID 접두사 사용하기 {/*using-the-same-id-prefix-on-the-client-and-the-server*/} -[동일한 페이지에서 여러 독립적인 React 앱을 렌더링하는 경우](#specifying-a-shared-prefix-for-all-generated-ids), 이러한 앱 중 일부가 서버에서 렌더링되는 경우, 클라이언트 측에서 [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) 호출에 전달하는 `identifierPrefix가` [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)와 같은 [서버 API](/reference/react-dom/server)에 전달하는 `identifierPrefix`와 동일한지 확인해야 합니다. +[동일한 페이지에서 여러 독립적인 React 앱을 렌더링하는 경우](#specifying-a-shared-prefix-for-all-generated-ids), 이러한 앱 중 일부가 서버에서 렌더링되는 경우, 클라이언트 측에서 [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) 호출에 전달하는 `identifierPrefix`가 [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)와 같은 [서버 API](/reference/react-dom/server)에 전달하는 `identifierPrefix`와 동일한지 확인해야 합니다. ```js // Server diff --git a/src/content/reference/react/useOptimistic.md b/src/content/reference/react/useOptimistic.md index 9b75f65af..3c8dcb32c 100644 --- a/src/content/reference/react/useOptimistic.md +++ b/src/content/reference/react/useOptimistic.md @@ -4,7 +4,7 @@ title: useOptimistic -`useOptimistic` 는 UI를 낙관적으로 업데이트할 수 있게 해주는 React Hook입니다. +`useOptimistic`은 UI를 낙관적으로 업데이트할 수 있게 해주는 React Hook입니다. ```js const [optimisticState, setOptimistic] = useOptimistic(value, reducer?); @@ -40,7 +40,7 @@ function MyComponent({name, todos}) { #### 매개변수 {/*parameters*/} * `state`: 작업이 대기 중이지 않을 때 초기에 반환될 값입니다. -* `updateFn(currentState, optimisticValue)`: 현재 상태와 addOptimistic에 전달된 낙관적인 값을 취하는 함수로, 결과적인 낙관적인 상태를 반환합니다. 순수 함수여야 합니다. `updateFn`은 두 개의 매개변수를 취합니다. `currentState`와 `optimisticValue`. 반환 값은 `currentState`와 `optimisticValue`의 병합된 값입니다. +* `updateFn(currentState, optimisticValue)`: 현재 State와 `addOptimistic`에 전달된 낙관적인 값을 취하는 함수로, 결과적인 낙관적인 State를 반환합니다. 순수 함수여야 합니다. `updateFn`은 두 개의 매개변수를 취합니다. `currentState`와 `optimisticValue`. 반환 값은 `currentState`와 `optimisticValue`의 병합된 값입니다. #### 반환값 {/*returns*/} @@ -110,21 +110,21 @@ export async function submitForm() { -When the button is clicked, `setIsPending(true)` uses optimistic state to immediately show "Submitting..." and disable the button. When the Action is done, `isPending` is rendered as `false` automatically. +버튼을 클릭하면 `setIsPending(true)`가 낙관적 state를 사용하여 즉시 "Submitting..."을 표시하고 버튼을 비활성화합니다. Action이 완료되면 `isPending`은 자동으로 `false`로 렌더링됩니다. -This pattern automatically shows a pending state however `action` prop is used with `Button`: +이 패턴은 `Button`에서 `action` prop을 어떤 방식으로 사용하든 보류 상태를 자동으로 표시합니다. ```js -// Show pending state for a state update +// state 업데이트에 대한 보류 상태 표시 + 카운터: {count} +

- Every second, increment by: + 매초 다음 값만큼 증가: @@ -179,15 +179,15 @@ export default function Timer() { -Try changing the increment value while the timer is running. The counter immediately uses the new increment value, but the timer keeps ticking smoothly without restarting. +타이머가 실행 중일 때 증가 값을 바꿔 보세요. 카운터는 새 증가 값을 즉시 사용하지만, 타이머는 다시 시작되지 않고 부드럽게 계속 실행됩니다. --- -### Using an event listener with latest values {/*using-an-event-listener-with-latest-values*/} +### 최신 값으로 이벤트 리스너 사용하기 {/*using-an-event-listener-with-latest-values*/} -When you set up an event listener in an Effect, you often need to read the latest values from render in the callback. Without `useEffectEvent`, you would need to include the values in your dependencies, causing the listener to be removed and re-added on every change. +Effect에서 이벤트 리스너를 설정할 때, 콜백에서 렌더링의 최신 값을 읽어야 하는 경우가 많습니다. `useEffectEvent`가 없다면 그 값들을 의존성에 포함해야 하므로, 값이 바뀔 때마다 리스너가 제거되고 다시 추가됩니다. -This example shows a dot that follows the cursor, but only when "Can move" is checked. The `onMove` Effect Event always reads the latest `canMove` value without re-running the Effect: +이 예시는 커서를 따라가는 점을 보여주지만, "점 움직이게 하기"가 체크된 경우에만 움직입니다. `onMove` Effect 이벤트는 Effect를 다시 실행하지 않고 항상 최신 `canMove` 값을 읽습니다. @@ -217,7 +217,7 @@ export default function App() { checked={canMove} onChange={e => setCanMove(e.target.checked)} /> - The dot is allowed to move + 점 움직이게 하기


-Toggle the checkbox and move your cursor. The dot responds immediately to the checkbox state, but the event listener is only set up once when the component mounts. +체크박스를 토글하고 커서를 움직여 보세요. 점은 체크박스 state에 즉시 반응하지만, 이벤트 리스너는 컴포넌트가 마운트될 때 한 번만 설정됩니다. --- -### Avoid reconnecting to external systems {/*showing-a-notification-without-reconnecting*/} +### 외부 시스템에 다시 연결하지 않기 {/*showing-a-notification-without-reconnecting*/} -A common use case for `useEffectEvent` is when you want to do something in response to an Effect, but that "something" depends on a value you don't want to react to. +`useEffectEvent`의 일반적인 사용 사례는 Effect에 대한 응답으로 무언가를 해야 하지만, 그 "무언가"가 Effect를 다시 실행시키고 싶지 않은 값에 의존하는 경우입니다. -In this example, a chat component connects to a room and shows a notification when connected. The user can mute notifications with a checkbox. However, you don't want to reconnect to the chat room every time the user changes the settings: +이 예시에서 채팅 컴포넌트는 방에 연결하고 연결되면 알림을 보여줍니다. 사용자는 체크박스로 알림을 음소거할 수 있습니다. 하지만 사용자가 설정을 바꿀 때마다 채팅방에 다시 연결되기를 원하지는 않습니다. @@ -281,26 +281,26 @@ import { showNotification } from './notifications.js'; function ChatRoom({ roomId, muted }) { const onConnected = useEffectEvent((roomId) => { - console.log('✅ Connected to ' + roomId + ' (muted: ' + muted + ')'); + console.log('✅ ' + roomId + '에 연결됨 (음소거: ' + muted + ')'); if (!muted) { - showNotification('Connected to ' + roomId); + showNotification(roomId + '에 연결됨'); } }); useEffect(() => { const connection = createConnection(roomId); - console.log('⏳ Connecting to ' + roomId + '...'); + console.log('⏳ ' + roomId + '에 연결 중...'); connection.on('connected', () => { onConnected(roomId); }); connection.connect(); return () => { - console.log('❌ Disconnected from ' + roomId); + console.log('❌ ' + roomId + '에서 연결 끊김'); connection.disconnect(); } }, [roomId]); - return

Welcome to the {roomId} room!

; + return

{roomId} 방에 오신 것을 환영합니다!

; } export default function App() { @@ -309,7 +309,7 @@ export default function App() { return ( <>
-In this example, `useInterval` is a custom Hook that sets up an interval. The `callback` passed to it is wrapped in an Effect Event, so the interval does not reset even if a new `callback` is passed in every render. +이 예시에서 `useInterval`은 interval을 설정하는 커스텀 Hook입니다. 전달된 `callback`은 Effect 이벤트로 감싸지므로, 렌더링마다 새 `callback`이 전달되어도 interval은 재설정되지 않습니다. --- -## Troubleshooting {/*troubleshooting*/} +## 문제 해결 {/*troubleshooting*/} -### I'm getting an error: "A function wrapped in useEffectEvent can't be called during rendering" {/*cant-call-during-rendering*/} +### 오류가 발생합니다: "A function wrapped in useEffectEvent can't be called during rendering" {/*cant-call-during-rendering*/} -This error means you're calling an Effect Event function during the render phase of your component. Effect Events can only be called from inside Effects or other Effect Events. +이 오류는 컴포넌트의 렌더링 단계 중에 Effect 이벤트 함수를 호출하고 있다는 뜻입니다. Effect 이벤트는 Effect 내부 또는 다른 Effect 이벤트 내부에서만 호출할 수 있습니다. ```js function MyComponent({ data }) { @@ -479,10 +479,10 @@ function MyComponent({ data }) { console.log(data); }); - // 🔴 Wrong: calling during render + // 🔴 잘못된 예시: 렌더링 중 호출 onLog(); - // ✅ Correct: call from an Effect + // ✅ 올바른 예시: Effect에서 호출 useEffect(() => { onLog(); }, []); @@ -491,55 +491,55 @@ function MyComponent({ data }) { } ``` -If you need to run logic during render, don't wrap it in `useEffectEvent`. Call the logic directly or move it into an Effect. +렌더링 중에 로직을 실행해야 한다면 `useEffectEvent`로 감싸지 마세요. 로직을 직접 호출하거나 Effect 내부로 옮기세요. --- -### I'm getting a lint error: "Functions returned from useEffectEvent must not be included in the dependency array" {/*effect-event-in-deps*/} +### 린트 오류가 발생합니다: "Functions returned from useEffectEvent must not be included in the dependency array" {/*effect-event-in-deps*/} -If you see a warning like "Functions returned from `useEffectEvent` must not be included in the dependency array", remove the Effect Event from your dependencies: +"Functions returned from useEffectEvent must not be included in the dependency array"와 같은 경고가 보이면 Effect 이벤트를 의존성에서 제거하세요. ```js const onSomething = useEffectEvent(() => { // ... }); -// 🔴 Wrong: Effect Event in dependencies +// 🔴 잘못된 예시: 의존성에 Effect 이벤트 포함 useEffect(() => { onSomething(); }, [onSomething]); -// ✅ Correct: no Effect Event in dependencies +// ✅ 올바른 예시: 의존성에 Effect 이벤트 없음 useEffect(() => { onSomething(); }, []); ``` -Effect Events are designed to be called from Effects without being listed as dependencies. The linter enforces this because the function identity is [intentionally not stable](#why-are-effect-events-not-stable). Including it would cause your Effect to re-run on every render. +Effect 이벤트는 의존성으로 지정하지 않고 Effect에서 호출하도록 설계되었습니다. 함수 식별성이 [의도적으로 안정적이지 않기](#why-are-effect-events-not-stable) 때문에 린터가 이를 강제합니다. 의존성에 포함하면 Effect가 렌더링마다 다시 실행됩니다. --- -### I'm getting a lint error: "... is a function created with useEffectEvent, and can only be called from Effects" {/*effect-event-called-outside-effect*/} +### 린트 오류가 발생합니다: "... is a function created with useEffectEvent, and can only be called from Effects" {/*effect-event-called-outside-effect*/} -If you see a warning like "... is a function created with React Hook `useEffectEvent`, and can only be called from Effects and Effect Events", you're calling the function from the wrong place: +"... is a function created with React Hook `useEffectEvent`, and can only be called from Effects and Effect Events"와 같은 경고가 보이면 함수를 잘못된 위치에서 호출하고 있다는 뜻입니다. ```js const onSomething = useEffectEvent(() => { console.log(value); }); -// 🔴 Wrong: calling from event handler +// 🔴 잘못된 예시: 이벤트 핸들러에서 호출 function handleClick() { onSomething(); } -// 🔴 Wrong: passing to child component +// 🔴 잘못된 예시: 자식 컴포넌트에 전달 return ; -// ✅ Correct: calling from Effect +// ✅ 올바른 예시: Effect에서 호출 useEffect(() => { onSomething(); }, []); ``` -Effect Events are specifically designed to be used in Effects local to the component they're defined in. If you need a callback for event handlers or to pass to children, use a regular function or `useCallback` instead. +Effect 이벤트는 자신이 정의된 컴포넌트의 Effect에서만 지역적으로 사용되도록 특별히 설계되었습니다. 이벤트 핸들러에 쓰거나 자식에게 전달할 콜백이 필요하다면 일반 함수나 `useCallback`을 대신 사용하세요. From 5f63ad09860f34d0fe523183636c7c71735eca52 Mon Sep 17 00:00:00 2001 From: lumir Date: Sat, 16 May 2026 21:23:13 +0900 Subject: [PATCH 3/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/content/reference/react/useOptimistic.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/useOptimistic.md b/src/content/reference/react/useOptimistic.md index 3c8dcb32c..e54a2b9bd 100644 --- a/src/content/reference/react/useOptimistic.md +++ b/src/content/reference/react/useOptimistic.md @@ -40,7 +40,7 @@ function MyComponent({name, todos}) { #### 매개변수 {/*parameters*/} * `state`: 작업이 대기 중이지 않을 때 초기에 반환될 값입니다. -* `updateFn(currentState, optimisticValue)`: 현재 State와 `addOptimistic`에 전달된 낙관적인 값을 취하는 함수로, 결과적인 낙관적인 State를 반환합니다. 순수 함수여야 합니다. `updateFn`은 두 개의 매개변수를 취합니다. `currentState`와 `optimisticValue`. 반환 값은 `currentState`와 `optimisticValue`의 병합된 값입니다. +* `updateFn(currentState, optimisticValue)`: 현재 state와 `addOptimistic`에 전달된 낙관적인 값을 취하는 함수로, 결과적인 낙관적인 state를 반환합니다. 순수 함수여야 합니다. `updateFn`은 두 개의 매개변수를 취합니다. `currentState`와 `optimisticValue`. 반환 값은 `currentState`와 `optimisticValue`의 병합된 값입니다. #### 반환값 {/*returns*/}