Skip to content

Commit fd33a64

Browse files
authored
Sync with react.dev @ ab18d2f (#1158)
This PR was automatically generated. Merge changes from [react.dev](https://github.com/reactjs/react.dev/commits/main) at ab18d2f The following files have conflicts and may need new translations: * [ ] [.github/workflows/discord_notify.yml](/reactjs/react.dev/commits/main/.github/workflows/discord_notify.yml) * [ ] [package.json](/reactjs/react.dev/commits/main/package.json) * [ ] [src/content/blog/2020/12/21/data-fetching-with-react-server-components.md](/reactjs/react.dev/commits/main/src/content/blog/2020/12/21/data-fetching-with-react-server-components.md) * [ ] [src/content/blog/2021/06/08/the-plan-for-react-18.md](/reactjs/react.dev/commits/main/src/content/blog/2021/06/08/the-plan-for-react-18.md) * [ ] [src/content/blog/2021/12/17/react-conf-2021-recap.md](/reactjs/react.dev/commits/main/src/content/blog/2021/12/17/react-conf-2021-recap.md) * [ ] [src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md](/reactjs/react.dev/commits/main/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md) * [ ] [src/content/blog/2023/03/16/introducing-react-dev.md](/reactjs/react.dev/commits/main/src/content/blog/2023/03/16/introducing-react-dev.md) * [ ] [src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md](/reactjs/react.dev/commits/main/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md) * [ ] [src/content/blog/2023/05/03/react-canaries.md](/reactjs/react.dev/commits/main/src/content/blog/2023/05/03/react-canaries.md) * [ ] [src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md](/reactjs/react.dev/commits/main/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md) * [ ] [src/content/blog/2024/04/25/react-19-upgrade-guide.md](/reactjs/react.dev/commits/main/src/content/blog/2024/04/25/react-19-upgrade-guide.md) * [ ] [src/content/blog/index.md](/reactjs/react.dev/commits/main/src/content/blog/index.md) * [ ] [src/content/community/conferences.md](/reactjs/react.dev/commits/main/src/content/community/conferences.md) * [ ] [src/content/community/docs-contributors.md](/reactjs/react.dev/commits/main/src/content/community/docs-contributors.md) * [ ] [src/content/community/team.md](/reactjs/react.dev/commits/main/src/content/community/team.md) * [ ] [src/content/community/versioning-policy.md](/reactjs/react.dev/commits/main/src/content/community/versioning-policy.md) * [ ] [src/content/learn/add-react-to-an-existing-project.md](/reactjs/react.dev/commits/main/src/content/learn/add-react-to-an-existing-project.md) * [ ] [src/content/learn/installation.md](/reactjs/react.dev/commits/main/src/content/learn/installation.md) * [ ] [src/content/learn/manipulating-the-dom-with-refs.md](/reactjs/react.dev/commits/main/src/content/learn/manipulating-the-dom-with-refs.md) * [ ] [src/content/learn/passing-data-deeply-with-context.md](/reactjs/react.dev/commits/main/src/content/learn/passing-data-deeply-with-context.md) * [ ] [src/content/learn/render-and-commit.md](/reactjs/react.dev/commits/main/src/content/learn/render-and-commit.md) * [ ] [src/content/learn/start-a-new-react-project.md](/reactjs/react.dev/commits/main/src/content/learn/start-a-new-react-project.md) * [ ] [src/content/learn/state-a-components-memory.md](/reactjs/react.dev/commits/main/src/content/learn/state-a-components-memory.md) * [ ] [src/content/learn/tutorial-tic-tac-toe.md](/reactjs/react.dev/commits/main/src/content/learn/tutorial-tic-tac-toe.md) * [ ] [src/content/reference/react-dom/client/createRoot.md](/reactjs/react.dev/commits/main/src/content/reference/react-dom/client/createRoot.md) * [ ] [src/content/reference/react-dom/client/hydrateRoot.md](/reactjs/react.dev/commits/main/src/content/reference/react-dom/client/hydrateRoot.md) * [ ] [src/content/reference/react-dom/components/input.md](/reactjs/react.dev/commits/main/src/content/reference/react-dom/components/input.md) * [ ] [src/content/reference/react-dom/components/style.md](/reactjs/react.dev/commits/main/src/content/reference/react-dom/components/style.md) * [ ] [src/content/reference/react-dom/static/prerender.md](/reactjs/react.dev/commits/main/src/content/reference/react-dom/static/prerender.md) * [ ] [src/content/reference/react/useActionState.md](/reactjs/react.dev/commits/main/src/content/reference/react/useActionState.md) * [ ] [src/content/reference/react/useDeferredValue.md](/reactjs/react.dev/commits/main/src/content/reference/react/useDeferredValue.md) * [ ] [src/content/reference/react/useImperativeHandle.md](/reactjs/react.dev/commits/main/src/content/reference/react/useImperativeHandle.md) * [ ] [src/content/reference/rsc/server-components.md](/reactjs/react.dev/commits/main/src/content/reference/rsc/server-components.md) * [ ] [src/sidebarLearn.json](/reactjs/react.dev/commits/main/src/sidebarLearn.json) * [ ] [yarn.lock](/reactjs/react.dev/commits/main/yarn.lock) Please fix the conflicts by pushing new commits to this pull request, either by editing the files directly on GitHub or by checking out this branch. ## DO NOT SQUASH MERGE THIS PULL REQUEST! Doing so will "erase" the commits from main and cause them to show up as conflicts the next time we merge.
2 parents 0891507 + e00dc3f commit fd33a64

38 files changed

+1842
-1733
lines changed

.editorconfig

-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,3 @@ charset = utf-8
55
end_of_line = lf
66
insert_final_newline = true
77
indent_style = space
8-
trim_trailing_whitespace = true

src/components/MDX/CodeBlock/CodeBlock.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ function getInlineDecorators(
336336
line.step === 3,
337337
'bg-green-40 border-green-40 text-green-60 dark:text-green-30':
338338
line.step === 4,
339+
// TODO: Some codeblocks use up to 6 steps.
339340
}
340341
),
341342
})

