Skip to content

Commit f4617d8

Browse files
merging all conflicts
2 parents b6eae7d + 5138e60 commit f4617d8

File tree

13 files changed

+73
-86
lines changed

13 files changed

+73
-86
lines changed

src/components/MDX/ErrorDecoder.tsx

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function parseQueryString(search: string): Array<string | undefined> {
6969
}
7070

7171
export default function ErrorDecoder() {
72-
const {errorMessage} = useErrorDecoderParams();
72+
const {errorMessage, errorCode} = useErrorDecoderParams();
7373
/** error messages that contain %s require reading location.search */
7474
const hasParams = errorMessage?.includes('%s');
7575
const [message, setMessage] = useState<React.ReactNode | null>(() =>
@@ -82,23 +82,28 @@ export default function ErrorDecoder() {
8282
if (errorMessage == null || !hasParams) {
8383
return;
8484
}
85+
const args = parseQueryString(window.location.search);
86+
let message = errorMessage;
87+
if (errorCode === '418') {
88+
// Hydration errors have a %s for the diff, but we don't add that to the args for security reasons.
89+
message = message.replace(/%s$/, '');
8590

86-
setMessage(
87-
urlify(
88-
replaceArgs(
89-
errorMessage,
90-
parseQueryString(window.location.search),
91-
'[missing argument]'
92-
)
93-
)
94-
);
91+
// Before React 19.1, the error message didn't have an arg, and was always HTML.
92+
if (args.length === 0) {
93+
args.push('HTML');
94+
} else if (args.length === 1 && args[0] === '') {
95+
args[0] = 'HTML';
96+
}
97+
}
98+
99+
setMessage(urlify(replaceArgs(message, args, '[missing argument]')));
95100
setIsReady(true);
96-
}, [hasParams, errorMessage]);
101+
}, [errorCode, hasParams, errorMessage]);
97102

98103
return (
99104
<code
100105
className={cn(
101-
'block bg-red-100 text-red-600 py-4 px-6 mt-5 rounded-lg',
106+
'whitespace-pre-line block bg-red-100 text-red-600 py-4 px-6 mt-5 rounded-lg',
102107
isReady ? 'opacity-100' : 'opacity-0'
103108
)}>
104109
<b>{message}</b>

src/components/MDX/Sandpack/template.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ root.render(
2828
eject: 'react-scripts eject',
2929
},
3030
dependencies: {
31-
react: '19.0.0-rc-3edc000d-20240926',
32-
'react-dom': '19.0.0-rc-3edc000d-20240926',
31+
react: '^19.1.0',
32+
'react-dom': '^19.1.0',
3333
'react-scripts': '^5.0.0',
3434
},
3535
},

src/content/community/meetups.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet
8181
* [Thessaloniki](https://www.meetup.com/Thessaloniki-ReactJS-Meetup/)
8282

8383
## India {/*india*/}
84-
* [Ahmedabad](https://www.meetup.com/react-ahmedabad/)
84+
* [Ahmedabad](https://reactahmedabad.dev/)
8585
* [Bangalore (React)](https://www.meetup.com/ReactJS-Bangalore/)
8686
* [Bangalore (React Native)](https://www.meetup.com/React-Native-Bangalore-Meetup)
8787
* [Chennai](https://www.linkedin.com/company/chennaireact)
@@ -169,6 +169,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet
169169
* [Cleveland, OH - ReactJS](https://www.meetup.com/Cleveland-React/)
170170
* [Columbus, OH - ReactJS](https://www.meetup.com/ReactJS-Columbus-meetup/)
171171
* [Dallas, TX - ReactJS](https://www.meetup.com/ReactDallas/)
172+
* [Denver, CO - React Denver](https://reactdenver.com/)
172173
* [Detroit, MI - Detroit React User Group](https://www.meetup.com/Detroit-React-User-Group/)
173174
* [Indianapolis, IN - React.Indy](https://www.meetup.com/React-Indy)
174175
* [Irvine, CA - ReactJS](https://www.meetup.com/ReactJS-OC/)

src/content/learn/build-a-react-app-from-scratch.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Rsbuild includes built-in support for React features like fast refresh, JSX, Typ
6565

6666
#### Metro for React Native {/*react-native*/}
6767

68-
If you'd you're starting from scratch with React Native you'll need to use [Metro](https://metrobundler.dev/), the JavaScript bundler for React Native. Metro supports bundling for platforms like iOS and Android, but lacks many features when compared to the tools here. We recommend starting with Vite, Parcel, or Rsbuild unless your project requires React Native support.
68+
If you're starting from scratch with React Native you'll need to use [Metro](https://metrobundler.dev/), the JavaScript bundler for React Native. Metro supports bundling for platforms like iOS and Android, but lacks many features when compared to the tools here. We recommend starting with Vite, Parcel, or Rsbuild unless your project requires React Native support.
6969

7070
</Note>
7171

@@ -83,7 +83,7 @@ Routers are a core part of modern applications, and are usually integrated with
8383

8484
We suggest using:
8585

86-
- [React Router](https://reactrouter.com/start/framework/custom)
86+
- [React Router](https://reactrouter.com/start/data/custom)
8787
- [Tanstack Router](https://tanstack.com/router/latest)
8888

8989

src/content/learn/reusing-logic-with-custom-hooks.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,11 @@ export function useOnlineStatus() {
13321332
13331333
위의 예시에서 `useOnlineStatus`는 한 쌍의 [`useState`](/reference/react/useState)와 [`useEffect`](/reference/react/useEffect)와 함께 실행됩니다. 하지만 이건 가장 좋은 해결 방법은 아닙니다. 이 해결 방법이 고려하지 못한 수많은 예외 상황이 존재합니다. 예를 들어, 이건 컴포넌트가 마운트됐을 때, `isOnline`이 이미 `true`라고 가정합니다. 하지만 이것은 네트워크가 이미 꺼졌을 때 틀린 가정이 됩니다. 이런 상황을 확인하기 위해 브라우저 [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) API를 사용할 수도 있습니다. 하지만 이걸 직접적으로 사용하게 되면 초기 HTML을 생성하기 위한 서버에선 동작하지 않습니다. 짧게 말하면 코드는 보완되어야 합니다.
13341334
1335+
<<<<<<< HEAD
13351336
운 좋게도 React 18은 이런 모든 문제를 신경 써주는 [`useSyncExternalStore`](/reference/react/useSyncExternalStore)라고 불리는 섬세한 API를 포함합니다. 여기 새 API의 장점을 가지고 다시 쓰인 `useOnlineStatus`이 있습니다.
1337+
=======
1338+
React includes a dedicated API called [`useSyncExternalStore`](/reference/react/useSyncExternalStore) which takes care of all of these problems for you. Here is your `useOnlineStatus` Hook, rewritten to take advantage of this new API:
1339+
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4
13361340
13371341
<Sandpack>
13381342

src/content/learn/tutorial-tic-tac-toe.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2254,7 +2254,11 @@ body {
22542254
22552255
</Sandpack>
22562256
2257+
<<<<<<< HEAD
22572258
`map`으로 `history` 배열을 반복할 때 전달한 함수 내에서 `squares` 인수는 `history`의 각 엘리먼트를 통과하고, `move` 인수는 각 배열 인덱스를 통과합니다: `0`, `1`, `2`, … (대부분은 실제 배열 엘리먼트가 필요하지만, 이 경우에는 이동 목록을 렌더링하기 위해 인덱스만 있어도 됩니다.)
2259+
=======
2260+
As you iterate through the `history` array inside the function you passed to `map`, the `squares` argument goes through each element of `history`, and the `move` argument goes through each array index: `0`, `1`, `2`, …. (In most cases, you'd need the actual array elements, but to render a list of moves you will only need indexes.)
2261+
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4
22582262
22592263
틱택토 게임 history의 각 이동에 대해 버튼 `<button>`이 포함된 목록 항목 `<li>`를 생성하세요. 버튼에는 (아직 구현하지 않은) `jumpTo`라는 함수를 호출하는 `onClick` 핸들러가 있습니다.
22602264

src/content/reference/react/Component.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,7 +1273,7 @@ button { margin-left: 10px; }
12731273
12741274
error boundary 컴포넌트를 구현하려면 오류에 대한 응답으로 state를 업데이트하고 사용자에게 오류 메시지를 표시할 수 있는 [`static getDerivedStateFromError`](#static-getderivedstatefromerror)를 제공해야 합니다. 또한 선택적으로 [`componentDidCatch`](#componentdidcatch)를 구현하여 분석 서비스에 오류를 기록하는 등의 추가 로직을 추가할 수도 있습니다.
12751275
1276-
<CanaryBadge /> With [`captureOwnerStack`](/reference/react/captureOwnerStack) you can include the Owner Stack during development.
1276+
With [`captureOwnerStack`](/reference/react/captureOwnerStack) you can include the Owner Stack during development.
12771277
12781278
```js {9-12,14-27}
12791279
import * as React from 'react';
@@ -1298,8 +1298,7 @@ class ErrorBoundary extends React.Component {
12981298
// in div (created by App)
12991299
// in App
13001300
info.componentStack,
1301-
// Only available in react@canary.
1302-
// Warning: Owner Stack is not available in production.
1301+
// Warning: `captureOwnerStack` is not available in production.
13031302
React.captureOwnerStack(),
13041303
);
13051304
}

src/content/reference/react/StrictMode.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,17 @@ Strict Mode 검사는 **개발 환경에서만 실행되지만**, 이미 코드
8787

8888
Strict Mode에서는 개발 시 다음과 같은 검사를 가능하게 합니다.
8989

90+
<<<<<<< HEAD
9091
- 컴포넌트가 순수하지 않은 렌더링으로 인한 버그를 찾기 위해 [추가로 다시 렌더링합니다.](#fixing-bugs-found-by-double-rendering-in-development)
9192
- 컴포넌트가 Effect 클린업이 누락되어 발생한 버그를 찾기 위해 [Effect를 다시 실행합니다.](#fixing-bugs-found-by-re-running-effects-in-development)
9293
- Your components will [re-run ref callbacks an extra time](#fixing-bugs-found-by-cleaning-up-and-re-attaching-dom-refs-in-development) to find bugs caused by missing ref cleanup.
9394
- 컴포넌트가 [더 이상 사용되지 않는 API를 사용하는지 확인합니다.](#fixing-deprecation-warnings-enabled-by-strict-mode)
95+
=======
96+
- Your components will [re-render an extra time](#fixing-bugs-found-by-double-rendering-in-development) to find bugs caused by impure rendering.
97+
- Your components will [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) to find bugs caused by missing Effect cleanup.
98+
- Your components will [re-run ref callbacks an extra time](#fixing-bugs-found-by-re-running-ref-callbacks-in-development) to find bugs caused by missing ref cleanup.
99+
- Your components will [be checked for usage of deprecated APIs.](#fixing-deprecation-warnings-enabled-by-strict-mode)
100+
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4
94101
95102

96103
**이러한 모든 검사는 개발 환경 전용이며 프로덕션 빌드에는 영향을 미치지 않습니다.**
@@ -124,6 +131,12 @@ function App() {
124131

125132
이 예시에서 `Header``Footer` 컴포넌트에서는 Strict Mode 검사가 실행되지 않습니다. 그러나 `Sidebar``Content`, 그리고 그 자손 컴포넌트는 깊이에 상관없이 검사가 실행됩니다.
126133

134+
<Note>
135+
136+
When `StrictMode` is enabled for a part of the app, React will only enable behaviors that are possible in production. For example, if `<StrictMode>` is not enabled at the root of the app, it will not [re-run Effects an extra time](#fixing-bugs-found-by-re-running-effects-in-development) on initial mount, since this would cause child effects to double fire without the parent effects, which cannot happen in production.
137+
138+
</Note>
139+
127140
---
128141

129142
### 개발 중 이중 렌더링으로 발견한 버그 수정 {/*fixing-bugs-found-by-double-rendering-in-development*/}

src/content/reference/react/captureOwnerStack.md

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
title: captureOwnerStack
33
---
44

5-
<Canary>
6-
7-
The `captureOwnerStack` API is currently only available in React's Canary and experimental channels. Learn more about [React's release channels here](/community/versioning-policy#all-release-channels).
8-
9-
</Canary>
10-
115
<Intro>
126

137
`captureOwnerStack` reads the current Owner Stack in development and returns it as a string if available.
@@ -126,22 +120,6 @@ createRoot(document.createElement('div'), {
126120
);
127121
```
128122

129-
```json package.json hidden
130-
{
131-
"dependencies": {
132-
"react": "canary",
133-
"react-dom": "canary",
134-
"react-scripts": "latest"
135-
},
136-
"scripts": {
137-
"start": "react-scripts start",
138-
"build": "react-scripts build",
139-
"test": "react-scripts test --env=jsdom",
140-
"eject": "react-scripts eject"
141-
}
142-
}
143-
```
144-
145123
```html public/index.html hidden
146124
<!DOCTYPE html>
147125
<html lang="en">
@@ -357,22 +335,6 @@ const container = document.getElementById("root");
357335
createRoot(container).render(<App />);
358336
```
359337

360-
```json package.json hidden
361-
{
362-
"dependencies": {
363-
"react": "canary",
364-
"react-dom": "canary",
365-
"react-scripts": "latest"
366-
},
367-
"scripts": {
368-
"start": "react-scripts start",
369-
"build": "react-scripts build",
370-
"test": "react-scripts test --env=jsdom",
371-
"eject": "react-scripts eject"
372-
}
373-
}
374-
```
375-
376338
```js src/App.js
377339
function Component() {
378340
return <button onClick={() => console.error('Some console error')}>Trigger console.error()</button>;
@@ -417,22 +379,6 @@ export default function App() {
417379
}
418380
```
419381

420-
```json package.json hidden
421-
{
422-
"dependencies": {
423-
"react": "canary",
424-
"react-dom": "canary",
425-
"react-scripts": "latest"
426-
},
427-
"scripts": {
428-
"start": "react-scripts start",
429-
"build": "react-scripts build",
430-
"test": "react-scripts test --env=jsdom",
431-
"eject": "react-scripts eject"
432-
}
433-
}
434-
```
435-
436382
</Sandpack>
437383

438384
### `captureOwnerStack` is not available {/*captureownerstack-is-not-available*/}

src/content/reference/react/useSyncExternalStore.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,43 +404,60 @@ store 데이터가 변경 가능한 경우 `getSnapshot` 함수는 해당 데이
404404
405405
subscribe 함수는 컴포넌트 내부에 정의되므로 리렌더링할 때마다 달라집니다.
406406
407-
```js {4-7}
407+
```js {2-5}
408408
function ChatIndicator() {
409+
<<<<<<< HEAD
409410
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
410411

411412
// 🚩항상 다른 함수를 사용하므로 React는 렌더링할 때마다 다시 구독합니다.
413+
=======
414+
// 🚩 Always a different function, so React will resubscribe on every re-render
415+
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4
412416
function subscribe() {
413417
// ...
414418
}
419+
420+
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
415421

416422
// ...
417423
}
418424
```
419425
420426
리렌더링 사이에 다른 `subscribe` 함수를 전달하면 React가 store를 다시 구독합니다. 이로 인해 성능 문제가 발생하고 store 재구독을 피하고 싶다면 `subscribe` 함수를 외부로 이동하세요.
421427
422-
```js {6-9}
423-
function ChatIndicator() {
424-
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
428+
```js {1-4}
429+
// ✅ Always the same function, so React won't need to resubscribe
430+
function subscribe() {
425431
// ...
426432
}
427433

434+
<<<<<<< HEAD
428435
// ✅ 항상 동일한 함수이므로 React는 다시 구독할 필요가 없습니다.
429436
function subscribe() {
437+
=======
438+
function ChatIndicator() {
439+
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
440+
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4
430441
// ...
431442
}
432443
```
433444
434445
또는 일부 인수가 변경될 때만 다시 구독하도록 `subscribe`을 [`useCallback`](/reference/react/useCallback)으로 래핑합니다.
435446
436-
```js {4-8}
447+
```js {2-5}
437448
function ChatIndicator({ userId }) {
449+
<<<<<<< HEAD
438450
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
439451

440452
// ✅ userId가 변경되지 않는 한 동일한 함수입니다.
453+
=======
454+
// ✅ Same function as long as userId doesn't change
455+
>>>>>>> 5138e605225b24d25701a1a1f68daa90499122a4
441456
const subscribe = useCallback(() => {
442457
// ...
443458
}, [userId]);
459+
460+
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
444461

445462
// ...
446463
}

0 commit comments

Comments
 (0)