src/content/blog/2024/04/25/react-19-upgrade-guide.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ To help make the upgrade to React 19 easier, we've published a `[email protected]` rele
2424

2525
We recommend upgrading to React 18.3 first to help identify any issues before upgrading to React 19.
2626

27-
For a list of changes in 18.3 see the [Release Notes](https://github.com/facebook/react/blob/main/CHANGELOG.md).
27+
For a list of changes in 18.3 see the [Release Notes](https://github.com/facebook/react/blob/main/CHANGELOG.md#1830-april-25-2024).
2828

2929
</Note>
3030

@@ -113,7 +113,7 @@ This will run the following codemods from `react-codemod`:
113113
- [`replace-string-ref`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-string-ref)
114114
- [`replace-act-import`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-act-import)
115115
- [`replace-use-form-state`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-use-form-state)
116-
- [`prop-types-typescript`](https://codemod.com/registry/react-prop-types-typescript)
116+
- [`prop-types-typescript`](https://github.com/reactjs/react-codemod#react-proptypes-to-prop-types)
117117

118118
This does not include the TypeScript changes. See [TypeScript changes](#typescript-changes) below.
119119

src/content/blog/2024/12/05/react-19.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ A component was suspended by an uncached promise. Creating promises inside a Cli
294294

295295
</ConsoleBlockMulti>
296296

297-
To fix, you need to pass a promise from a suspense powered library or framework that supports caching for promises. In the future we plan to ship features to make it easier to cache promises in render.
297+
To fix, you need to pass a promise from a Suspense powered library or framework that supports caching for promises. In the future we plan to ship features to make it easier to cache promises in render.
298298

299299
</Note>
300300

src/content/blog/2025/02/14/sunsetting-create-react-app.md

+320
Large diffs are not rendered by default.

src/content/blog/index.md

+6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ title: React 블로그
1010

1111
<div className="sm:-mx-5 flex flex-col gap-5 mt-12">
1212

13+
<BlogCard title="Sunsetting Create React App" date="February 13, 2025" url="/blog/2025/02/14/sunsetting-create-react-app">
14+
15+
Today, we’re deprecating Create React App for new apps, and encouraging existing apps to migrate to a framework, or to migrate to a build tool like Vite, Parcel, or RSBuild. We’re also providing docs for when a framework isn’t a good fit for your project, you want to build your own framework, or you just want to learn how React works by building a React app from scratch ...
16+
17+
</BlogCard>
18+
1319
<BlogCard title="React v19 " date="December 5, 2024" url="/blog/2024/12/05/react-19">
1420

1521
In the React 19 Upgrade Guide, we shared step-by-step instructions for upgrading your app to React 19. In this post, we'll give an overview of the new features in React 19, and how you can adopt them ...

src/content/community/conferences.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ April 3 (Reanimated Training) + April 4 (Conference), 2025. Paris, France.
2121
[Website](https://reactnativeconnection.io/) - [X](https://x.com/reactnativeconn) - [Bluesky](https://bsky.app/profile/reactnativeconnect.bsky.social)
2222

2323
### CityJS London 2025 {/*cityjs-london*/}
24+
2425
April 23 - 25, 2025. In-person in London, UK
2526

2627
[Website](https://london.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social)

src/content/community/versioning-policy.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ React의 모든 안정적인 빌드는 높은 수준의 테스트를 거치고
77

88
</Intro>
99

10-
지난 버전을 확인하려면, [React 버전](/versions) 페이지를 참고해주세요.
10+
This versioning policy describes our approach to version numbers for packages such as `react` and `react-dom`. 지난 버전을 확인하려면, [React 버전](/versions) 페이지를 참고해주세요.
1111

1212
## Stable releases {/*stable-releases*/}
1313

@@ -23,7 +23,9 @@ Stable React releases (also known as “Latest” release channel) follow [seman
2323

2424
마이너 릴리즈는 릴리즈의 가장 흔한 유형입니다.
2525

26-
### Breaking Changes {/*breaking-changes*/}
26+
We know our users continue to use old versions of React in production. If we learn of a security vulnerability in React, we release a backported fix for all major versions that are affected by the vulnerability.
27+
28+
### Breaking changes {/*breaking-changes*/}
2729

2830
Breaking Changes는 모두에게 불편하기에 우리는 메이저 릴리즈의 수를 최소화하려고 노력합니다. 예를 들어, React 15는 2016년 4월에 릴리즈, React 16은 2017년 9월에 릴리즈, React 17은 2020년 10월에 릴리즈되었습니다.
2931

src/content/learn/add-react-to-an-existing-project.md

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ title: 기존 프로젝트에 React 추가하기
4646

4747
* **이미 애플리케이션이 `import` 문을 이용해 파일로 분리하고 있다면** 기존에 가지고 있는 설정을 이용해 보세요. JS 코드에서 `<div />`를 작성하면 문법 오류가 발생하는지 확인해 보세요. 문법 오류가 발생한다면 [Babel을 이용한 자바스크립트 코드 변환](https://babeljs.io/setup)이 필요할 수 있으며, JSX를 사용하려면 [Babel React 프리셋](https://babeljs.io/docs/babel-preset-react)을 활성화해야 할 수도 있습니다.
4848

49+
* **If your app doesn't have an existing setup for compiling JavaScript modules,** set it up with [Vite](https://vite.dev/). The Vite community maintains [many integrations with backend frameworks](https://github.com/vitejs/awesome-vite#integrations-with-backends), including Rails, Django, and Laravel. If your backend framework is not listed, [follow this guide](https://vite.dev/guide/backend-integration.html) to manually integrate Vite builds with your backend.
50+
4951
* **애플리케이션이 자바스크립트 모듈을 컴파일하기 위한 기존 설정이 없다면,** [Vite](https://vitejs.dev/)를 이용하여 설정하세요. Vite 커뮤니티는 Rails, Django, Laravel을 포함한 [다양한 백엔드 프레임워크와의 통합](https://github.com/vitejs/awesome-vite#integrations-with-backends)을 지원하고 있습니다. 사용 중인 백엔드 프레임워크가 목록에 없다면 [가이드를 참고하여](https://vitejs.dev/guide/backend-integration.html) Vite 빌드를 백엔드와 수동으로 통합하세요.
5052

5153
설정이 제대로 동작하는지 확인하려면 프로젝트 폴더에서 아래 명령어를 실행하세요.
@@ -88,6 +90,8 @@ root.render(<h1>Hello, world</h1>);
8890

8991
처음으로 기존 프로젝트에 모듈 자바스크립트 환경을 통합하기는 다소 어려워 보일 수 있으나, 그만한 가치가 있는 일입니다! 어려움을 겪는 부분이 있다면 [커뮤니티 리소스](/community)[Vite 채팅](https://chat.vitejs.dev/)을 이용해 보세요.
9092

93+
Integrating a modular JavaScript environment into an existing project for the first time can feel intimidating, but it's worth it! If you get stuck, try our [community resources](/community) or the [Vite Chat](https://chat.vite.dev/).
94+
9195
</Note>
9296

9397

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
---
2+
title: Build a React app from Scratch
3+
---
4+
5+
<Intro>
6+
7+
If your app has constraints not well-served by existing frameworks, you prefer to build your own framework, or you just want to learn the basics of a React app, you can build a React app from scratch.
8+
9+
</Intro>
10+
11+
<DeepDive>
12+
13+
#### Consider using a framework {/*consider-using-a-framework*/}
14+
15+
Starting from scratch is an easy way to get started using React, but a major tradeoff to be aware of is that going this route is often the same as building your own adhoc framework. As your requirements evolve, you may need to solve more framework-like problems that our recommended frameworks already have well developed and supported solutions for.
16+
17+
For example, if in the future your app needs support for server-side rendering (SSR), static site generation (SSG), and/or React Server Components (RSC), you will have to implement those on your own. Similarly, future React features that require integrating at the framework level will have to be implemented on your own if you want to use them.
18+
19+
Our recommended frameworks also help you build better performing apps. For example, reducing or eliminating waterfalls from network requests makes for a better user experience. This might not be a high priority when you are building a toy project, but if your app gains users you may want to improve its performance.
20+
21+
Going this route also makes it more difficult to get support, since the way you develop routing, data-fetching, and other features will be unique to your situation. You should only choose this option if you are comfortable tackling these problems on your own, or if you’re confident that you will never need these features.
22+
23+
For a list of recommended frameworks, check out [Creating a React App](/learn/creating-a-react-app).
24+
25+
</DeepDive>
26+
27+
28+
## Step 1: Install a build tool {/*step-1-install-a-build-tool*/}
29+
30+
The first step is to install a build tool like `vite`, `parcel`, or `rsbuild`. These build tools provide features to package and run source code, provide a development server for local development and a build command to deploy your app to a production server.
31+
32+
### Vite {/*vite*/}
33+
34+
[Vite](https://vite.dev/) is a build tool that aims to provide a faster and leaner development experience for modern web projects.
35+
36+
<TerminalBlock>
37+
{`npm create vite@latest my-app -- --template react`}
38+
</TerminalBlock>
39+
40+
Vite is opinionated and comes with sensible defaults out of the box. Vite has a rich ecosystem of plugins to support fast refresh, JSX, Babel/SWC, and other common features. See Vite's [React plugin](https://vite.dev/plugins/#vitejs-plugin-react) or [React SWC plugin](https://vite.dev/plugins/#vitejs-plugin-react-swc) and [React SSR example project](https://vite.dev/guide/ssr.html#example-projects) to get started.
41+
42+
Vite is already being used as a build tool in one of our [recommended frameworks](/learn/creating-a-react-app): [React Router](https://reactrouter.com/start/framework/installation).
43+
44+
### Parcel {/*parcel*/}
45+
46+
[Parcel](https://parceljs.org/) combines a great out-of-the-box development experience with a scalable architecture that can take your project from just getting started to massive production applications.
47+
48+
<TerminalBlock>
49+
{`npm install --save-dev parcel`}
50+
</TerminalBlock>
51+
52+
Parcel supports fast refresh, JSX, TypeScript, Flow, and styling out of the box. See [Parcel's React recipe](https://parceljs.org/recipes/react/#getting-started) to get started.
53+
54+
### Rsbuild {/*rsbuild*/}
55+
56+
[Rsbuild](https://rsbuild.dev/) is an Rspack-powered build tool that provides a seamless development experience for React applications. It comes with carefully tuned defaults and performance optimizations ready to use.
57+
58+
<TerminalBlock>
59+
{`npx create-rsbuild --template react`}
60+
</TerminalBlock>
61+
62+
Rsbuild includes built-in support for React features like fast refresh, JSX, TypeScript, and styling. See [Rsbuild's React guide](https://rsbuild.dev/guide/framework/react) to get started.
63+
64+
<Note>
65+
66+
#### Metro for React Native {/*react-native*/}
67+
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.
69+
70+
</Note>
71+
72+
## Step 2: Build Common Application Patterns {/*step-2-build-common-application-patterns*/}
73+
74+
The build tools listed above start off with a client-only, single-page app (SPA), but don't include any further solutions for common functionality like routing, data fetching, or styling.
75+
76+
The React ecosystem includes many tools for these problems. We've listed a few that are widely used as a starting point, but feel free to choose other tools if those work better for you.
77+
78+
### Routing {/*routing*/}
79+
80+
Routing determines what content or pages to display when a user visits a particular URL. You need to set up a router to map URLs to different parts of your app. You'll also need to handle nested routes, route parameters, and query parameters. Routers can be configured within your code, or defined based on your component folder and file structures.
81+
82+
Routers are a core part of modern applications, and are usually integrated with data fetching (including prefetching data for a whole page for faster loading), code splitting (to minimize client bundle sizes), and page rendering approaches (to decide how each page gets generated).
83+
84+
We suggest using:
85+
86+
- [React Router](https://reactrouter.com/start/framework/custom)
87+
- [Tanstack Router](https://tanstack.com/router/latest)
88+
89+
90+
### Data Fetching {/*data-fetching*/}
91+
92+
Fetching data from a server or other data source is a key part of most applications. Doing this properly requires handling loading states, error states, and caching the fetched data, which can be complex.
93+
94+
Purpose-built data fetching libraries do the hard work of fetching and caching the data for you, letting you focus on what data your app needs and how to display it. These libraries are typically used directly in your components, but can also be integrated into routing loaders for faster pre-fetching and better performance, and in server rendering as well.
95+
96+
Note that fetching data directly in components can lead to slower loading times due to network request waterfalls, so we recommend prefetching data in router loaders or on the server as much as possible! This allows a page's data to be fetched all at once as the page is being displayed.
97+
98+
If you're fetching data from most backends or REST-style APIs, we suggest using:
99+
100+
- [React Query](https://react-query.tanstack.com/)
101+
- [SWR](https://swr.vercel.app/)
102+
- [RTK Query](https://redux-toolkit.js.org/rtk-query/overview)
103+
104+
If you're fetching data from a GraphQL API, we suggest using:
105+
106+
- [Apollo](https://www.apollographql.com/docs/react)
107+
- [Relay](https://relay.dev/)
108+
109+
110+
### Code-splitting {/*code-splitting*/}
111+
112+
Code-splitting is the process of breaking your app into smaller bundles that can be loaded on demand. An app's code size increases with every new feature and additional dependency. Apps can become slow to load because all of the code for the entire app needs to be sent before it can be used. Caching, reducing features/dependencies, and moving some code to run on the server can help mitigate slow loading but are incomplete solutions that can sacrifice functionality if overused.
113+
114+
Similarly, if you rely on the apps using your framework to split the code, you might encounter situations where loading becomes slower than if no code splitting were happening at all. For example, [lazily loading](/reference/react/lazy) a chart delays sending the code needed to render the chart, splitting the chart code from the rest of the app. [Parcel supports code splitting with React.lazy](https://parceljs.org/recipes/react/#code-splitting). However, if the chart loads its data *after* it has been initially rendered you are now waiting twice. This is a waterfall: rather than fetching the data for the chart and sending the code to render it simultaneously, you must wait for each step to complete one after the other.
115+
116+
Splitting code by route, when integrated with bundling and data fetching, can reduce the initial load time of your app and the time it takes for the largest visible content of the app to render ([Largest Contentful Paint](https://web.dev/articles/lcp)).
117+
118+
For code-splitting instructions, see your build tool docs:
119+
- [Vite build optimizations](https://v3.vitejs.dev/guide/features.html#build-optimizations)
120+
- [Parcel code splitting](https://parceljs.org/features/code-splitting/)
121+
- [Rsbuild code splitting](https://rsbuild.dev/guide/optimization/code-splitting)
122+
123+
### Improving Application Performance {/*improving-application-performance*/}
124+
125+
Since the build tool you select only support single page apps (SPAs) you'll need to implement other [rendering patterns](https://www.patterns.dev/vanilla/rendering-patterns) like server-side rendering (SSR), static site generation (SSG), and/or React Server Components (RSC). Even if you don't need these features at first, in the future there may be some routes that would benefit SSR, SSG or RSC.
126+
127+
* **Single-page apps (SPA)** load a single HTML page and dynamically updates the page as the user interacts with the app. SPAs are easier to get started with, but they can have slower initial load times. SPAs are the default architecture for most build tools.
128+
129+
* **Streaming Server-side rendering (SSR)** renders a page on the server and sends the fully rendered page to the client. SSR can improve performance, but it can be more complex to set up and maintain than a single-page app. With the addition of streaming, SSR can be very complex to set up and maintain. See [Vite's SSR guide]( https://vite.dev/guide/ssr).
130+
131+
* **Static site generation (SSG)** generates static HTML files for your app at build time. SSG can improve performance, but it can be more complex to set up and maintain than server-side rendering. See [Vite's SSG guide](https://vite.dev/guide/ssr.html#pre-rendering-ssg).
132+
133+
* **React Server Components (RSC)** lets you mix build-time, server-only, and interactive components in a single React tree. RSC can improve performance, but it currently requires deep expertise to set up and maintain. See [Parcel's RSC examples](https://github.com/parcel-bundler/rsc-examples).
134+
135+
Your rendering strategies need to integrate with your router so apps built with your framework can choose the rendering strategy on a per-route level. This will enable different rendering strategies without having to rewrite your whole app. For example, the landing page for your app might benefit from being statically generated (SSG), while a page with a content feed might perform best with server-side rendering.
136+
137+
Using the right rendering strategy for the right routes can decrease the time it takes for the first byte of content to be loaded ([Time to First Byte](https://web.dev/articles/ttfb)), the first piece of content to render ([First Contentful Paint](https://web.dev/articles/fcp)), and the largest visible content of the app to render ([Largest Contentful Paint](https://web.dev/articles/lcp)).
138+
139+
### And more... {/*and-more*/}
140+
141+
These are just a few examples of the features a new app will need to consider when building from scratch. Many limitations you'll hit can be difficult to solve as each problem is interconnected with the others and can require deep expertise in problem areas you may not be familiar with.
142+
143+
If you don't want to solve these problems on your own, you can [get started with a framework](/learn/creating-a-react-app) that provides these features out of the box.

0 commit comments

Comments
 (0)