From bb38630bc9c4aed40b72eaa171caf7e410a9e393 Mon Sep 17 00:00:00 2001 From: lauren Date: Mon, 7 Oct 2024 19:14:43 -0400 Subject: [PATCH 001/829] Add react-compiler-runtime instructions to compiler docs (#7213) For users of React < 19, there is a new react-compiler-runtime package that can be used to provide a "polyfill" for runtime APIs needed for compiled code. This PR adds docs for that. --- src/content/learn/react-compiler.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 2920e8643..5afaa4cf5 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -20,8 +20,6 @@ These docs are still a work in progress. More documentation is available in the React Compiler is a new experimental compiler that we've open sourced to get early feedback from the community. It still has rough edges and is not yet fully ready for production. - -React Compiler requires React 19 RC. If you are unable to upgrade to React 19, you may try a userspace implementation of the cache function as described in the [Working Group](https://github.com/reactwg/react-compiler/discussions/6). However, please note that this is not recommended and you should upgrade to React 19 when possible. React Compiler is a new experimental compiler that we've open sourced to get early feedback from the community. It is a build-time only tool that automatically optimizes your React app. It works with plain JavaScript, and understands the [Rules of React](/reference/rules), so you don't need to rewrite any code to use it. @@ -226,6 +224,29 @@ module.exports = function () { `babel-plugin-react-compiler` should run first before other Babel plugins as the compiler requires the input source information for sound analysis. +React Compiler works best with React 19 RC. If you are unable to upgrade, you can install the extra `react-compiler-runtime` package which will allow the compiled code to run on versions prior to 19. However, note that the minimum supported version is 17. + + +npm install react-compiler-runtime@experimental + + +You should also add the correct `target` to your compiler config, where `target` is the major version of React you are targeting: + +```js {3} +// babel.config.js +const ReactCompilerConfig = { + target: '18' // '17' | '18' | '19' +}; + +module.exports = function () { + return { + plugins: [ + ['babel-plugin-react-compiler', ReactCompilerConfig], + ], + }; +}; +``` + ### Vite {/*usage-with-vite*/} If you use Vite, you can add the plugin to vite-plugin-react: From 2b2d0f2309f49c82cf5bb88ea62fb2e44661c634 Mon Sep 17 00:00:00 2001 From: Jake Saterlay <41985955+JakeSaterlay@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:57:10 +0100 Subject: [PATCH 002/829] `useActionState` pending example (#6989) Co-authored-by: Sebastian "Sebbie" Silbermann --- src/content/reference/react/useActionState.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/content/reference/react/useActionState.md b/src/content/reference/react/useActionState.md index 6f5924e3d..52fba47e7 100644 --- a/src/content/reference/react/useActionState.md +++ b/src/content/reference/react/useActionState.md @@ -20,7 +20,7 @@ In earlier React Canary versions, this API was part of React DOM and called `use `useActionState` is a Hook that allows you to update state based on the result of a form action. ```js -const [state, formAction] = useActionState(fn, initialState, permalink?); +const [state, formAction, isPending] = useActionState(fn, initialState, permalink?); ``` @@ -35,7 +35,7 @@ const [state, formAction] = useActionState(fn, initialState, permalink?); {/* TODO T164397693: link to actions documentation once it exists */} -Call `useActionState` at the top level of your component to create component state that is updated [when a form action is invoked](/reference/react-dom/components/form). You pass `useActionState` an existing form action function as well as an initial state, and it returns a new action that you use in your form, along with the latest form state. The latest form state is also passed to the function that you provided. +Call `useActionState` at the top level of your component to create component state that is updated [when a form action is invoked](/reference/react-dom/components/form). You pass `useActionState` an existing form action function as well as an initial state, and it returns a new action that you use in your form, along with the latest form state and whether the Action is still pending. The latest form state is also passed to the function that you provided. ```js import { useActionState } from "react"; @@ -71,10 +71,11 @@ If used with a Server Action, `useActionState` allows the server's response from #### Returns {/*returns*/} -`useActionState` returns an array with exactly two values: +`useActionState` returns an array with the following values: 1. The current state. During the first render, it will match the `initialState` you have passed. After the action is invoked, it will match the value returned by the action. 2. A new action that you can pass as the `action` prop to your `form` component or `formAction` prop to any `button` component within the form. +3. The `isPending` flag that tells you whether there is a pending Transition. #### Caveats {/*caveats*/} @@ -104,10 +105,11 @@ function MyComponent() { } ``` -`useActionState` returns an array with exactly two items: +`useActionState` returns an array with the following items: 1. The current state of the form, which is initially set to the initial state you provided, and after the form is submitted is set to the return value of the action you provided. 2. A new action that you pass to `
` as its `action` prop. +3. A pending state that you can utilise whilst your action is processing. When the form is submitted, the action function that you provided will be called. Its return value will become the new current state of the form. @@ -133,13 +135,13 @@ import { useActionState, useState } from "react"; import { addToCart } from "./actions.js"; function AddToCartForm({itemID, itemTitle}) { - const [message, formAction] = useActionState(addToCart, null); + const [message, formAction, isPending] = useActionState(addToCart, null); return (

{itemTitle}

- {message} + {isPending ? "Loading..." : message}
); } @@ -162,6 +164,10 @@ export async function addToCart(prevState, queryData) { if (itemID === "1") { return "Added to cart"; } else { + // Add a fake delay to make waiting noticeable. + await new Promise(resolve => { + setTimeout(resolve, 2000); + }); return "Couldn't add to cart: the item is sold out."; } } From 2bd6189d240703990a3c7452fd4124ba48e9f0d2 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Tue, 15 Oct 2024 03:56:53 +0900 Subject: [PATCH 003/829] Capitalize "Effect" (#7211) --- src/content/reference/react/useReducer.md | 2 +- src/content/reference/react/useState.md | 2 +- src/content/reference/react/useTransition.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/reference/react/useReducer.md b/src/content/reference/react/useReducer.md index cfd0fb856..ed3dc68c2 100644 --- a/src/content/reference/react/useReducer.md +++ b/src/content/reference/react/useReducer.md @@ -52,7 +52,7 @@ function MyComponent() { #### Caveats {/*caveats*/} * `useReducer` is a Hook, so you can only call it **at the top level of your component** or your own Hooks. You can't call it inside loops or conditions. If you need that, extract a new component and move the state into it. -* The `dispatch` function has a stable identity, so you will often see it omitted from effect dependencies, but including it will not cause the effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) +* The `dispatch` function has a stable identity, so you will often see it omitted from Effect dependencies, but including it will not cause the Effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) * In Strict Mode, React will **call your reducer and initializer twice** in order to [help you find accidental impurities.](#my-reducer-or-initializer-function-runs-twice) This is development-only behavior and does not affect production. If your reducer and initializer are pure (as they should be), this should not affect your logic. The result from one of the calls is ignored. --- diff --git a/src/content/reference/react/useState.md b/src/content/reference/react/useState.md index 4aa9d5911..23db1aae5 100644 --- a/src/content/reference/react/useState.md +++ b/src/content/reference/react/useState.md @@ -85,7 +85,7 @@ function handleClick() { * React [batches state updates.](/learn/queueing-a-series-of-state-updates) It updates the screen **after all the event handlers have run** and have called their `set` functions. This prevents multiple re-renders during a single event. In the rare case that you need to force React to update the screen earlier, for example to access the DOM, you can use [`flushSync`.](/reference/react-dom/flushSync) -* The `set` function has a stable identity, so you will often see it omitted from effect dependencies, but including it will not cause the effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) +* The `set` function has a stable identity, so you will often see it omitted from Effect dependencies, but including it will not cause the Effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) * Calling the `set` function *during rendering* is only allowed from within the currently rendering component. React will discard its output and immediately attempt to render it again with the new state. This pattern is rarely needed, but you can use it to **store information from the previous renders**. [See an example below.](#storing-information-from-previous-renders) diff --git a/src/content/reference/react/useTransition.md b/src/content/reference/react/useTransition.md index 5066fe637..b6dcb3c73 100644 --- a/src/content/reference/react/useTransition.md +++ b/src/content/reference/react/useTransition.md @@ -80,7 +80,7 @@ function TabContainer() { * The function you pass to `startTransition` must be synchronous. React immediately executes this function, marking all state updates that happen while it executes as Transitions. If you try to perform more state updates later (for example, in a timeout), they won't be marked as Transitions. -* The `startTransition` function has a stable identity, so you will often see it omitted from effect dependencies, but including it will not cause the effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) +* The `startTransition` function has a stable identity, so you will often see it omitted from Effect dependencies, but including it will not cause the Effect to fire. If the linter lets you omit a dependency without errors, it is safe to do. [Learn more about removing Effect dependencies.](/learn/removing-effect-dependencies#move-dynamic-objects-and-functions-inside-your-effect) * A state update marked as a Transition will be interrupted by other state updates. For example, if you update a chart component inside a Transition, but then start typing into an input while the chart is in the middle of a re-render, React will restart the rendering work on the chart component after handling the input update. From ee094926d54eef5cec54c9299842eeb822c7859b Mon Sep 17 00:00:00 2001 From: lauren Date: Thu, 17 Oct 2024 16:55:24 -0400 Subject: [PATCH 004/829] [compiler] Move React 17/18 section to its own subheading (#7230) Currently it's a little hidden, let's move it to its own subheading for more prominence --- src/content/learn/react-compiler.md | 54 +++++++++++++---------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 5afaa4cf5..08e2e5672 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -192,61 +192,63 @@ export default function App() { When you have more confidence with rolling out the compiler, you can expand coverage to other directories as well and slowly roll it out to your whole app. -#### New projects {/*new-projects*/} - -If you're starting a new project, you can enable the compiler on your entire codebase, which is the default behavior. +### Using React Compiler with React 17 or 18 {/*using-react-compiler-with-react-17-or-18*/} -## Usage {/*installation*/} - -### Babel {/*usage-with-babel*/} +React Compiler works best with React 19 RC. If you are unable to upgrade, you can install the extra `react-compiler-runtime` package which will allow the compiled code to run on versions prior to 19. However, note that the minimum supported version is 17. -npm install babel-plugin-react-compiler@experimental +npm install react-compiler-runtime@experimental -The compiler includes a Babel plugin which you can use in your build pipeline to run the compiler. - -After installing, add it to your Babel config. Please note that it's critical that the compiler run **first** in the pipeline: +You should also add the correct `target` to your compiler config, where `target` is the major version of React you are targeting: -```js {7} +```js {3} // babel.config.js -const ReactCompilerConfig = { /* ... */ }; +const ReactCompilerConfig = { + target: '18' // '17' | '18' | '19' +}; module.exports = function () { return { plugins: [ - ['babel-plugin-react-compiler', ReactCompilerConfig], // must run first! - // ... + ['babel-plugin-react-compiler', ReactCompilerConfig], ], }; }; ``` -`babel-plugin-react-compiler` should run first before other Babel plugins as the compiler requires the input source information for sound analysis. +#### New projects {/*new-projects*/} -React Compiler works best with React 19 RC. If you are unable to upgrade, you can install the extra `react-compiler-runtime` package which will allow the compiled code to run on versions prior to 19. However, note that the minimum supported version is 17. +If you're starting a new project, you can enable the compiler on your entire codebase, which is the default behavior. + +## Usage {/*installation*/} + +### Babel {/*usage-with-babel*/} -npm install react-compiler-runtime@experimental +npm install babel-plugin-react-compiler@experimental -You should also add the correct `target` to your compiler config, where `target` is the major version of React you are targeting: +The compiler includes a Babel plugin which you can use in your build pipeline to run the compiler. -```js {3} +After installing, add it to your Babel config. Please note that it's critical that the compiler run **first** in the pipeline: + +```js {7} // babel.config.js -const ReactCompilerConfig = { - target: '18' // '17' | '18' | '19' -}; +const ReactCompilerConfig = { /* ... */ }; module.exports = function () { return { plugins: [ - ['babel-plugin-react-compiler', ReactCompilerConfig], + ['babel-plugin-react-compiler', ReactCompilerConfig], // must run first! + // ... ], }; }; ``` +`babel-plugin-react-compiler` should run first before other Babel plugins as the compiler requires the input source information for sound analysis. + ### Vite {/*usage-with-vite*/} If you use Vite, you can add the plugin to vite-plugin-react: @@ -392,12 +394,6 @@ To report issues, please first create a minimal repro on the [React Compiler Pla You can also provide feedback in the React Compiler Working Group by applying to be a member. Please see [the README for more details on joining](https://github.com/reactwg/react-compiler). -### `(0 , _c) is not a function` error {/*0--_c-is-not-a-function-error*/} - -This occurs if you are not using React 19 RC and up. To fix this, [upgrade your app to React 19 RC](https://react.dev/blog/2024/04/25/react-19-upgrade-guide) first. - -If you are unable to upgrade to React 19, you may try a userspace implementation of the cache function as described in the [Working Group](https://github.com/reactwg/react-compiler/discussions/6). However, please note that this is not recommended and you should upgrade to React 19 when possible. - ### How do I know my components have been optimized? {/*how-do-i-know-my-components-have-been-optimized*/} [React Devtools](/learn/react-developer-tools) (v5.0+) has built-in support for React Compiler and will display a "Memo ✨" badge next to components that have been optimized by the compiler. From 9467bc58868e66c53ca9385c8531dcf7b02178c2 Mon Sep 17 00:00:00 2001 From: lauren Date: Fri, 18 Oct 2024 00:12:01 -0400 Subject: [PATCH 005/829] [compiler] Add docs for Beta (#7231) Updates our compiler docs for the latest Beta release. --- src/content/learn/react-compiler.md | 146 +++++++++------------------- 1 file changed, 48 insertions(+), 98 deletions(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 08e2e5672..4fc974fa9 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -3,7 +3,7 @@ title: React Compiler --- -This page will give you an introduction to the new experimental React Compiler and how to try it out successfully. +This page will give you an introduction to React Compiler and how to try it out successfully. @@ -19,12 +19,28 @@ These docs are still a work in progress. More documentation is available in the -React Compiler is a new experimental compiler that we've open sourced to get early feedback from the community. It still has rough edges and is not yet fully ready for production. +React Compiler is a new compiler currently in Beta, that we've open sourced to get early feedback from the community. While it has been used in production at companies like Meta, rolling out the compiler to production for your app will depend on the health of your codebase and how well you’ve followed the [Rules of React](/reference/rules). + +The latest Beta release can be found with the `@beta` tag, and daily experimental releases with `@experimental`. -React Compiler is a new experimental compiler that we've open sourced to get early feedback from the community. It is a build-time only tool that automatically optimizes your React app. It works with plain JavaScript, and understands the [Rules of React](/reference/rules), so you don't need to rewrite any code to use it. +React Compiler is a new compiler that we've open sourced to get early feedback from the community. It is a build-time only tool that automatically optimizes your React app. It works with plain JavaScript, and understands the [Rules of React](/reference/rules), so you don't need to rewrite any code to use it. + +The compiler also includes an [eslint plugin](#installing-eslint-plugin-react-compiler) that surfaces the analysis from the compiler right in your editor. **We strongly recommend everyone use the linter today.** The linter does not require that you have the compiler installed, so you can use it even if you are not ready to try out the compiler. + +The compiler is currently released as `beta`, and is available to try out on React 17+ apps and libraries. To install the Beta: -The compiler also includes an [eslint plugin](#installing-eslint-plugin-react-compiler) that surfaces the analysis from the compiler right in your editor. The plugin runs independently of the compiler and can be used even if you aren't using the compiler in your app. We recommend all React developers to use this eslint plugin to help improve the quality of your codebase. + +npm install -D babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta + + +Or, if you're using Yarn: + + +yarn add -D babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta + + +If you are not using React 19 yet, please see [the section below](#using-react-compiler-with-react-17-or-18) for further instructions. ### What does the compiler do? {/*what-does-the-compiler-do*/} @@ -94,19 +110,9 @@ However, if `expensivelyProcessAReallyLargeArrayOfObjects` is truly an expensive So if `expensivelyProcessAReallyLargeArrayOfObjects` was used in many different components, even if the same exact items were passed down, that expensive calculation would be run repeatedly. We recommend [profiling](https://react.dev/reference/react/useMemo#how-to-tell-if-a-calculation-is-expensive) first to see if it really is that expensive before making code more complicated. -### What does the compiler assume? {/*what-does-the-compiler-assume*/} - -React Compiler assumes that your code: - -1. Is valid, semantic JavaScript -2. Tests that nullable/optional values and properties are defined before accessing them (for example, by enabling [`strictNullChecks`](https://www.typescriptlang.org/tsconfig/#strictNullChecks) if using TypeScript), i.e., `if (object.nullableProperty) { object.nullableProperty.foo }` or with optional-chaining `object.nullableProperty?.foo` -3. Follows the [Rules of React](https://react.dev/reference/rules) - -React Compiler can verify many of the Rules of React statically, and will safely skip compilation when it detects an error. To see the errors we recommend also installing [eslint-plugin-react-compiler](https://www.npmjs.com/package/eslint-plugin-react-compiler). - ### Should I try out the compiler? {/*should-i-try-out-the-compiler*/} -Please note that the compiler is still experimental and has many rough edges. While it has been used in production at companies like Meta, rolling out the compiler to production for your app will depend on the health of your codebase and how well you've followed the [Rules of React](/reference/rules). +Please note that the compiler is still in Beta and has many rough edges. While it has been used in production at companies like Meta, rolling out the compiler to production for your app will depend on the health of your codebase and how well you've followed the [Rules of React](/reference/rules). **You don't have to rush into using the compiler now. It's okay to wait until it reaches a stable release before adopting it.** However, we do appreciate trying it out in small experiments in your apps so that you can [provide feedback](#reporting-issues) to us to help make the compiler better. @@ -119,7 +125,7 @@ In addition to these docs, we recommend checking the [React Compiler Working Gro Prior to installing the compiler, you can first check to see if your codebase is compatible: -npx react-compiler-healthcheck@experimental +npx react-compiler-healthcheck@beta This script will: @@ -141,7 +147,7 @@ Found no usage of incompatible libraries. React Compiler also powers an eslint plugin. The eslint plugin can be used **independently** of the compiler, meaning you can use the eslint plugin even if you don't use the compiler. -npm install eslint-plugin-react-compiler@experimental +npm install -D eslint-plugin-react-compiler@beta Then, add it to your eslint config: @@ -176,28 +182,18 @@ const ReactCompilerConfig = { }; ``` -In rare cases, you can also configure the compiler to run in "opt-in" mode using the `compilationMode: "annotation"` option. This makes it so the compiler will only compile components and hooks annotated with a `"use memo"` directive. Please note that the `annotation` mode is a temporary one to aid early adopters, and that we don't intend for the `"use memo"` directive to be used for the long term. - -```js {2,7} -const ReactCompilerConfig = { - compilationMode: "annotation", -}; +When you have more confidence with rolling out the compiler, you can expand coverage to other directories as well and slowly roll it out to your whole app. -// src/app.jsx -export default function App() { - "use memo"; - // ... -} -``` +#### New projects {/*new-projects*/} -When you have more confidence with rolling out the compiler, you can expand coverage to other directories as well and slowly roll it out to your whole app. +If you're starting a new project, you can enable the compiler on your entire codebase, which is the default behavior. ### Using React Compiler with React 17 or 18 {/*using-react-compiler-with-react-17-or-18*/} React Compiler works best with React 19 RC. If you are unable to upgrade, you can install the extra `react-compiler-runtime` package which will allow the compiled code to run on versions prior to 19. However, note that the minimum supported version is 17. -npm install react-compiler-runtime@experimental +npm install react-compiler-runtime@beta You should also add the correct `target` to your compiler config, where `target` is the major version of React you are targeting: @@ -217,16 +213,22 @@ module.exports = function () { }; ``` -#### New projects {/*new-projects*/} +### Using the compiler on libraries {/*using-the-compiler-on-libraries*/} -If you're starting a new project, you can enable the compiler on your entire codebase, which is the default behavior. +React Compiler can also be used to compile libraries. Because React Compiler needs to run on the original source code prior to any code transformations, it is not possible for an application's build pipeline to compile the libraries they use. Hence, our recommendation is for library maintainers to independently compile and test their libraries with the compiler, and ship compiled code to npm. + +Because your code is pre-compiled, users of your library will not need to have the compiler enabled in order to benefit from the automatic memoization applied to your library. If your library targets apps not yet on React 19, specify a minimum [`target` and add `react-compiler-runtime` as a direct dependency](#using-react-compiler-with-react-17-or-18). The runtime package will use the correct implementation of APIs depending on the application's version, and polyfill the missing APIs if necessary. + +Library code can often require more complex patterns and usage of escape hatches. For this reason, we recommend ensuring that you have sufficient testing in order to identify any issues that might arise from using the compiler on your library. If you identify any issues, you can always opt-out the specific components or hooks with the [`'use no memo'` directive](#something-is-not-working-after-compilation). + +Similarly to apps, it is not necessary to fully compile 100% of your components or hooks to see benefits in your library. A good starting point might be to identify the most performance sensitive parts of your library and ensuring that they don't break the [Rules of React](/reference/rules), which you can use `eslint-plugin-react-compiler` to identify. ## Usage {/*installation*/} ### Babel {/*usage-with-babel*/} -npm install babel-plugin-react-compiler@experimental +npm install babel-plugin-react-compiler@beta The compiler includes a Babel plugin which you can use in your build pipeline to run the compiler. @@ -275,36 +277,7 @@ export default defineConfig(() => { ### Next.js {/*usage-with-nextjs*/} -Next.js has an experimental configuration to enable the React Compiler. It automatically ensures Babel is set up with `babel-plugin-react-compiler`. - -- Install Next.js canary, which uses React 19 Release Candidate -- Install `babel-plugin-react-compiler` - - -npm install next@canary babel-plugin-react-compiler@experimental - - -Then configure the experimental option in `next.config.js`: - -```js {4,5,6} -// next.config.js -/** @type {import('next').NextConfig} */ -const nextConfig = { - experimental: { - reactCompiler: true, - }, -}; - -module.exports = nextConfig; -``` - -Using the experimental option ensures support for the React Compiler in: - -- App Router -- Pages Router -- Webpack (default) -- Turbopack (opt-in through `--turbo`) - +Please refer to the [Next.js docs](https://nextjs.org/docs/canary/app/api-reference/next-config-js/reactCompiler) for more information. ### Remix {/*usage-with-remix*/} Install `vite-plugin-babel`, and add the compiler's Babel plugin to it: @@ -337,40 +310,7 @@ export default defineConfig({ ### Webpack {/*usage-with-webpack*/} -You can create your own loader for React Compiler, like so: - -```js -const ReactCompilerConfig = { /* ... */ }; -const BabelPluginReactCompiler = require('babel-plugin-react-compiler'); - -function reactCompilerLoader(sourceCode, sourceMap) { - // ... - const result = transformSync(sourceCode, { - // ... - plugins: [ - [BabelPluginReactCompiler, ReactCompilerConfig], - ], - // ... - }); - - if (result === null) { - this.callback( - Error( - `Failed to transform "${options.filename}"` - ) - ); - return; - } - - this.callback( - null, - result.code, - result.map === null ? undefined : result.map - ); -} - -module.exports = reactCompilerLoader; -``` +A community Webpack loader is [now available here](https://github.com/SukkaW/react-compiler-webpack). ### Expo {/*usage-with-expo*/} @@ -394,6 +334,16 @@ To report issues, please first create a minimal repro on the [React Compiler Pla You can also provide feedback in the React Compiler Working Group by applying to be a member. Please see [the README for more details on joining](https://github.com/reactwg/react-compiler). +### What does the compiler assume? {/*what-does-the-compiler-assume*/} + +React Compiler assumes that your code: + +1. Is valid, semantic JavaScript. +2. Tests that nullable/optional values and properties are defined before accessing them (for example, by enabling [`strictNullChecks`](https://www.typescriptlang.org/tsconfig/#strictNullChecks) if using TypeScript), i.e., `if (object.nullableProperty) { object.nullableProperty.foo }` or with optional-chaining `object.nullableProperty?.foo`. +3. Follows the [Rules of React](https://react.dev/reference/rules). + +React Compiler can verify many of the Rules of React statically, and will safely skip compilation when it detects an error. To see the errors we recommend also installing [eslint-plugin-react-compiler](https://www.npmjs.com/package/eslint-plugin-react-compiler). + ### How do I know my components have been optimized? {/*how-do-i-know-my-components-have-been-optimized*/} [React Devtools](/learn/react-developer-tools) (v5.0+) has built-in support for React Compiler and will display a "Memo ✨" badge next to components that have been optimized by the compiler. From 5b643d5a66312fac04bb9260af2fa366206cb0d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sat, 19 Oct 2024 18:23:04 +0900 Subject: [PATCH 006/829] docs: fix conflicts in sync with react.dev --- src/content/learn/react-compiler.md | 6 +--- src/content/reference/react/useActionState.md | 32 ++++--------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 6e8e41aed..588b2f071 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -19,13 +19,9 @@ title: React 컴파일러 -<<<<<<< HEAD -React 컴파일러는 커뮤니티로부터 초기 피드백을 받기 위해 오픈소스로 공개된 새로운 실험적 컴파일러입니다. 아직 안정적이지 않으며 프로덕션 환경에서는 완전히 준비되지 않았습니다. +React 컴파일러는 커뮤니티로부터 초기 피드백을 받기 위해 오픈소스로 공개한 새로운 실험적 컴파일러입니다. 아직 안정적이지 않으며 프로덕션 환경에서는 완전히 준비되지 않았습니다. React 컴파일러는 React 19 RC를 필요로 합니다. React 19로 업그레이드할 수 없는 경우 [워킹 그룹](https://github.com/reactwg/react-compiler/discussions/6)에 설명된 대로 사용자 공간 캐시 함수 구현을 시도해 볼 수 있습니다. 그러나 이 방법은 권장하지 않으며 가능한 한 React 19로 업그레이드하는 것이 좋습니다. -======= -React Compiler is a new experimental compiler that we've open sourced to get early feedback from the community. It still has rough edges and is not yet fully ready for production. ->>>>>>> 2b2d0f2309f49c82cf5bb88ea62fb2e44661c634 React 컴파일러는 빌드 타임 전용 도구로 React 앱을 자동으로 최적화합니다. 순수 JavaScript로 동작하며 [React의 규칙](/reference/rules)을 이해하므로 코드를 다시 작성할 필요가 없습니다. diff --git a/src/content/reference/react/useActionState.md b/src/content/reference/react/useActionState.md index dff7b338c..f24569478 100644 --- a/src/content/reference/react/useActionState.md +++ b/src/content/reference/react/useActionState.md @@ -35,11 +35,7 @@ const [state, formAction, isPending] = useActionState(fn, initialState, permalin {/* TODO T164397693: link to actions documentation once it exists */} -<<<<<<< HEAD -컴포넌트 최상위 레벨에서 `useActionState`를 호출하여 [폼 액션이 실행될 때](/reference/react-dom/components/form) 업데이트되는 컴포넌트 state를 생성합니다. `useActionState`에 기존의 폼 작업 함수와 초기 state를 전달하면, 최신 폼 state와 함께 폼에서 사용하는 새로운 액션을 반환합니다. 최신 폼 state 또한 제공된 함수에 전달됩니다. -======= -Call `useActionState` at the top level of your component to create component state that is updated [when a form action is invoked](/reference/react-dom/components/form). You pass `useActionState` an existing form action function as well as an initial state, and it returns a new action that you use in your form, along with the latest form state and whether the Action is still pending. The latest form state is also passed to the function that you provided. ->>>>>>> 2b2d0f2309f49c82cf5bb88ea62fb2e44661c634 +컴포넌트 최상위 레벨에서 `useActionState`를 호출하여 [폼 액션이 실행될 때](/reference/react-dom/components/form) 업데이트되는 컴포넌트 state를 생성합니다. `useActionState`는 기존의 폼 액션 함수와 초기 state를 전달받고, 폼에서 사용할 새로운 액션을 반환합니다. 이와 함께 최신 폼 state와 액션이 여전히 진행(Pending) 중인지 여부도 반환합니다. 최신 폼 State는 제공된 함수에도 전달됩니다. ```js import { useActionState } from "react"; @@ -75,18 +71,11 @@ Server Action과 함께 사용하는 경우, `useActionState`를 사용하여 hy #### 반환값 {/*returns*/} -<<<<<<< HEAD -`useActionState`는 정확히 두 개의 값이 담긴 배열을 반환합니다. +`useActionState`는 다음 3가지 값들이 포함된 배열을 반환합니다. 1. 현재 state입니다. 첫 번째 렌더링에서는 전달한 `initialState`와 일치합니다. 액션이 실행된 이후에는 액션에서 반환한 값과 일치합니다. 2. `form` 컴포넌트의 `action` prop에 전달하거나 폼 내부 `button` 컴포넌트의 `formAction` prop에 전달할 수 있는 새로운 액션입니다. -======= -`useActionState` returns an array with the following values: - -1. The current state. During the first render, it will match the `initialState` you have passed. After the action is invoked, it will match the value returned by the action. -2. A new action that you can pass as the `action` prop to your `form` component or `formAction` prop to any `button` component within the form. -3. The `isPending` flag that tells you whether there is a pending Transition. ->>>>>>> 2b2d0f2309f49c82cf5bb88ea62fb2e44661c634 +3. 대기 중인 전환(Pending Transition)이 있는지 여부를 알려주는 `isPending` 플래그입니다. #### 주의 사항 {/*caveats*/} @@ -116,18 +105,11 @@ function MyComponent() { } ``` -<<<<<<< HEAD -`useActionState`는 정확히 두 개의 항목으로 구성된 배열을 반환합니다. - -1. 폼의 현재 state입니다. 처음에는 제공한 초기 state로 설정되며, 폼이 제출된 후에는 전달한 액션의 반환값으로 설정됩니다. -2. `
`의 `action` prop에 전달할 새로운 action입니다. -======= -`useActionState` returns an array with the following items: +`useActionState`는 다음 3가지 항목들이 포함된 배열을 반환합니다. -1. The current state of the form, which is initially set to the initial state you provided, and after the form is submitted is set to the return value of the action you provided. -2. A new action that you pass to `` as its `action` prop. -3. A pending state that you can utilise whilst your action is processing. ->>>>>>> 2b2d0f2309f49c82cf5bb88ea62fb2e44661c634 +1. 폼의 현재 state입니다. 처음에는 전달한 초기 state로 설정되며, 폼이 제출된 후에는 전달한 액션의 반환값으로 설정됩니다. +2. ``의 `action` prop에 전달할 새로운 액션입니다. +3. 액션이 처리되는 동안 사용할 수 있는 대기(Pending) state입니다. 폼을 제출하면 전달한 액션 함수가 호출됩니다. 액션의 반환값은 폼의 새로운 현재 state가 됩니다. From 78ebe77f821ab9fada2c22a397013ac48a43fd54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sun, 20 Oct 2024 18:16:36 +0900 Subject: [PATCH 007/829] docs: update `content/learn/index.md` (#1084) --- src/content/learn/index.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/content/learn/index.md b/src/content/learn/index.md index eea49705f..bb02d6b26 100644 --- a/src/content/learn/index.md +++ b/src/content/learn/index.md @@ -115,7 +115,7 @@ React는 CSS 파일을 추가하는 방법을 규정하지 않습니다. 가장 ## 데이터 표시하기 {/*displaying-data*/} -JSX를 사용하면 자바스크립트에 마크업을 넣을 수 있습니다. 중괄호를 사용하면 코드에서 일부 변수를 삽입하여 사용자에게 표시할 수 있도록 자바스크립트로 "이스케이프 백" 할 수 있습니다. 아래의 예시는 `user.name`을 표시합니다. +JSX를 사용하면 자바스크립트에 마크업을 넣을 수 있습니다. 중괄호를 사용하면 코드에서 일부 변수를 삽입하여 사용자에게 표시할 수 있도록 자바스크립트로 "이스케이프 백(Escape Back)" 할 수 있습니다. 아래의 예시는 `user.name`을 표시합니다. ```js {3} return ( @@ -125,7 +125,7 @@ return ( ); ``` -JSX 어트리뷰트에서 따옴표 *대신* 중괄호를 사용하여 "자바스크립트로 이스케이프" 할 수도 있습니다. 예를 들어 `className="avatar"`는 `"avatar"` 문자열을 CSS로 전달하지만 `src={user.imageUrl}`는 자바스크립트 `user.imageUrl` 변수 값을 읽은 다음 해당 값을 `src` 어트리뷰트로 전달합니다. +JSX 어트리뷰트에서 따옴표 *대신* 중괄호를 사용하여 "자바스크립트로 이스케이프(Escape Into JavaScript)" 할 수도 있습니다. 예를 들어 `className="avatar"`는 `"avatar"` 문자열을 CSS로 전달하지만 `src={user.imageUrl}`는 자바스크립트 `user.imageUrl` 변수 값을 읽은 다음 해당 값을 `src` 어트리뷰트로 전달합니다. ```js {3,4} return ( @@ -177,7 +177,7 @@ export default function Profile() { -위의 예시에서 `style={{}}` 은 특별한 문법이 아니라 `style={ }` JSX 중괄호 안에 있는 일반 `{}` 객체입니다. 스타일이 자바스크립트 변수에 의존하는 경우 `style` 어트리뷰트를 사용할 수 있습니다. +위의 예시에서 `style={{}}`은 특별한 문법이 아니라 `style={ }` JSX 중괄호 안에 있는 일반 `{}` 객체입니다. 스타일이 자바스크립트 변수에 의존하는 경우 `style` 어트리뷰트를 사용할 수 있습니다. ## 조건부 렌더링 {/*conditional-rendering*/} @@ -197,7 +197,7 @@ return ( ); ``` -더욱 간결한 코드를 원한다면 [조건부 삼항 연산자](https://developer.mozilla.org/ko-KR/docs/Web/JavaScript/Reference/Operators/Conditional_Operator)를 사용할 수 있습니다. 이것은 `if` 문과 달리 JSX 내부에서 작동합니다. +더욱 간결한 코드를 원한다면 [조건부 삼항 연산자](https://developer.mozilla.org/ko-KR/docs/Web/JavaScript/Reference/Operators/Conditional_Operator)를 사용할 수 있습니다. 이것은 `if` 문과 달리 JSX 내부에서 동작합니다. ```js
@@ -223,7 +223,7 @@ return ( 컴포넌트 리스트를 렌더링하기 위해서는 [`for` 문](https://developer.mozilla.org/ko-KR/docs/Web/JavaScript/Reference/Statements/for) 및 [`map()` 함수](https://developer.mozilla.org/ko-KR/docs/Web/JavaScript/Reference/Global_Objects/Array/map)와 같은 자바스크립트 기능을 사용합니다. -예를 들어 여러 제품이 있다고 가정해 보겠습니다. +예를 들어 여러 제품이 있다고 가정하겠습니다. ```js const products = [ @@ -246,7 +246,7 @@ return ( ); ``` -`
  • `에 `key` 어트리뷰트가 있는 것을 주목하세요. 목록의 각 항목에 대해, 형제 항목 사이에서 해당 항목을 고유하게 식별하는 문자열 또는 숫자를 전달해야 합니다. React는 나중에 항목을 삽입, 삭제 또는 재정렬할 때 어떤 일이 일어났는지 알기 위해 key를 사용합니다. +`
  • `에 `key` 어트리뷰트가 있는 것을 주목하세요. 목록의 각 항목에 대해, 형제 항목 사이에서 해당 항목을 고유하게 식별하는 문자열 또는 숫자를 전달해야 합니다. React는 나중에 항목을 삽입, 삭제 또는 재정렬할 때 어떤 일이 일어났는지 알기 위해 `key`를 사용합니다. @@ -295,7 +295,7 @@ function MyButton() { } ``` -`onClick={handleClick}`의 끝에 소괄호가 없는 것을 주목하세요! 이벤트 핸들러 함수를 *호출*하지 않고 *전달*만 하면 됩니다. React는 사용자가 버튼을 클릭할 때 이벤트 핸들러를 호출합니다. +`onClick={handleClick}`의 끝에 소괄호(`()`)가 없는 것을 주목하세요! 이벤트 핸들러 함수를 *호출*하지 않고 *전달*만 하면 됩니다. React는 사용자가 버튼을 클릭할 때 이벤트 핸들러를 호출합니다. ## 화면 업데이트하기 {/*updating-the-screen*/} @@ -380,11 +380,11 @@ button { 각 버튼이 고유한 `count` state를 "기억"하고 다른 버튼에 영향을 주지 않는 방식에 주목해 주세요. -## Hooks 사용하기 {/*using-hooks*/} +## Hook 사용하기 {/*using-hooks*/} -`use`로 시작하는 함수를 *Hooks*라고 합니다. `useState`는 React에서 제공하는 내장 Hook입니다. 다른 내장 Hooks는 [API 레퍼런스](/reference/react)에서 찾아볼 수 있습니다. 또한 기존의 것들을 조합하여 자신만의 Hooks를 작성할 수도 있습니다. +`use`로 시작하는 함수를 *Hook*이라고 합니다. `useState`는 React에서 제공하는 내장 Hook입니다. 다른 내장 Hook은 [API 레퍼런스](/reference/react)에서 찾아볼 수 있습니다. 또한 기존의 것들을 조합하여 자신만의 Hook을 작성할 수도 있습니다. -Hooks는 다른 함수보다 더 제한적입니다. 컴포넌트(또는 다른 Hooks)의 *상단*에서만 Hooks를 호출할 수 있습니다. 조건이나 반복에서 `useState`를 사용하고 싶다면 새 컴포넌트를 추출하여 그곳에 넣으세요. +Hook은 다른 함수보다 더 제한적입니다. 컴포넌트(또는 다른 Hook)의 *상단*에서만 Hook을 호출할 수 있습니다. 조건이나 반복에서 `useState`를 사용하고 싶다면 새 컴포넌트를 추출하여 그곳에 넣으세요. ## 컴포넌트 간에 데이터 공유하기 {/*sharing-data-between-components*/} @@ -394,7 +394,7 @@ Hooks는 다른 함수보다 더 제한적입니다. 컴포넌트(또는 다른 -처음에 `MyButton`의 `count` 각 state는 `0`입니다. +처음에 각 `MyButton`의 `count` State는 `0`입니다. @@ -455,7 +455,7 @@ function MyButton() { ``` -그 다음 공유된 클릭 핸들러와 함께 `MyApp`에서 각 `MyButton`으로 *state를 전달합니다*. 이전에 ``와 같은 기본 제공 태그를 사용했던 것처럼 JSX 중괄호를 사용하여 `MyButton`에 정보를 전달할 수 있습니다: +그 다음 공유된 클릭 핸들러와 함께 `MyApp`에서 각 `MyButton`으로 *state를 전달합니다*. 이전에 ``와 같은 기본 제공 태그를 사용했던 것처럼 JSX 중괄호를 사용하여 `MyButton`에 정보를 전달할 수 있습니다. ```js {11-12} export default function MyApp() { @@ -477,7 +477,7 @@ export default function MyApp() { 이렇게 전달한 정보를 *props*라고 합니다. 이제 `MyApp` 컴포넌트는 `count` state와 `handleClick` 이벤트 핸들러를 포함하며, *이 두 가지를 각 버튼에 props로 전달합니다*. -마지막으로 부모 컴포넌트에서 전달한 props를 *읽도록* `MyButton`을 변경합니다: +마지막으로 부모 컴포넌트에서 전달한 props를 *읽도록* `MyButton`을 변경합니다. ```js {1,3} @@ -490,7 +490,7 @@ function MyButton({ count, onClick }) { } ``` -버튼을 클릭하면 `onClick` 핸들러가 실행됩니다. 각 버튼의 `onClick` prop는 `MyApp` 내부의 `handleClick` 함수로 설정되었으므로 그 안에 있는 코드가 실행됩니다. 이 코드는 `setCount(count + 1)`를 실행하여 `count` state 변수를 증가시킵니다. 새로운 `count` 값은 각 버튼에 prop로 전달되므로 모든 버튼에는 새로운 값이 표시됩니다. 이를 "state 올리기"라고 합니다. state를 위로 이동함으로써 컴포넌트 간에 state를 공유하게 됩니다. +버튼을 클릭하면 `onClick` 핸들러가 실행됩니다. 각 버튼의 `onClick` prop는 `MyApp` 내부의 `handleClick` 함수로 설정되었으므로 그 안에 있는 코드가 실행됩니다. 이 코드는 `setCount(count + 1)`를 실행하여 `count` state 변수를 증가시킵니다. 새로운 `count` 값은 각 버튼에 prop로 전달되므로 모든 버튼에는 새로운 값이 표시됩니다. 이를 "state 끌어올리기"라고 합니다. state를 위로 이동함으로써 컴포넌트 간에 state를 공유하게 됩니다. @@ -535,4 +535,4 @@ button { 이제 React 코드를 작성하는 기본적인 방법을 알았습니다! -[자습서](/learn/tutorial-tic-tac-toe)를 확인하여 실습하고 React로 첫 번째 미니 앱을 만들어보세요. \ No newline at end of file +[자습서](/learn/tutorial-tic-tac-toe)를 확인하여 이를 실습하고 React로 첫 번째 미니 앱을 만들어보세요. From 43c044dbf567109b9e0859c0b722101a59bceb59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sun, 20 Oct 2024 20:14:21 +0900 Subject: [PATCH 008/829] docs(typo): fix typos in `extracting-state-logic-into-a-reducer.md` (#1085) --- .../extracting-state-logic-into-a-reducer.md | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/content/learn/extracting-state-logic-into-a-reducer.md b/src/content/learn/extracting-state-logic-into-a-reducer.md index 682dbb6cb..3d7c279a1 100644 --- a/src/content/learn/extracting-state-logic-into-a-reducer.md +++ b/src/content/learn/extracting-state-logic-into-a-reducer.md @@ -4,14 +4,14 @@ title: state 로직을 reducer로 작성하기 -한 컴포넌트에서 state 업데이트가 여러 이벤트 핸들러로 분산되는 경우가 있습니다. 이 경우 컴포넌트를 관리하기 어려워집니다. 따라서, 이 문제 해결을 위해 state를 업데이트하는 모든 로직을 *reducer*를 사용해 컴포넌트 외부로 단일 함수로 통합해 관리할 수 있습니다. +한 컴포넌트에서 state 업데이트가 여러 이벤트 핸들러로 분산되는 경우가 있습니다. 이 경우 컴포넌트를 관리하기 어려워집니다. 따라서, 문제 해결을 위해 state를 업데이트하는 모든 로직을 *reducer*를 사용해 컴포넌트 외부의 단일 함수로 통합해 관리할 수 있습니다. - reducer 함수란 무엇인가 -- `useState`에서 `useReducer`로 리펙토링 하는 방법 +- `useState`에서 `useReducer`로 리팩토링 하는 방법 - reducer를 언제 사용할 수 있는지 - reducer를 잘 작성하는 방법 @@ -19,7 +19,7 @@ title: state 로직을 reducer로 작성하기 ## reducer를 사용하여 state 로직 통합하기 {/*consolidate-state-logic-with-a-reducer*/} -컴포넌트가 복잡해지면 컴포넌트의 state가 업데이트되는 다양한 경우를 한눈에 파악하기 어려워질 수 있습니다. 예를 들어, 아래의 `TaskApp` 컴포넌트는 state에 `tasks` 배열을 보유하고 있으며, 세 가지의 이벤트 핸들러를 사용하여 task를 추가, 제거 및 수정합니다: +컴포넌트가 복잡해지면 컴포넌트의 state가 업데이트되는 다양한 경우를 한눈에 파악하기 어려워질 수 있습니다. 예를 들어, 아래의 `TaskApp` 컴포넌트는 state에 `tasks` 배열을 보유하고 있으며, 세 가지의 이벤트 핸들러를 사용하여 task를 추가, 제거 및 수정합니다. @@ -180,7 +180,7 @@ ul, li { margin: 0; padding: 0; } -각 이벤트 핸들러는 state를 업데이트하기 위해 `setTasks`를 호출합니다. 컴포넌트가 커질수록 그 안에서 state를 다루는 로직의 양도 늘어나게 됩니다. 복잡성를 줄이고 접근성을 높이기 위해서, 컴포넌트 내부에 있는 state 로직을 컴포넌트 외부의 **"reducer"라고 하는** 단일 함수로 옮길 수 있습니다. +각 이벤트 핸들러는 state를 업데이트하기 위해 `setTasks`를 호출합니다. 컴포넌트가 커질수록 그 안에서 state를 다루는 로직의 양도 늘어나게 됩니다. 복잡성은 줄이고 접근성을 높이기 위해서, 컴포넌트 내부에 있는 state 로직을 컴포넌트 외부의 **"reducer"라고 하는** 단일 함수로 옮길 수 있습니다. reducer는 state를 다루는 다른 방법입니다. 다음과 같은 세가지 단계에 걸쳐 `useState`에서 `useReducer`로 바꿀 수 있습니다. @@ -220,11 +220,11 @@ function handleDeleteTask(taskId) { 위 코드에서 state 설정 관련 로직을 전부 지워보세요. 다음과 같이 세가지 이벤트 핸들러가 남습니다. -- 사용자가 "Add" 를 눌렀을 때 호출되는 `handleAddTask(text)` -- 사용자가 task를 토글하거나 "저장"을 누르면 호출되는 `handleChangeTask(task)` -- 사용자가 "Delete" 를 누르면 호출되는 `handleDeleteTask(taskId)` +- 사용자가 "Add"를 눌렀을 때 호출되는 `handleAddTask(text)`. +- 사용자가 task를 토글하거나 "Save"를 누르면 호출되는 `handleChangeTask(task)`. +- 사용자가 "Delete"를 누르면 호출되는 `handleDeleteTask(taskId)`. -reducer를 사용한 state 관리는 state 직접 설정하는 것과 약간 다릅니다. state를 설정하여 React에게 “무엇을 할 지”를 지시하는 대신, 이벤트 핸들러에서 “action”을 전달하여 “사용자가 방금 한 일”을 지정합니다. (state 업데이트 로직은 다른 곳에 있습니다!) 즉, 이벤트 핸들러를 통해 ”`tasks`를 설정”하는 대신 “task를 추가/변경/삭제”하는 action을 전달하는 것입니다. 이러한 방식이 사용자의 의도를 더 명확하게 설명합니다. +reducer를 사용한 state 관리는 state를 직접 설정하는 것과 약간 다릅니다. state를 설정하여 React에게 "무엇을 할 지"를 지시하는 대신, 이벤트 핸들러에서 "action"을 전달하여 "사용자가 방금 한 일"을 지정합니다. (state 업데이트 로직은 다른 곳에 있습니다!) 즉, 이벤트 핸들러를 통해 "`tasks`를 설정"하는 대신 "task를 추가/변경/삭제"하는 action을 전달하는 것입니다. 이러한 방식이 사용자의 의도를 더 명확하게 설명합니다. ```js function handleAddTask(text) { @@ -282,7 +282,7 @@ dispatch({ ### 2단계: reducer 함수 작성하기 {/*step-2-write-a-reducer-function*/} -reducer 함수는 state에 대한 로직을 넣는 곳 입니다. 이 함수는 현재의 state 값과 action 객체, 이렇게 두 개의 인자를 받고 다음 state 값을 반환합니다. +reducer 함수는 state에 대한 로직을 넣는 곳입니다. 이 함수는 현재의 state 값과 action 객체, 이렇게 두 개의 인자를 받고 다음 state 값을 반환합니다. ```js function yourReducer(state, action) { @@ -296,7 +296,7 @@ React는 reducer에서 반환한 값을 state에 설정합니다. 1. 첫 번째 인자에 현재 state (`tasks`) 선언하기. 2. 두 번째 인자에 `action` 객체 선언하기. -3. reducer에서 *다음* state 반환하기. (React가 state에 설정하게 될 값) +3. reducer에서 *다음* state 반환하기 (React가 state에 설정하게 될 값). 다음은 state 설정과 관련 모든 로직을 reducer 함수로 마이그레이션한 코드입니다. @@ -359,7 +359,7 @@ function tasksReducer(tasks, action) { } ``` -각자 다른 `case` 속에서 선언된 변수들이 서로 충돌하지 않도록 `case` 블록을 중괄호인 `{`와 `}`로 감싸는 걸 추천합니다. 또 `case`는 일반적인 경우라면 `return`으로 끝나야합니다. `return` 하는 것을 잊으면 코드가 다음 case로 "떨어져" 실수할 수 있습니다! +각자 다른 `case` 속에서 선언된 변수들이 서로 충돌하지 않도록 `case` 블록을 중괄호인 `{`와 `}`로 감싸는 걸 추천합니다. 또 `case`는 일반적인 경우라면 `return`으로 끝나야합니다. `return` 하는 것을 잊으면 코드가 다음 `case`로 "떨어져" 실수할 수 있습니다! 아직 switch 문에 익숙하지 않다면, if/else 문을 사용해도 괜찮습니다. @@ -469,9 +469,9 @@ const [tasks, setTasks] = useState(initialTasks); const [tasks, dispatch] = useReducer(tasksReducer, initialTasks); ``` -`useReducer` 훅은 초기 state 값을 입력받아 유상태(stateful) 값을 반환한다는 점과 state를 설정하는 함수(useReducer의 경우는 dispatch 함수를 의미)의 원리를 보면 `useState`와 비슷합니다. 하지만 조금 다른 점이 있습니다. +`useReducer` hook은 초기 state 값을 입력받아 유상태(stateful) 값을 반환한다는 점과 state를 설정하는 함수(`useReducer`의 경우는 dispatch 함수를 의미)의 원리를 보면 `useState`와 비슷합니다. 하지만 조금 다른 점이 있습니다. -`useReducer` 훅은 두 개의 인자를 넘겨받습니다. +`useReducer` hook은 두 개의 인자를 넘겨받습니다. 1. reducer 함수 2. 초기 state 값 @@ -670,7 +670,7 @@ ul, li { margin: 0; padding: 0; } -아래 처럼 reducer를 다른 파일로 분리하는 것도 가능합니다. +아래처럼 reducer를 다른 파일로 분리하는 것도 가능합니다. @@ -884,7 +884,7 @@ reducer가 좋은 점만 있는 것은 아닙니다! 아래에서 `useState`와 reducer를 작성할 때, 다음과 같은 두 가지 팁을 명심하세요. -- **Reducers는 반드시 순수해야 합니다.** [state updater functions](/learn/queueing-a-series-of-state-updates)와 비슷하게, reducer는 렌더링 중에 실행됩니다! (action은 다음 렌더링까지 대기합니다.) 이것은 reducer는 [반드시 순수](/learn/keeping-components-pure)해야한다는 걸 의미합니다.—즉, 입력 값이 같다면 결과 값도 항상 같아야 합니다. 요청을 보내거나 timeout을 스케쥴링하거나 사이드 이펙트(컴포넌트 외부에 영향을 미치는 작업)을 수행해서는 안 됩니다. reducer는 [objects](/learn/updating-objects-in-state)와 [arrays](/learn/updating-arrays-in-state)을 변이 없이 업데이트해야 합니다. +- **Reducer는 반드시 순수해야 합니다.** [state 업데이트 함수](/learn/queueing-a-series-of-state-updates)와 비슷하게, reducer는 렌더링 중에 실행됩니다! (action은 다음 렌더링까지 대기합니다.) 이것은 reducer는 [반드시 순수](/learn/keeping-components-pure)해야한다는 걸 의미합니다. 즉, 입력 값이 같다면 결과 값도 항상 같아야 합니다. 요청을 보내거나 timeout을 스케쥴링하거나 사이드 이펙트(컴포넌트 외부에 영향을 미치는 작업)를 수행해서는 안 됩니다. reducer는 [객체](/learn/updating-objects-in-state)와 [배열](/learn/updating-arrays-in-state)을 변경하지 않고 업데이트해야 합니다. - **각 action은 데이터 안에서 여러 변경들이 있더라도 하나의 사용자 상호작용을 설명해야 합니다.** 예를 들어, 사용자가 reducer가 관리하는 5개의 필드가 있는 양식에서 ‘재설정’을 누른 경우, 5개의 개별 `set_field` action보다는 하나의 `reset_form` action을 전송하는 것이 더 합리적입니다. 모든 action을 reducer에 기록하면 어떤 상호작용이나 응답이 어떤 순서로 일어났는지 재구성할 수 있을 만큼 로그가 명확해야 합니다. 이는 디버깅에 도움이 됩니다! @@ -1096,30 +1096,30 @@ ul, li { margin: 0; padding: 0; } -reducer는 순수해야 하기 때문에, 이 안에서는 state를 변형할 수 없습니다. 그러나, Immer에서 제공하는 특별한 `draft`객체를 사용하면 안전하게 state를 변형할 수 있습니다. 내부적으로, Immer는 변경 사항이 반영된 `초안(draft)`으로 state의 복사본을 생성합니다. 이것이 `useImmerReducer` 가 관리하는 reducer가 첫 번째 인수인 state를 변형할 수 있고 새로운 state 값을 반환할 필요가 없는 이유입니다. +reducer는 순수해야 하기 때문에, 이 안에서는 state를 변경할 수 없습니다. 그러나, Immer에서 제공하는 특별한 `draft` 객체를 사용하면 안전하게 state를 변경할 수 있습니다. 내부적으로, Immer는 변경 사항이 반영된 `draft`로 state의 복사본을 생성합니다. 이것이 `useImmerReducer`가 관리하는 reducer가 첫 번째 인수인 state를 변형할 수 있고 새로운 state 값을 반환할 필요가 없는 이유입니다. ## 요약 {/*요약*/} -- `useState`에서 `useReducer`로 변환하려면: +- `useState`에서 `useReducer`로 변환하려면 1. 이벤트 핸들러에서 action을 전달합니다. 2. 주어진 state와 action에 대해 다음 state를 반환하는 reducer 함수를 작성합니다. 3. `useState`를 `useReducer`로 바꿉니다. - reducer를 사용하면 코드를 조금 더 작성해야 하지만 디버깅과 테스트에 도움이 됩니다. - reducer는 반드시 순수해야 합니다. - 각 action은 단일 사용자 상호작용을 설명해야 합니다. -- 객체와 배열을 변이하는 스타일로 reducer를 작성하려면 Immer 라이브러리를 사용하세요. +- 객체와 배열을 변경하는 스타일로 reducer를 작성하려면 Immer 라이브러리를 사용하세요. #### 이벤트 핸들러에서 action 전달하기 {/*dispatch-actions-from-event-handlers*/} -현재 `ContactList.js`와 `Chat.js`의 이벤트 핸들러 안에는 `// TODO` 주석이 있습니다. 이 때문에 input에 값을 입력해도 동작하지 않고 탭 버튼을 클릭해도 선택된 수신인이 변경할 수 없습니다. +현재 `ContactList.js`와 `Chat.js`의 이벤트 핸들러 안에는 `// TODO` 주석이 있습니다. 이 때문에 input에 값을 입력해도 동작하지 않고 탭 버튼을 클릭해도 선택된 수신인을 변경할 수 없습니다. -`// TODO` 주석이 있는 부분을 지우고 상황에 맞는 action을 `전달(dispatch)`하는 코드를 작성해보세요. action에 대한 힌트를 얻고 싶다면 `messengerReducer.js`에 구현된 reducer를 확인해보세요. 이 reducer는 이미 작성되어있기 때문에 변경할 필요가 없습니다. 여러분은 `ContactList.js`와 `Chat.js`에 action을 담아 전달하는 코드를 작성하기만 하면 됩니다. +`// TODO` 주석이 있는 부분을 지우고 상황에 맞는 action을 `dispatch`하는 코드를 작성해보세요. action에 대한 힌트를 얻고 싶다면 `messengerReducer.js`에 구현된 reducer를 확인해보세요. 이 reducer는 이미 작성되어있기 때문에 변경할 필요가 없습니다. 여러분은 `ContactList.js`와 `Chat.js`에 action을 담아 전달하는 코드를 작성하기만 하면 됩니다. -`dispatch` 함수는 컴포넌트의 prop으로 전달되기 때문에 이미 두 컴포넌트 모두에서 사용할 수 있습니다. 따라서 알맞은 action 객체를 담아 `dispatch` 를 호출하면 됩니다. +`dispatch` 함수는 컴포넌트의 prop으로 전달되기 때문에 이미 두 컴포넌트 모두에서 사용할 수 있습니다. 따라서 알맞은 action 객체를 담아 `dispatch`를 호출하면 됩니다. action 객체를 어떻게 작성해야하는지 확인하고 싶다면, reducer를 보고 어떤 `action` 필드가 들어갈지 유추할 수 있습니다. reducer에 정의된 `changed_selection`의 경우를 예를 들어 보겠습니다. From 8f6d6a92a496ab758e03000928bdacbbbafaddd3 Mon Sep 17 00:00:00 2001 From: lauren Date: Mon, 21 Oct 2024 12:13:10 -0400 Subject: [PATCH 009/829] [compiler] Remove section on healthcheck (#7239) * [compiler] Remove section on healthcheck This package will be deprecated soon. It makes adopting the compiler confusing since it can spread the misconception that you need to have all your components successfully compiled before you can use the compiler. For now let's remove this from our docs and deprecate the package on npm. We can always choose to repurpose this in the future. * Clarify that 100% compilation is not necessary --- src/content/learn/react-compiler.md | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 4fc974fa9..cc7d31927 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -48,6 +48,10 @@ In order to optimize applications, React Compiler automatically memoizes your co The compiler uses its knowledge of JavaScript and React's rules to automatically memoize values or groups of values within your components and hooks. If it detects breakages of the rules, it will automatically skip over just those components or hooks, and continue safely compiling other code. + +React Compiler can statically detect when Rules of React are broken, and safely opt-out of optimizing just the affected components or hooks. It is not necessary for the compiler to optimize 100% of your codebase. + + If your codebase is already very well-memoized, you might not expect to see major performance improvements with the compiler. However, in practice memoizing the correct dependencies that cause performance issues is tricky to get right by hand. @@ -120,28 +124,6 @@ Please note that the compiler is still in Beta and has many rough edges. While i In addition to these docs, we recommend checking the [React Compiler Working Group](https://github.com/reactwg/react-compiler) for additional information and discussion about the compiler. -### Checking compatibility {/*checking-compatibility*/} - -Prior to installing the compiler, you can first check to see if your codebase is compatible: - - -npx react-compiler-healthcheck@beta - - -This script will: - -- Check how many components can be successfully optimized: higher is better -- Check for `` usage: having this enabled and followed means a higher chance that the [Rules of React](/reference/rules) are followed -- Check for incompatible library usage: known libraries that are incompatible with the compiler - -As an example: - - -Successfully compiled 8 out of 9 components. -StrictMode usage not found. -Found no usage of incompatible libraries. - - ### Installing eslint-plugin-react-compiler {/*installing-eslint-plugin-react-compiler*/} React Compiler also powers an eslint plugin. The eslint plugin can be used **independently** of the compiler, meaning you can use the eslint plugin even if you don't use the compiler. @@ -165,7 +147,9 @@ module.exports = { The eslint plugin will display any violations of the rules of React in your editor. When it does this, it means that the compiler has skipped over optimizing that component or hook. This is perfectly okay, and the compiler can recover and continue optimizing other components in your codebase. + **You don't have to fix all eslint violations straight away.** You can address them at your own pace to increase the amount of components and hooks being optimized, but it is not required to fix everything before you can use the compiler. + ### Rolling out the compiler to your codebase {/*using-the-compiler-effectively*/} From d9e650fe6ec6a8b2da56543c54126c408705353f Mon Sep 17 00:00:00 2001 From: lauren Date: Mon, 21 Oct 2024 14:22:35 -0400 Subject: [PATCH 010/829] Add React Compiler Beta Release post (#7240) Add a new blog post announcing the React Compiler Beta release! --- .../2024/10/21/react-compiler-beta-release.md | 126 ++++++++++++++++++ src/content/blog/index.md | 6 + src/sidebarBlog.json | 7 + 3 files changed, 139 insertions(+) create mode 100644 src/content/blog/2024/10/21/react-compiler-beta-release.md diff --git a/src/content/blog/2024/10/21/react-compiler-beta-release.md b/src/content/blog/2024/10/21/react-compiler-beta-release.md new file mode 100644 index 000000000..bba93e4ee --- /dev/null +++ b/src/content/blog/2024/10/21/react-compiler-beta-release.md @@ -0,0 +1,126 @@ +--- +title: "React Compiler Beta Release" +author: Lauren Tan +date: 2024/10/21 +description: At React Conf 2024, we announced the experimental release of React Compiler, a build-time tool that optimizes your React app through automatic memoization. In this post, we want to share what's next for open source, and our progress on the compiler. + +--- + +October 21, 2024 by [Lauren Tan](https://twitter.com/potetotes). + +--- + + + +The React team is excited to share new updates: + + + +1. We're publishing React Compiler Beta today, so that early adopters and library maintainers can try it and provide feedback. +2. We're officially supporting React Compiler for apps on React 17+, through an optional `react-compiler-runtime` package. +3. We're opening up public membership of the [React Compiler Working Group](https://github.com/reactwg/react-compiler) to prepare the community for gradual adoption of the compiler. + +--- + +At [React Conf 2024](/blog/2024/05/22/react-conf-2024-recap), we announced the experimental release of React Compiler, a build-time tool that optimizes your React app through automatic memoization. [You can find an introduction to React Compiler here](/learn/react-compiler). + +Since the first release, we've fixed numerous bugs reported by the React community, received several high quality bug fixes and contributions[^1] to the compiler, made the compiler more resilient to the broad diversity of JavaScript patterns, and have continued to roll out the compiler more widely at Meta. + +In this post, we want to share what's next for React Compiler. + +## Try React Compiler Beta today {/*try-react-compiler-beta-today*/} + +At [React India 2024](https://www.youtube.com/watch?v=qd5yk2gxbtg), we shared an update on React Compiler. Today, we are excited to announce a new Beta release of React Compiler and ESLint plugin. New betas are published to npm using the `@beta` tag. + +To install React Compiler Beta: + + +npm install -D babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta + + +Or, if you're using Yarn: + + +yarn add -D babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta + + +You can watch [Sathya Gunasekaran's](https://twitter.com/_gsathya) talk at React India here: + + + +## We recommend everyone use the React Compiler linter today {/*we-recommend-everyone-use-the-react-compiler-linter-today*/} + +React Compiler’s eslint plugin helps developers proactively identify and correct [Rules of React](/reference/rules) violations. **We strongly recommend everyone use the linter today**. The linter does not require that you have the compiler installed, so you can use it independently, even if you are not ready to try out the compiler. + +To install the linter only: + + +npm install -D eslint-plugin-react-compiler@beta + + +Or, if you're using Yarn: + + +yarn add -D eslint-plugin-react-compiler@beta + + +Using the linter helps identify Rules of React breakages, making it easier to adopt the compiler when it's fully released. + +## Backwards Compatibility {/*backwards-compatibility*/} + +React Compiler produces code that depends on runtime APIs added in React 19, but we've since added support for the compiler to also work with React 17 and 18. If you are not on React 19 yet, in the Beta release you can now try out React Compiler by specifying a minimum `target` in your compiler config, and adding `react-compiler-runtime` as a dependency. [You can find docs on this here](/learn/react-compiler#using-react-compiler-with-react-17-or-18). + +## Using React Compiler in libraries {/*using-react-compiler-in-libraries*/} + +Our initial release was focused on identifying major issues with using the compiler in applications. We've gotten great feedback and have substantially improved the compiler since then. We're now ready for broad feedback from the community, and for library authors to try out the compiler to improve performance and the developer experience of maintaining your library. + +React Compiler can also be used to compile libraries. Because React Compiler needs to run on the original source code prior to any code transformations, it is not possible for an application's build pipeline to compile the libraries they use. Hence, our recommendation is for library maintainers to independently compile and test their libraries with the compiler, and ship compiled code to npm. + +Because your code is pre-compiled, users of your library will not need to have the compiler enabled in order to benefit from the automatic memoization applied to your library. If your library targets apps not yet on React 19, specify a minimum `target` and add `react-compiler-runtime` as a direct dependency. The runtime package will use the correct implementation of APIs depending on the application's version, and polyfill the missing APIs if necessary. + +[You can find more docs on this here.](/learn/react-compiler#using-the-compiler-on-libraries) + +## Opening up React Compiler Working Group to everyone {/*opening-up-react-compiler-working-group-to-everyone*/} + +We previously announced the invite-only [React Compiler Working Group](https://github.com/reactwg/react-compiler) at React Conf to provide feedback, ask questions, and collaborate on the compiler's experimental release. + +From today, together with the Beta release of React Compiler, we are opening up Working Group membership to everyone. The goal of the React Compiler Working Group is to prepare the ecosystem for a smooth, gradual adoption of React Compiler by existing applications and libraries. Please continue to file bug reports in the [React repo](https://github.com/facebook/react), but please leave feedback, ask questions, or share ideas in the [Working Group discussion forum](https://github.com/reactwg/react-compiler/discussions). + +The core team will also use the discussions repo to share our research findings. As the Stable Release gets closer, any important information will also be posted on this forum. + +## React Compiler at Meta {/*react-compiler-at-meta*/} + +At [React Conf](/blog/2024/05/22/react-conf-2024-recap), we shared that our rollout of the compiler on Quest Store and Instagram were successful. Since then, we've deployed React Compiler across several more major web apps at Meta, including [Facebook](https://www.facebook.com) and [Threads](https://www.threads.net). That means if you've used any of these apps recently, you may have had your experience powered by the compiler. We were able to onboard these apps onto the compiler with few code changes required, in a monorepo with more than 100,000 React components. + +We've seen notable performance improvements across all of these apps. As we've rolled out, we're continuing to see results on the order of [the wins we shared previously at ReactConf](https://youtu.be/lyEKhv8-3n0?t=3223). These apps have already been heavily hand tuned and optimized by Meta engineers and React experts over the years, so even improvements on the order of a few percent are a huge win for us. + +We also expected developer productivity wins from React Compiler. To measure this, we collaborated with our data science partners at Meta[^2] to conduct a thorough statistical analysis of the impact of manual memoization on productivity. Before rolling out the compiler at Meta, we discovered that only about 8% of React pull requests used manual memoization and that these pull requests took 31-46% longer to author[^3]. This confirmed our intuition that manual memoization introduces cognitive overhead, and we anticipate that React Compiler will lead to more efficient code authoring and review. Notably, React Compiler also ensures that *all* code is memoized by default, not just the (in our case) 8% where developers explicitly apply memoization. + +## Roadmap to Stable {/*roadmap-to-stable*/} + +*This is not a final roadmap, and is subject to change.* + +We intend to ship a Release Candidate of the compiler in the near future following the Beta release, when the majority of apps and libraries that follow the Rules of React have been proven to work well with the compiler. After a period of final feedback from the community, we plan on a Stable Release for the compiler. The Stable Release will mark the beginning of a new foundation for React, and all apps and libraries will be strongly recommended to use the compiler and eslint plugin. + +* ✅ Experimental: Released at React Conf 2024, primarily for feedback from early adopters. +* ✅ Public Beta: Available today, for feedback from the wider community. +* 🚧 Release Candidate (RC): React Compiler works for the majority of rule-following apps and libraries without issue. +* 🚧 General Availability: After final feedback period from the community. + +These releases also include the compiler's eslint plugin, which surfaces diagnostics statically analyzed by the compiler. We plan to combine the existing eslint-plugin-react-hooks plugin with the compiler's eslint plugin, so only one plugin needs to be installed. + +Post-Stable, we plan to add more compiler optimizations and improvements. This includes both continual improvements to automatic memoization, and new optimizations altogether, with minimal to no change of product code. Upgrading to each new release of the compiler is aimed to be straightforward, and each upgrade will continue to improve performance and add better handling of diverse JavaScript and React patterns. + +Throughout this process, we also plan to prototype an IDE extension for React. It is still very early in research, so we expect to be able to share more of our findings with you in a future React Labs blog post. + +--- + +Thanks to [Sathya Gunasekaran](https://twitter.com/_gsathya), [Joe Savona](https://twitter.com/en_JS), [Ricky Hanlon](https://twitter.com/rickhanlonii), [Alex Taylor](https://github.com/alexmckenley), [Jason Bonta](https://twitter.com/someextent), and [Eli White](https://twitter.com/Eli_White) for reviewing and editing this post. + +--- + +[^1]: Thanks [@nikeee](https://github.com/facebook/react/pulls?q=is%3Apr+author%3Anikeee), [@henryqdineen](https://github.com/facebook/react/pulls?q=is%3Apr+author%3Ahenryqdineen), [@TrickyPi](https://github.com/facebook/react/pulls?q=is%3Apr+author%3ATrickyPi), and several others for their contributions to the compiler. + +[^2]: Thanks [Vaishali Garg](https://www.linkedin.com/in/vaishaligarg09) for leading this study on React Compiler at Meta, and for reviewing this post. + +[^3]: After controlling on author tenure, diff length/complexity, and other potential confounding factors. \ No newline at end of file diff --git a/src/content/blog/index.md b/src/content/blog/index.md index 4a1a165a3..e37631e80 100644 --- a/src/content/blog/index.md +++ b/src/content/blog/index.md @@ -10,6 +10,12 @@ This blog is the official source for the updates from the React team. Anything i
    + + +We announced an experimental release of React Compiler at React Conf 2024. We've made a lot of progress since then, and in this post we want to share what's next for React Compiler ... + + + Last week we hosted React Conf 2024, a two-day conference in Henderson, Nevada where 700+ attendees gathered in-person to discuss the latest in UI engineering. This was our first in-person conference since 2019, and we were thrilled to be able to bring the community together again ... diff --git a/src/sidebarBlog.json b/src/sidebarBlog.json index 26dcdc4dd..84947fdf5 100644 --- a/src/sidebarBlog.json +++ b/src/sidebarBlog.json @@ -11,6 +11,13 @@ "path": "/blog", "skipBreadcrumb": true, "routes": [ + { + "title": "React Compiler Beta Release and Roadmap", + "titleForHomepage": "React Compiler Beta Release and Roadmap", + "icon": "blog", + "date": "October 21, 2024", + "path": "/blog/2024/10/21/react-compiler-beta-release" + }, { "title": "React Conf 2024 Recap", "titleForHomepage": "React Conf 2024 Recap", From e2b2b90c2d3a13a4997d23cff5a8a14a004b6916 Mon Sep 17 00:00:00 2001 From: lauren Date: Mon, 21 Oct 2024 15:02:06 -0400 Subject: [PATCH 011/829] Fix capitalization of eslint (#7241) --- src/content/blog/2024/10/21/react-compiler-beta-release.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/blog/2024/10/21/react-compiler-beta-release.md b/src/content/blog/2024/10/21/react-compiler-beta-release.md index bba93e4ee..768a2e16b 100644 --- a/src/content/blog/2024/10/21/react-compiler-beta-release.md +++ b/src/content/blog/2024/10/21/react-compiler-beta-release.md @@ -50,7 +50,7 @@ You can watch [Sathya Gunasekaran's](https://twitter.com/_gsathya) talk at React ## We recommend everyone use the React Compiler linter today {/*we-recommend-everyone-use-the-react-compiler-linter-today*/} -React Compiler’s eslint plugin helps developers proactively identify and correct [Rules of React](/reference/rules) violations. **We strongly recommend everyone use the linter today**. The linter does not require that you have the compiler installed, so you can use it independently, even if you are not ready to try out the compiler. +React Compiler’s ESLint plugin helps developers proactively identify and correct [Rules of React](/reference/rules) violations. **We strongly recommend everyone use the linter today**. The linter does not require that you have the compiler installed, so you can use it independently, even if you are not ready to try out the compiler. To install the linter only: @@ -100,14 +100,14 @@ We also expected developer productivity wins from React Compiler. To measure thi *This is not a final roadmap, and is subject to change.* -We intend to ship a Release Candidate of the compiler in the near future following the Beta release, when the majority of apps and libraries that follow the Rules of React have been proven to work well with the compiler. After a period of final feedback from the community, we plan on a Stable Release for the compiler. The Stable Release will mark the beginning of a new foundation for React, and all apps and libraries will be strongly recommended to use the compiler and eslint plugin. +We intend to ship a Release Candidate of the compiler in the near future following the Beta release, when the majority of apps and libraries that follow the Rules of React have been proven to work well with the compiler. After a period of final feedback from the community, we plan on a Stable Release for the compiler. The Stable Release will mark the beginning of a new foundation for React, and all apps and libraries will be strongly recommended to use the compiler and ESLint plugin. * ✅ Experimental: Released at React Conf 2024, primarily for feedback from early adopters. * ✅ Public Beta: Available today, for feedback from the wider community. * 🚧 Release Candidate (RC): React Compiler works for the majority of rule-following apps and libraries without issue. * 🚧 General Availability: After final feedback period from the community. -These releases also include the compiler's eslint plugin, which surfaces diagnostics statically analyzed by the compiler. We plan to combine the existing eslint-plugin-react-hooks plugin with the compiler's eslint plugin, so only one plugin needs to be installed. +These releases also include the compiler's ESLint plugin, which surfaces diagnostics statically analyzed by the compiler. We plan to combine the existing eslint-plugin-react-hooks plugin with the compiler's ESLint plugin, so only one plugin needs to be installed. Post-Stable, we plan to add more compiler optimizations and improvements. This includes both continual improvements to automatic memoization, and new optimizations altogether, with minimal to no change of product code. Upgrading to each new release of the compiler is aimed to be straightforward, and each upgrade will continue to improve performance and add better handling of diverse JavaScript and React patterns. From a3656c235e6e51d6d761705e9adad2a00cc1292a Mon Sep 17 00:00:00 2001 From: Ricky Date: Mon, 21 Oct 2024 16:07:47 -0400 Subject: [PATCH 012/829] Add atproto-did (#7242) --- public/.well-known/atproto-did | 1 + 1 file changed, 1 insertion(+) create mode 100644 public/.well-known/atproto-did diff --git a/public/.well-known/atproto-did b/public/.well-known/atproto-did new file mode 100644 index 000000000..ad8b0a36b --- /dev/null +++ b/public/.well-known/atproto-did @@ -0,0 +1 @@ +did:plc:uorpbnp2q32vuvyeruwauyhe \ No newline at end of file From 1bda70ac459659d5ec916b6c130a3e27a8a49b0f Mon Sep 17 00:00:00 2001 From: lauren Date: Tue, 22 Oct 2024 01:55:44 -0400 Subject: [PATCH 013/829] Add link to eslint configuration in compiler blog post (#7244) --- src/content/blog/2024/10/21/react-compiler-beta-release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/blog/2024/10/21/react-compiler-beta-release.md b/src/content/blog/2024/10/21/react-compiler-beta-release.md index 768a2e16b..f5a870b22 100644 --- a/src/content/blog/2024/10/21/react-compiler-beta-release.md +++ b/src/content/blog/2024/10/21/react-compiler-beta-release.md @@ -64,7 +64,7 @@ Or, if you're using Yarn: yarn add -D eslint-plugin-react-compiler@beta -Using the linter helps identify Rules of React breakages, making it easier to adopt the compiler when it's fully released. +After installation you can enable the linter by [adding it to your ESLint config](/learn/react-compiler#installing-eslint-plugin-react-compiler). Using the linter helps identify Rules of React breakages, making it easier to adopt the compiler when it's fully released. ## Backwards Compatibility {/*backwards-compatibility*/} From e628e5df0df29611592a3a15a594f28069966a35 Mon Sep 17 00:00:00 2001 From: Karl Horky Date: Wed, 23 Oct 2024 18:11:08 +0200 Subject: [PATCH 014/829] Add ESLint flat config example, fix ESLint name (#7246) * Add ESLint flat config example, fix ESLint name * Use official terminology * Fix key --- src/content/learn/react-compiler.md | 35 +++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index cc7d31927..df46954d2 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -13,7 +13,7 @@ These docs are still a work in progress. More documentation is available in the * Getting started with the compiler -* Installing the compiler and eslint plugin +* Installing the compiler and ESLint plugin * Troubleshooting @@ -26,7 +26,7 @@ The latest Beta release can be found with the `@beta` tag, and daily experimenta React Compiler is a new compiler that we've open sourced to get early feedback from the community. It is a build-time only tool that automatically optimizes your React app. It works with plain JavaScript, and understands the [Rules of React](/reference/rules), so you don't need to rewrite any code to use it. -The compiler also includes an [eslint plugin](#installing-eslint-plugin-react-compiler) that surfaces the analysis from the compiler right in your editor. **We strongly recommend everyone use the linter today.** The linter does not require that you have the compiler installed, so you can use it even if you are not ready to try out the compiler. +The compiler also includes an [ESLint plugin](#installing-eslint-plugin-react-compiler) that surfaces the analysis from the compiler right in your editor. **We strongly recommend everyone use the linter today.** The linter does not require that you have the compiler installed, so you can use it even if you are not ready to try out the compiler. The compiler is currently released as `beta`, and is available to try out on React 17+ apps and libraries. To install the Beta: @@ -126,13 +126,30 @@ In addition to these docs, we recommend checking the [React Compiler Working Gro ### Installing eslint-plugin-react-compiler {/*installing-eslint-plugin-react-compiler*/} -React Compiler also powers an eslint plugin. The eslint plugin can be used **independently** of the compiler, meaning you can use the eslint plugin even if you don't use the compiler. +React Compiler also powers an ESLint plugin. The ESLint plugin can be used **independently** of the compiler, meaning you can use the ESLint plugin even if you don't use the compiler. npm install -D eslint-plugin-react-compiler@beta -Then, add it to your eslint config: +Then, add it to your ESLint config: + +```js +import reactCompiler from 'eslint-plugin-react-compiler' + +export default [ + { + plugins: { + 'react-compiler': reactCompiler, + }, + rules: { + 'react-compiler/react-compiler': 'error', + }, + }, +] +``` + +Or, in the deprecated eslintrc config format: ```js module.exports = { @@ -140,15 +157,15 @@ module.exports = { 'eslint-plugin-react-compiler', ], rules: { - 'react-compiler/react-compiler': "error", + 'react-compiler/react-compiler': 'error', }, } ``` -The eslint plugin will display any violations of the rules of React in your editor. When it does this, it means that the compiler has skipped over optimizing that component or hook. This is perfectly okay, and the compiler can recover and continue optimizing other components in your codebase. +The ESLint plugin will display any violations of the rules of React in your editor. When it does this, it means that the compiler has skipped over optimizing that component or hook. This is perfectly okay, and the compiler can recover and continue optimizing other components in your codebase. -**You don't have to fix all eslint violations straight away.** You can address them at your own pace to increase the amount of components and hooks being optimized, but it is not required to fix everything before you can use the compiler. +**You don't have to fix all ESLint violations straight away.** You can address them at your own pace to increase the amount of components and hooks being optimized, but it is not required to fix everything before you can use the compiler. ### Rolling out the compiler to your codebase {/*using-the-compiler-effectively*/} @@ -333,11 +350,11 @@ React Compiler can verify many of the Rules of React statically, and will safely [React Devtools](/learn/react-developer-tools) (v5.0+) has built-in support for React Compiler and will display a "Memo ✨" badge next to components that have been optimized by the compiler. ### Something is not working after compilation {/*something-is-not-working-after-compilation*/} -If you have eslint-plugin-react-compiler installed, the compiler will display any violations of the rules of React in your editor. When it does this, it means that the compiler has skipped over optimizing that component or hook. This is perfectly okay, and the compiler can recover and continue optimizing other components in your codebase. **You don't have to fix all eslint violations straight away.** You can address them at your own pace to increase the amount of components and hooks being optimized. +If you have eslint-plugin-react-compiler installed, the compiler will display any violations of the rules of React in your editor. When it does this, it means that the compiler has skipped over optimizing that component or hook. This is perfectly okay, and the compiler can recover and continue optimizing other components in your codebase. **You don't have to fix all ESLint violations straight away.** You can address them at your own pace to increase the amount of components and hooks being optimized. Due to the flexible and dynamic nature of JavaScript however, it's not possible to comprehensively detect all cases. Bugs and undefined behavior such as infinite loops may occur in those cases. -If your app doesn't work properly after compilation and you aren't seeing any eslint errors, the compiler may be incorrectly compiling your code. To confirm this, try to make the issue go away by aggressively opting out any component or hook you think might be related via the [`"use no memo"` directive](#opt-out-of-the-compiler-for-a-component). +If your app doesn't work properly after compilation and you aren't seeing any ESLint errors, the compiler may be incorrectly compiling your code. To confirm this, try to make the issue go away by aggressively opting out any component or hook you think might be related via the [`"use no memo"` directive](#opt-out-of-the-compiler-for-a-component). ```js {2} function SuspiciousComponent() { From eb174dd932613fb0784a78ee2d9360554538cc08 Mon Sep 17 00:00:00 2001 From: Andre Sander Date: Wed, 23 Oct 2024 18:12:04 +0200 Subject: [PATCH 015/829] Update components-and-hooks-must-be-pure.md (#7245) --- .../reference/rules/components-and-hooks-must-be-pure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/rules/components-and-hooks-must-be-pure.md b/src/content/reference/rules/components-and-hooks-must-be-pure.md index 9da65d04a..d3d54560e 100644 --- a/src/content/reference/rules/components-and-hooks-must-be-pure.md +++ b/src/content/reference/rules/components-and-hooks-must-be-pure.md @@ -194,7 +194,7 @@ function ProductDetailPage({ product }) { } ``` -One way to achieve the desired result of updating `window.title` outside of render is to [synchronize the component with `window`](/learn/synchronizing-with-effects). +One way to achieve the desired result of updating `document.title` outside of render is to [synchronize the component with `document`](/learn/synchronizing-with-effects). As long as calling a component multiple times is safe and doesn’t affect the rendering of other components, React doesn’t care if it’s 100% pure in the strict functional programming sense of the word. It is more important that [components must be idempotent](/reference/rules/components-and-hooks-must-be-pure). From defed0cc7221eb0c1ea07cb1cdbf7b9f11e0b31c Mon Sep 17 00:00:00 2001 From: jaeyo03 <137462767+jaeyo03@users.noreply.github.com> Date: Thu, 24 Oct 2024 23:54:30 +0900 Subject: [PATCH 016/829] docs: add explanation for missing y property case (#1093) --- src/content/learn/choosing-the-state-structure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/choosing-the-state-structure.md b/src/content/learn/choosing-the-state-structure.md index b06b54849..fb6833a87 100644 --- a/src/content/learn/choosing-the-state-structure.md +++ b/src/content/learn/choosing-the-state-structure.md @@ -98,7 +98,7 @@ body { margin: 0; padding: 0; height: 250px; } -State 변수가 객체인 경우에는 다른 필드를 명시적으로 복사하지 않고 [하나의 필드만 업데이트할 수 없다](/learn/updating-objects-in-state)는 것을 기억하세요. 예를 들어, 위의 예시에서는 `y` 속성이 전혀 없기 때문입니다. `setPosition({ x: 100 })`를 할 수 없습니다! 대신, `x`만 설정하려면 `setPosition({ ...position, x: 100 })`을 하거나 두 개의 state 변수로 나누고 `setX(100)`을 해야 합니다. +State 변수가 객체인 경우에는 다른 필드를 명시적으로 복사하지 않고 [하나의 필드만 업데이트할 수 없다](/learn/updating-objects-in-state)는 것을 기억하세요. 예를 들어 위의 예시에서 `setPosition({ x: 100 })`은 `y` 속성이 존재하지 않기 때문에 사용할 수 없습니다! 대신, `x`만 설정하려면 `setPosition({ ...position, x: 100 })`을 하거나 두 개의 state 변수로 나누고 `setX(100)`을 해야 합니다. From c772c957891c890343486b15a85b04754c86c966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sat, 26 Oct 2024 15:58:30 +0900 Subject: [PATCH 017/829] docs(typo): curly quotes to straight quotes (#1091) --- ...t-we-have-been-working-on-february-2024.md | 2 +- src/content/learn/conditional-rendering.md | 6 +-- src/content/learn/escape-hatches.md | 4 +- .../extracting-state-logic-into-a-reducer.md | 2 +- .../learn/passing-props-to-a-component.md | 10 ++--- .../queueing-a-series-of-state-updates.md | 6 +-- src/content/learn/rendering-lists.md | 10 ++--- src/content/learn/state-as-a-snapshot.md | 14 +++---- src/content/learn/thinking-in-react.md | 2 +- src/content/learn/tutorial-tic-tac-toe.md | 38 +++++++++---------- src/content/learn/your-first-component.md | 2 +- src/content/reference/react-dom/render.md | 2 +- .../reference/react/useDeferredValue.md | 4 +- src/content/reference/react/useState.md | 2 +- .../reference/react/useSyncExternalStore.md | 2 +- 15 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md b/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md index a71799eae..f7fea38f1 100644 --- a/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md +++ b/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md @@ -109,7 +109,7 @@ Activity는 여전히 연구 중이며, 라이브러리 개발자에게 노출 - [Sathya Gunasekaran](/community/team#sathya-gunasekaran)은 [React India](https://www.youtube.com/watch?v=kjOacmVsLSE) 콘퍼런스에서 React 컴파일러에 관해 이야기했습니다. -- [Dan Abramov](/community/team#dan-abramov)은 [RemixConf](https://www.youtube.com/watch?v=zMf_xeGPn6s)에서 “다른 차원의 React”를 주제로 강연했습니다. 이곳에서 React 서버 컴포넌트와 액션을 어떻게 만들었는지에 관한 대안적인 역사를 탐구했습니다. +- [Dan Abramov](/community/team#dan-abramov)은 [RemixConf](https://www.youtube.com/watch?v=zMf_xeGPn6s)에서 "다른 차원의 React"를 주제로 강연했습니다. 이곳에서 React 서버 컴포넌트와 액션을 어떻게 만들었는지에 관한 대안적인 역사를 탐구했습니다. - [Dan Abramov](/community/team#dan-abramov)은 [Changelog의 JS Party 팟캐스트](https://changelog.com/jsparty/311)에서 React 서버 컴포넌트에 대한 인터뷰를 받았습니다. diff --git a/src/content/learn/conditional-rendering.md b/src/content/learn/conditional-rendering.md index aaacc4d57..10d836bda 100644 --- a/src/content/learn/conditional-rendering.md +++ b/src/content/learn/conditional-rendering.md @@ -270,7 +270,7 @@ return ( ); ``` -이것을 “`isPacked`이면 (`&&`) 체크 표시를 렌더링하고, 그렇지 않으면 아무것도 렌더링하지 않습니다."라고 읽을 수 있습니다. +이것을 "`isPacked`이면 (`&&`) 체크 표시를 렌더링하고, 그렇지 않으면 아무것도 렌더링하지 않습니다."라고 읽을 수 있습니다. 자, 잘 작동합니다. @@ -444,8 +444,8 @@ JavaScript가 익숙하지 않다면, 처음에는 이런 다양한 코드 스 * React에서 JavaScript로 분기 로직을 제어합니다. * 조건부로 `if` 문과 함께 JSX 식을 반환할 수 있습니다. * 조건부로 일부 JSX를 변수에 저장한 다음 중괄호를 사용하여 다른 JSX에 포함할 수 있습니다. -* JSX에서 `{cond ? : }`는 *“`cond`이면 ``를 렌더링하고, 그렇지 않으면 ``를 렌더링합니다."* 를 의미합니다. -* JSX에서 `{cond && }`는 *“`cond`이면, ``를 렌더링하되, 그렇지 않으면 아무것도 렌더링하지 않습니다."* 를 의미합니다. +* JSX에서 `{cond ? : }`는 *"`cond`이면 ``를 렌더링하고, 그렇지 않으면 ``를 렌더링합니다."* 를 의미합니다. +* JSX에서 `{cond && }`는 *"`cond`이면, ``를 렌더링하되, 그렇지 않으면 아무것도 렌더링하지 않습니다."* 를 의미합니다. * 위 예시는 흔한 방법이지만, `if`를 선호한다면 사용하지 않아도 됩니다. diff --git a/src/content/learn/escape-hatches.md b/src/content/learn/escape-hatches.md index 84e2dcc95..bc1fa2238 100644 --- a/src/content/learn/escape-hatches.md +++ b/src/content/learn/escape-hatches.md @@ -23,7 +23,7 @@ title: 탈출구 ## Ref로 값 참조하기 {/*referencing-values-with-refs*/} -컴포넌트가 일부 정보를 “기억”하고 싶지만, 해당 정보가 [렌더링을 유발](/learn/render-and-commit)하지 않도록 하려면 ref를 사용하세요. +컴포넌트가 일부 정보를 "기억"하고 싶지만, 해당 정보가 [렌더링을 유발](/learn/render-and-commit)하지 않도록 하려면 ref를 사용하세요. ```js const ref = useRef(0); @@ -193,7 +193,7 @@ input { display: block; margin-bottom: 20px; } ## Effect가 필요하지 않은 경우 {/*you-might-not-need-an-effect*/} -Effect는 React 패러다임에서 벗어날 수 있는 탈출구입니다. Effect를 사용하면 React를 “벗어나” 컴포넌트를 외부 시스템과 동기화할 수 있습니다. 외부 시스템이 관여하지 않는 경우 (예를 들어 일부 props 또는 state가 변경될 때 컴포넌트의 state를 업데이트하려는 경우) Effect가 필요하지 않습니다. 불필요한 Effect를 제거하면 코드를 더 쉽게 따라갈 수 있고, 실행 속도가 빨라지며, 에러 발생 가능성이 줄어듭니다. +Effect는 React 패러다임에서 벗어날 수 있는 탈출구입니다. Effect를 사용하면 React를 "벗어나" 컴포넌트를 외부 시스템과 동기화할 수 있습니다. 외부 시스템이 관여하지 않는 경우 (예를 들어 일부 props 또는 state가 변경될 때 컴포넌트의 state를 업데이트하려는 경우) Effect가 필요하지 않습니다. 불필요한 Effect를 제거하면 코드를 더 쉽게 따라갈 수 있고, 실행 속도가 빨라지며, 에러 발생 가능성이 줄어듭니다. Effect가 필요하지 않은 두 가지 일반적인 경우가 있습니다. - **렌더링을 위해 데이터를 변환하는 데 Effect가 필요하지 않습니다.** diff --git a/src/content/learn/extracting-state-logic-into-a-reducer.md b/src/content/learn/extracting-state-logic-into-a-reducer.md index 3d7c279a1..7996d67e4 100644 --- a/src/content/learn/extracting-state-logic-into-a-reducer.md +++ b/src/content/learn/extracting-state-logic-into-a-reducer.md @@ -886,7 +886,7 @@ reducer를 작성할 때, 다음과 같은 두 가지 팁을 명심하세요. - **Reducer는 반드시 순수해야 합니다.** [state 업데이트 함수](/learn/queueing-a-series-of-state-updates)와 비슷하게, reducer는 렌더링 중에 실행됩니다! (action은 다음 렌더링까지 대기합니다.) 이것은 reducer는 [반드시 순수](/learn/keeping-components-pure)해야한다는 걸 의미합니다. 즉, 입력 값이 같다면 결과 값도 항상 같아야 합니다. 요청을 보내거나 timeout을 스케쥴링하거나 사이드 이펙트(컴포넌트 외부에 영향을 미치는 작업)를 수행해서는 안 됩니다. reducer는 [객체](/learn/updating-objects-in-state)와 [배열](/learn/updating-arrays-in-state)을 변경하지 않고 업데이트해야 합니다. -- **각 action은 데이터 안에서 여러 변경들이 있더라도 하나의 사용자 상호작용을 설명해야 합니다.** 예를 들어, 사용자가 reducer가 관리하는 5개의 필드가 있는 양식에서 ‘재설정’을 누른 경우, 5개의 개별 `set_field` action보다는 하나의 `reset_form` action을 전송하는 것이 더 합리적입니다. 모든 action을 reducer에 기록하면 어떤 상호작용이나 응답이 어떤 순서로 일어났는지 재구성할 수 있을 만큼 로그가 명확해야 합니다. 이는 디버깅에 도움이 됩니다! +- **각 action은 데이터 안에서 여러 변경들이 있더라도 하나의 사용자 상호작용을 설명해야 합니다.** 예를 들어, 사용자가 reducer가 관리하는 5개의 필드가 있는 양식에서 '재설정'을 누른 경우, 5개의 개별 `set_field` action보다는 하나의 `reset_form` action을 전송하는 것이 더 합리적입니다. 모든 action을 reducer에 기록하면 어떤 상호작용이나 응답이 어떤 순서로 일어났는지 재구성할 수 있을 만큼 로그가 명확해야 합니다. 이는 디버깅에 도움이 됩니다! ## Immer로 간결한 reducer 작성하기 {/*writing-concise-reducers-with-immer*/} diff --git a/src/content/learn/passing-props-to-a-component.md b/src/content/learn/passing-props-to-a-component.md index a5f37597f..65ce933a1 100644 --- a/src/content/learn/passing-props-to-a-component.md +++ b/src/content/learn/passing-props-to-a-component.md @@ -192,7 +192,7 @@ function Avatar({ person, size }) { } ``` -이 문법을 [“구조 분해 할당”](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_a_function_parameter)이라고 부르며 함수 매개변수의 속성과 동등합니다. +이 문법을 ["구조 분해 할당"](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_a_function_parameter)이라고 부르며 함수 매개변수의 속성과 동등합니다. ```js function Avatar(props) { @@ -350,9 +350,9 @@ export function getImageUrl(person, size = 's') { -`` 내부의 ``를 텍스트로 바꾸어 `` 컴포넌트가 중첩된 콘텐츠를 어떻게 감싸는지 확인해 보세요. 그 내부에서 무엇이 렌더링 되는지 “알” 필요는 없습니다. 이 유연한 패턴은 많은 곳에서 볼 수 있습니다. +`` 내부의 ``를 텍스트로 바꾸어 `` 컴포넌트가 중첩된 콘텐츠를 어떻게 감싸는지 확인해 보세요. 그 내부에서 무엇이 렌더링 되는지 "알" 필요는 없습니다. 이 유연한 패턴은 많은 곳에서 볼 수 있습니다. -`children` prop을 가지고 있는 컴포넌트는 부모 컴포넌트가 임의의 JSX로 “채울” 수 있는 “구멍”이 있는 것으로 생각할 수 있습니다. 패널, 그리드 등의 시각적 래퍼에 종종 `children` prop를 사용합니다. +`children` prop을 가지고 있는 컴포넌트는 부모 컴포넌트가 임의의 JSX로 "채울" 수 있는 "구멍"이 있는 것으로 생각할 수 있습니다. 패널, 그리드 등의 시각적 래퍼에 종종 `children` prop를 사용합니다. @@ -416,7 +416,7 @@ export default function App() { 그러나 props는 컴퓨터 과학에서 "변경할 수 없다"라는 의미의 [불변성](https://en.wikipedia.org/wiki/Immutable_object)을 가지고 있습니다. 컴포넌트가 props를 변경해야 하는 경우(예: 사용자의 상호작용이나 새로운 데이터에 대한 응답), 부모 컴포넌트에 *다른 props*, 즉 새로운 객체를 전달하도록 "요청"해야 합니다! 그러면 이전의 props는 버려지고, 결국 자바스크립트 엔진은 기존 props가 차지했던 메모리를 회수하게 됩니다. -**“props 변경”을 시도하지 마세요.** 선택한 색을 변경하는 등 사용자 입력에 반응해야 하는 경우에는 [State: 컴포넌트의 메모리](/learn/state-a-components-memory)에서 배울 “set state”가 필요할 것입니다. +**"props 변경"을 시도하지 마세요.** 선택한 색을 변경하는 등 사용자 입력에 반응해야 하는 경우에는 [State: 컴포넌트의 메모리](/learn/state-a-components-memory)에서 배울 "set state"가 필요할 것입니다. @@ -740,7 +740,7 @@ JSX 어트리뷰트의 컬렉션이 아닌 JavaScript 객체의 속성으로 구 이번 예시에서는 `Avatar` 가 ``의 넓이와 높이를 결정하는 숫자 `size` prop를 받습니다. `size` prop은 `40`으로 설정되어 있습니다. 그러나 새 탭에서 이미지를 열면, 이미지가 `160픽셀`로 커져 있을 것입니다. 실제 이미지 크기는 요청하는 썸네일 크기에 따라 결정됩니다. -`size` prop에 따라 가장 가까운 이미지 크기를 요청하도록 `Avatar` 컴포넌트를 변경하세요. 특히 `size` 가 `90`보다 작으면 `'s'`(”small”)을, 아니면 `'b'`(”big”)을 `getImageUrl` 함수에 전달하세요. `size` prop를 다른 값들을 전달해 보고, 아바타를 렌더링 하는지, 새 탭에서 이미지를 열어 변경사항이 제대로 반영되는지 확인해 보세요. +`size` prop에 따라 가장 가까운 이미지 크기를 요청하도록 `Avatar` 컴포넌트를 변경하세요. 특히 `size` 가 `90`보다 작으면 `'s'`("small")을, 아니면 `'b'`("big")을 `getImageUrl` 함수에 전달하세요. `size` prop를 다른 값들을 전달해 보고, 아바타를 렌더링 하는지, 새 탭에서 이미지를 열어 변경사항이 제대로 반영되는지 확인해 보세요. ```js src/App.js diff --git a/src/content/learn/queueing-a-series-of-state-updates.md b/src/content/learn/queueing-a-series-of-state-updates.md index 4b0633886..27e6a6fd0 100644 --- a/src/content/learn/queueing-a-series-of-state-updates.md +++ b/src/content/learn/queueing-a-series-of-state-updates.md @@ -17,7 +17,7 @@ state 변수를 설정하면 다음 렌더링이 큐에 들어갑니다. 그러 ## React state batches 업데이트 {/*react-batches-state-updates*/} -`setNumber(number + 1)`를 세 번 호출하므로 “+3” 버튼을 클릭하면 세 번 증가할 것으로 예상할 수 있습니다. +`setNumber(number + 1)`를 세 번 호출하므로 "+3" 버튼을 클릭하면 세 번 증가할 것으로 예상할 수 있습니다. @@ -67,7 +67,7 @@ setNumber(0 + 1); ## 다음 렌더링 전에 동일한 state 변수를 여러 번 업데이트하기 {/*updating-the-same-state-multiple-times-before-the-next-render*/} -흔한 사례는 아니지만, 다음 렌더링 전에 동일한 state 변수를 여러 번 업데이트 하고 싶다면 `setNumber(number + 1)` 와 같은 다음 state 값을 전달하는 대신, `setNumber(n => n + 1)` 와 같이 이전 큐의 state를 기반으로 다음 state를 계산하는 함수를 전달할 수 있습니다. 이는 단순히 state 값을 대체하는 것이 아니라 React에 “state 값으로 무언가를 하라”고 지시하는 방법입니다. +흔한 사례는 아니지만, 다음 렌더링 전에 동일한 state 변수를 여러 번 업데이트 하고 싶다면 `setNumber(number + 1)` 와 같은 다음 state 값을 전달하는 대신, `setNumber(n => n + 1)` 와 같이 이전 큐의 state를 기반으로 다음 state를 계산하는 함수를 전달할 수 있습니다. 이는 단순히 state 값을 대체하는 것이 아니라 React에 "state 값으로 무언가를 하라"고 지시하는 방법입니다. 이제 카운터를 증가시켜 보세요. @@ -168,7 +168,7 @@ h1 { display: inline-block; margin: 10px; width: 30px; text-align: center; } 이 이벤트 핸들러가 React에 지시하는 작업은 다음과 같습니다. -1. `setNumber(number + 5)` : `number`는 `0`이므로 `setNumber(0 + 5)`입니다. React는 큐에 *“`5`로 바꾸기”* 를 추가합니다. +1. `setNumber(number + 5)` : `number`는 `0`이므로 `setNumber(0 + 5)`입니다. React는 큐에 *"`5`로 바꾸기"* 를 추가합니다. 2. `setNumber(n => n + 1)` : `n => n + 1`는 업데이터 함수입니다. React는 *해당 함수*를 큐에 추가합니다. 다음 렌더링하는 동안 React는 state 큐를 순회합니다. diff --git a/src/content/learn/rendering-lists.md b/src/content/learn/rendering-lists.md index 900f9f83b..1ba2aaabe 100644 --- a/src/content/learn/rendering-lists.md +++ b/src/content/learn/rendering-lists.md @@ -123,11 +123,11 @@ const people = [{ }]; ``` -직업이 `'chemist'`인 사람들만 표시하고 싶다고 가정해 봅시다. JavaScript의 `filter()` 메서드를 사용하여 해당하는 사람만 반환할 수 있습니다. 이 메서드는 항목 배열을 받아 “test”(`true` 혹은 `false`를 반환하는 함수)를 통과한 후 테스트에 통과된 항목(`true`가 반환된 항목)만 있는 새로운 배열을 반환합니다. +직업이 `'chemist'`인 사람들만 표시하고 싶다고 가정해 봅시다. JavaScript의 `filter()` 메서드를 사용하여 해당하는 사람만 반환할 수 있습니다. 이 메서드는 항목 배열을 받아 "test"(`true` 혹은 `false`를 반환하는 함수)를 통과한 후 테스트에 통과된 항목(`true`가 반환된 항목)만 있는 새로운 배열을 반환합니다. -`직업`이 `'chemist'`인 항목만 필요합니다. 이를 위한 “test” 함수는 `(person) => person.profession === 'chemist'`와 같습니다. 이를 적용하는 과정은 다음과 같습니다. +`직업`이 `'chemist'`인 항목만 필요합니다. 이를 위한 "test" 함수는 `(person) => person.profession === 'chemist'`와 같습니다. 이를 적용하는 과정은 다음과 같습니다. -1. `people`에서 `filter()`를 호출해 `person.profession === 'chemist'`로 필터링해서 “chemist”로만 구성된 새로운 배열 `chemists`를 **생성**합니다. +1. `people`에서 `filter()`를 호출해 `person.profession === 'chemist'`로 필터링해서 "chemist"로만 구성된 새로운 배열 `chemists`를 **생성**합니다. ```js const chemists = people.filter(person => @@ -262,7 +262,7 @@ const listItems = chemists.map(person => { // 중괄호 }); ``` -`=> {` 를 표현하는 화살표 함수를 [“block body”](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#function_body)를 가지고 있다고 말합니다. 이 함수를 사용하면 한 줄 이상의 코드를 작성할 수 있지만 `return` 문을 *반드시* 작성해야 합니다. 그렇지 않으면 아무것도 반환되지 않습니다! +`=> {` 를 표현하는 화살표 함수를 ["block body"](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#function_body)를 가지고 있다고 말합니다. 이 함수를 사용하면 한 줄 이상의 코드를 작성할 수 있지만 `return` 문을 *반드시* 작성해야 합니다. 그렇지 않으면 아무것도 반환되지 않습니다! @@ -1080,7 +1080,7 @@ export const recipes = [{ -여기서 ``는 “`recipe` 객체의 모든 속성을 props로 `Recipe` 컴포넌트로 전달”하는 손쉬운 구문입니다. `` 처럼 각 prop을 명시적으로 작성할 수도 있습니다. +여기서 ``는 "`recipe` 객체의 모든 속성을 props로 `Recipe` 컴포넌트로 전달"하는 손쉬운 구문입니다. `` 처럼 각 prop을 명시적으로 작성할 수도 있습니다. **`key`는 `Recipe`에서 반환된 루트 `
    `가 아니라 `` 자체에 지정된다는 점에 유의하세요.** 이는 이 `key`가 주변 배열의 context 내에서 직접 필요하기 때문입니다. 이전에는 `
    ` 배열이 있었기 때문에 각 배열에 `key`가 필요했지만, 지금은 `` 배열이 있습니다. 즉, 컴포넌트를 추출할 때 복사하여 붙여넣은 JSX 외부에 `key`를 남겨두는 것을 잊지 마세요. diff --git a/src/content/learn/state-as-a-snapshot.md b/src/content/learn/state-as-a-snapshot.md index 84f8a7001..8782bac7b 100644 --- a/src/content/learn/state-as-a-snapshot.md +++ b/src/content/learn/state-as-a-snapshot.md @@ -89,7 +89,7 @@ React가 컴포넌트를 다시 렌더링할 때. -컴포넌트의 메모리로써 state는 함수가 반환된 후 사라지는 일반 변수와 다릅니다. state는 실제로 함수 외부에 마치 선반에 있는 것처럼 React 자체에 “존재”합니다. React가 컴포넌트를 호출하면 특정 렌더링에 대한 state의 스냅샷을 제공합니다. 컴포넌트는 **해당 렌더링의 state 값을 사용해** 계산된 새로운 props 세트와 이벤트 핸들러가 포함된 UI의 스냅샷을 JSX에 반환합니다! +컴포넌트의 메모리로써 state는 함수가 반환된 후 사라지는 일반 변수와 다릅니다. state는 실제로 함수 외부에 마치 선반에 있는 것처럼 React 자체에 "존재"합니다. React가 컴포넌트를 호출하면 특정 렌더링에 대한 state의 스냅샷을 제공합니다. 컴포넌트는 **해당 렌더링의 state 값을 사용해** 계산된 새로운 props 세트와 이벤트 핸들러가 포함된 UI의 스냅샷을 JSX에 반환합니다! @@ -97,7 +97,7 @@ React가 컴포넌트를 다시 렌더링할 때. -다음은 이것이 어떻게 작동하는지 보여주는 간단한 실험입니다. 이 예시에서는 ‘+3’ 버튼을 클릭하면 `setNumber(number + 1)`를 세 번 호출하므로 카운터가 세 번 증가할 것으로 예상할 수 있습니다. +다음은 이것이 어떻게 작동하는지 보여주는 간단한 실험입니다. 이 예시에서는 '+3' 버튼을 클릭하면 `setNumber(number + 1)`를 세 번 호출하므로 카운터가 세 번 증가할 것으로 예상할 수 있습니다. "+3" 버튼을 클릭하면 어떻게 되는지 확인해 봅시다. @@ -212,7 +212,7 @@ setNumber(0 + 5); alert(0); ``` -하지만 경고창에 타이머를 설정하여 컴포넌트가 다시 렌더링 된 후에만 발동하도록 하면 어떨까요? “0” 또는 “5”라고 표시될까요? 맞춰보세요! +하지만 경고창에 타이머를 설정하여 컴포넌트가 다시 렌더링 된 후에만 발동하도록 하면 어떨까요? "0" 또는 "5"라고 표시될까요? 맞춰보세요! @@ -254,14 +254,14 @@ setTimeout(() => { React에 저장된 state는 경고창이 실행될 때 변경되었을 수 있지만 사용자가 상호작용한 시점에 state 스냅샷을 사용하는 건 이미 예약되어 있던 것입니다! -**state 변수의 값은** 이벤트 핸들러의 코드가 비동기적이더라도 **렌더링 내에서 절대 변경되지 않습니다.** 해당 렌더링의 `onClick` 내에서, `setNumber(number + 5)`가 호출된 후에도 `number`의 값은 계속 `0`입니다. 이 값은 컴포넌트를 호출해 React가 UI의 “스냅샷을 찍을” 때 “고정”된 값입니다. +**state 변수의 값은** 이벤트 핸들러의 코드가 비동기적이더라도 **렌더링 내에서 절대 변경되지 않습니다.** 해당 렌더링의 `onClick` 내에서, `setNumber(number + 5)`가 호출된 후에도 `number`의 값은 계속 `0`입니다. 이 값은 컴포넌트를 호출해 React가 UI의 "스냅샷을 찍을" 때 "고정"된 값입니다. 다음은 이벤트 핸들러가 타이밍 실수를 줄이는 방법을 보여주는 예입니다. 아래는 5초 지연된 메시지를 보내는 양식입니다. 이 시나리오를 상상해 보세요. 1. "Send" 버튼을 누르면 Alice에게 "Hello"가 전송됩니다. 2. 5초 지연이 끝나기 전에 "To" 필드의 값을 "Bob"으로 변경합니다. -`alert`에 어떤 내용이 표시되기를 기대하나요? “앨리스에게 인사했습니다”라고 표시될까요, 아니면 “당신은 밥에게 인사했습니다”라고 표시될까요? 알고 있는 내용을 바탕으로 추측해보고, 다음의 코드를 실행해 보세요. +`alert`에 어떤 내용이 표시되기를 기대하나요? "앨리스에게 인사했습니다"라고 표시될까요, 아니면 "당신은 밥에게 인사했습니다"라고 표시될까요? 알고 있는 내용을 바탕으로 추측해보고, 다음의 코드를 실행해 보세요. @@ -316,7 +316,7 @@ label, textarea { margin-bottom: 10px; display: block; } * state를 설정하면 새 렌더링을 요청합니다. * React는 컴포넌트 외부에 마치 선반에 보관하듯 state를 저장합니다. * `useState`를 호출하면 React는 해당 렌더링에 대한 state의 스냅샷을 제공합니다. -* 변수와 이벤트 핸들러는 다시 렌더링해도 “살아남지” 않습니다. 모든 렌더링에는 고유한 이벤트 핸들러가 있습니다. +* 변수와 이벤트 핸들러는 다시 렌더링해도 "살아남지" 않습니다. 모든 렌더링에는 고유한 이벤트 핸들러가 있습니다. * 모든 렌더링(및 그 안의 함수)은 항상 React가 그 렌더링에 제공한 state의 스냅샷을 "보게" 됩니다. * 렌더링 된 JSX에 대해 생각하는 방식과 유사하게 이벤트 핸들러에서 state를 대체할 수 있습니다. * 과거에 생성된 이벤트 핸들러는 그것이 생성된 렌더링 시점의 state 값을 갖습니다. @@ -414,7 +414,7 @@ h1 { margin-top: 20px; } alert(walk ? 'Stop is next' : 'Walk is next'); ``` -하지만 이렇게 읽으면 이해가 될 것입니다. “신호등에 ‘Walk now’가 표시되면, 메시지에 ‘Stop is next.’라고, 표시되어야 합니다.” 이벤트 핸들러 내부의 `walk` 변수는 해당 렌더링의 값인 `walk`와 일치하며 변경되지 않습니다. +하지만 이렇게 읽으면 이해가 될 것입니다. "신호등에 'Walk now'가 표시되면, 메시지에 'Stop is next.'라고, 표시되어야 합니다." 이벤트 핸들러 내부의 `walk` 변수는 해당 렌더링의 값인 `walk`와 일치하며 변경되지 않습니다. 대체 메서드를 적용하여 이것이 올바른지 확인할 수 있습니다. `walk`가 `true`이면 다음과 같은 결과를 얻습니다. diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index 0778d0097..33fad485d 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -60,7 +60,7 @@ JSON이 잘 구조화 되어있다면, 종종 이것이 UI의 컴포넌트 구 -`ProductTable`을 보면 “Name”과 “Price” 레이블을 포함한 테이블 헤더 기능만을 가진 컴포넌트는 없습니다. 독립된 컴포넌트를 따로 생성할 지 생성하지 않을지는 당신의 선택입니다. 이 예시에서는 `ProductTable`의 위의 단순한 헤더들이 `ProductTable`의 일부이기 때문에 위 레이블들을 컴포넌트로 만들지 않고 그냥 남겨두었습니다. 그러나 이 헤더가 복잡해지면 (즉 정렬을 위한 기능을 추가하는 등) `ProductTableHeader` 컴포넌트를 만드는 것이 더 합리적일 것입니다. +`ProductTable`을 보면 "Name"과 "Price" 레이블을 포함한 테이블 헤더 기능만을 가진 컴포넌트는 없습니다. 독립된 컴포넌트를 따로 생성할 지 생성하지 않을지는 당신의 선택입니다. 이 예시에서는 `ProductTable`의 위의 단순한 헤더들이 `ProductTable`의 일부이기 때문에 위 레이블들을 컴포넌트로 만들지 않고 그냥 남겨두었습니다. 그러나 이 헤더가 복잡해지면 (즉 정렬을 위한 기능을 추가하는 등) `ProductTableHeader` 컴포넌트를 만드는 것이 더 합리적일 것입니다. 이제 모의 시안 내의 컴포넌트들을 확인했으니, 이들을 계층 구조로 정리해 봅시다. 모의 시안에서 한 컴포넌트 내에 있는 다른 컴포넌트는 계층 구조에서 자식으로 표현됩니다. diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index 2f7fff51e..1d559a93e 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -514,7 +514,7 @@ body { ### props를 통해 데이터 전달하기 {/*passing-data-through-props*/} -다음으로 사용자가 사각형을 클릭할 때 사각형의 값을 비어있는 상태에서 “X”로 변경해야 합니다. 조금 전 보드를 만들었던 방법으로는 사각형을 변경하는 코드를 9번 (각 사각형당 한번) 복사해서 붙여 넣어야 합니다! 복사-붙여넣기 대신 React의 컴포넌트 아키텍처를 사용하면 재사용할 수 있는 컴포넌트를 만들어서 지저분하고 중복된 코드를 피할 수 있습니다. +다음으로 사용자가 사각형을 클릭할 때 사각형의 값을 비어있는 상태에서 "X"로 변경해야 합니다. 조금 전 보드를 만들었던 방법으로는 사각형을 변경하는 코드를 9번 (각 사각형당 한번) 복사해서 붙여 넣어야 합니다! 복사-붙여넣기 대신 React의 컴포넌트 아키텍처를 사용하면 재사용할 수 있는 컴포넌트를 만들어서 지저분하고 중복된 코드를 피할 수 있습니다. 먼저 `Board` 컴포넌트에서 첫 번째 사각형을 정의하는 줄(``)을 새 `Square` 컴포넌트로 복사하세요. @@ -561,7 +561,7 @@ export default function Board() { ![1로 채워진 보드](../images/tutorial/board-filled-with-ones.png) -이런! 이전에 가지고 있던 번호가 채워진 사각형이 사라졌습니다. 이제 각 사각형은 “1”로 표시됩니다. 이 문제를 해결하기 위해 *props*를 사용하여 각 사각형이 가져야 할 값을 부모 컴포넌트(`Board`)에서 자식 컴포넌트(`Square`)로 전달하겠습니다. +이런! 이전에 가지고 있던 번호가 채워진 사각형이 사라졌습니다. 이제 각 사각형은 "1"로 표시됩니다. 이 문제를 해결하기 위해 *props*를 사용하여 각 사각형이 가져야 할 값을 부모 컴포넌트(`Board`)에서 자식 컴포넌트(`Square`)로 전달하겠습니다. `Square` 컴포넌트를 `Board`에서 전달할 prop `value`를 읽도록 수정하세요. @@ -585,7 +585,7 @@ function Square({ value }) { ![value로 채워진 보드](../images/tutorial/board-filled-with-value.png) -컴포넌트에서 단어 “value”가 아닌 JavaScript 변수 `value`가 렌더링 되어야 합니다. JSX에서 “JavaScript로 탈출”하려면, 중괄호가 필요합니다. JSX에서 `value` 주위에 중괄호를 다음과 같이 추가하세요. +컴포넌트에서 단어 "value"가 아닌 JavaScript 변수 `value`가 렌더링 되어야 합니다. JSX에서 "JavaScript로 탈출"하려면, 중괄호가 필요합니다. JSX에서 `value` 주위에 중괄호를 다음과 같이 추가하세요. ```js {2} function Square({ value }) { @@ -735,9 +735,9 @@ function Square({ value }) { -다음으로 사각형 컴포넌트가 클릭 된 것을 “기억”하고 “X” 표시로 채워보겠습니다. 컴포넌트는 무언가 “기억”하기 위해 *state*를 사용합니다. +다음으로 사각형 컴포넌트가 클릭 된 것을 "기억"하고 "X" 표시로 채워보겠습니다. 컴포넌트는 무언가 "기억"하기 위해 *state*를 사용합니다. -React는 컴포넌트에서 호출하여 무언가를 “기억”할 수 있는 `useState`라는 특별한 함수를 제공합니다. `Square`의 현재 값을 state에 저장하고 `Square`가 클릭 되면 값을 변경해 보도록 하겠습니다. +React는 컴포넌트에서 호출하여 무언가를 "기억"할 수 있는 `useState`라는 특별한 함수를 제공합니다. `Square`의 현재 값을 state에 저장하고 `Square`가 클릭 되면 값을 변경해 보도록 하겠습니다. 파일 상단에서 `useState`를 불러오세요. `Square` 컴포넌트에서 value prop을 제거하는 대신, `Square` 컴포넌트의 시작 부분에 `useState`를 호출하는 새 줄을 추가하고 `value`라는 이름의 state 변수를 반환하도록 하세요. @@ -780,7 +780,7 @@ export default function Board() { } ``` -이제 `Square`가 클릭 되었을 때 “X”를 표시하도록 변경하겠습니다. `console.log("clicked!");` 이벤트 핸들러를 `setValue('X');`로 변경하세요. 이제 `Square` 컴포넌트는 다음과 같습니다. +이제 `Square`가 클릭 되었을 때 "X"를 표시하도록 변경하겠습니다. `console.log("clicked!");` 이벤트 핸들러를 `setValue('X');`로 변경하세요. 이제 `Square` 컴포넌트는 다음과 같습니다. ```js {5} function Square() { @@ -801,7 +801,7 @@ function Square() { } ``` -`onClick` 핸들러에서 `set` 함수를 호출함으로써 React에 ` : () =>
    Text
    ; - + return ; } ``` @@ -54,10 +47,10 @@ const ButtonComponent = () => ; const TextComponent = () =>
    Text
    ; function Parent({type}) { - const Component = type === 'button' + const Component = type === 'button' ? ButtonComponent // Reference existing component : TextComponent; - + return ; } ``` @@ -72,7 +65,7 @@ You might define components inside to access local state: // ❌ Wrong: Inner component to access parent state function Parent() { const [theme, setTheme] = useState('light'); - + function ThemedButton() { // Recreated every render! return ( ); } - + return ; } ``` diff --git a/src/content/reference/eslint-plugin-react-hooks/lints/unsupported-syntax.md b/src/content/reference/eslint-plugin-react-hooks/lints/unsupported-syntax.md index b6055449a..a3eefcdb2 100644 --- a/src/content/reference/eslint-plugin-react-hooks/lints/unsupported-syntax.md +++ b/src/content/reference/eslint-plugin-react-hooks/lints/unsupported-syntax.md @@ -1,6 +1,5 @@ --- title: unsupported-syntax -version: rc --- @@ -9,12 +8,6 @@ Validates against syntax that React Compiler does not support. If you need to, y - - -This rule is available in `eslint-plugin-react-hooks` v6. - - - ## Rule Details {/*rule-details*/} React Compiler needs to statically analyze your code to apply optimizations. Features like `eval` and `with` make it impossible to statically understand what the code does at compile time, so the compiler can't optimize components that use them. diff --git a/src/content/reference/eslint-plugin-react-hooks/lints/use-memo.md b/src/content/reference/eslint-plugin-react-hooks/lints/use-memo.md index faa8c42d1..a5a77e5f6 100644 --- a/src/content/reference/eslint-plugin-react-hooks/lints/use-memo.md +++ b/src/content/reference/eslint-plugin-react-hooks/lints/use-memo.md @@ -1,6 +1,5 @@ --- title: use-memo -version: rc --- @@ -9,12 +8,6 @@ Validates that the `useMemo` hook is used with a return value. See [`useMemo` do - - -This rule is available in `eslint-plugin-react-hooks` v6. - - - ## Rule Details {/*rule-details*/} `useMemo` is for computing and caching expensive values, not for side effects. Without a return value, `useMemo` returns `undefined`, which defeats its purpose and likely indicates you're using the wrong hook. diff --git a/src/content/reference/react-compiler/compiling-libraries.md b/src/content/reference/react-compiler/compiling-libraries.md index f09ffcb72..ec0a7581e 100644 --- a/src/content/reference/react-compiler/compiling-libraries.md +++ b/src/content/reference/react-compiler/compiling-libraries.md @@ -21,7 +21,7 @@ As a library author, you can compile your library code before publishing to npm. Add React Compiler to your library's build process: -npm install -D babel-plugin-react-compiler@rc +npm install -D babel-plugin-react-compiler@latest Configure your build tool to compile your library. For example, with Babel: @@ -45,13 +45,13 @@ If your library supports React versions below 19, you'll need additional configu We recommend installing react-compiler-runtime as a direct dependency: -npm install react-compiler-runtime@rc +npm install react-compiler-runtime@latest ```json { "dependencies": { - "react-compiler-runtime": "^19.1.0-rc.2" + "react-compiler-runtime": "^1.0.0" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0" diff --git a/src/content/reference/react-compiler/configuration.md b/src/content/reference/react-compiler/configuration.md index f38f1afc0..ec9b27e6f 100644 --- a/src/content/reference/react-compiler/configuration.md +++ b/src/content/reference/react-compiler/configuration.md @@ -130,7 +130,7 @@ module.exports = { Older React versions need the runtime package and target configuration: ```bash -npm install react-compiler-runtime@rc +npm install react-compiler-runtime@latest ``` ```js diff --git a/src/content/reference/react-compiler/target.md b/src/content/reference/react-compiler/target.md index 381748513..8ccc4a6b1 100644 --- a/src/content/reference/react-compiler/target.md +++ b/src/content/reference/react-compiler/target.md @@ -45,7 +45,7 @@ Configures the React version compatibility for the compiled output. - Always use string values, not numbers (e.g., `'17'` not `17`) - Don't include patch versions (e.g., use `'18'` not `'18.2.0'`) - React 19 includes built-in compiler runtime APIs -- React 17 and 18 require installing `react-compiler-runtime@rc` +- React 17 and 18 require installing `react-compiler-runtime@latest` --- @@ -75,7 +75,7 @@ For React 17 and React 18 projects, you need two steps: 1. Install the runtime package: ```bash -npm install react-compiler-runtime@rc +npm install react-compiler-runtime@latest ``` 2. Configure the target: @@ -114,7 +114,7 @@ If you see errors like "Cannot find module 'react/compiler-runtime'": 2. If using React 17 or 18, install the runtime: ```bash - npm install react-compiler-runtime@rc + npm install react-compiler-runtime@latest ``` 3. Ensure your target matches your React version: @@ -130,7 +130,7 @@ Ensure the runtime package is: 1. Installed in your project (not globally) 2. Listed in your `package.json` dependencies -3. The correct version (`@rc` tag) +3. The correct version (`@latest` tag) 4. Not in `devDependencies` (it's needed at runtime) ### Checking compiled output {/*checking-output*/} diff --git a/src/content/versions.md b/src/content/versions.md index 780c13eb0..abb32cec4 100644 --- a/src/content/versions.md +++ b/src/content/versions.md @@ -41,7 +41,7 @@ For versions older than React 15, see [15.react.dev](https://15.react.dev). - [React v19](/blog/2024/12/05/react-19) - [React 19 Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide) - [React Compiler Beta Release](/blog/2024/10/21/react-compiler-beta-release) -- [React Compiler RC](/blog/2025/04/21/react-compiler-rc) +- [React Compiler v1.0](/blog/2025/10/07/react-compiler-1) - [React 19.2](/blog/2025/10/01/react-19-2) **Talks** @@ -299,7 +299,7 @@ For versions older than React 15, see [15.react.dev](https://15.react.dev). React was open-sourced on May 29, 2013. The initial commit is: [`75897c`: Initial public release](https://github.com/facebook/react/commit/75897c2dcd1dd3a6ca46284dd37e13d22b4b16b4) -See the first blog post: [Why did we build React?](https://legacy.reactjs.org/blog/2013/06/05/why-react.html) +See the first blog post: [Why did we build React?](https://legacy.reactjs.org/blog/2013/06/05/why-react.html) React was open sourced at Facebook Seattle in 2013: diff --git a/src/sidebarBlog.json b/src/sidebarBlog.json index dad2c44c4..be88c3b4a 100644 --- a/src/sidebarBlog.json +++ b/src/sidebarBlog.json @@ -11,6 +11,13 @@ "path": "/blog", "skipBreadcrumb": true, "routes": [ + { + "title": "React Compiler v1.0", + "titleForHomepage": "React Compiler v1.0", + "icon": "blog", + "date": "October 8, 2025", + "path": "/blog/2025/10/07/react-compiler-1" + }, { "title": "Introducing the React Foundation", "titleForHomepage": "Introducing the React Foundation", @@ -25,13 +32,6 @@ "date": "April 23, 2025", "path": "/blog/2025/04/23/react-labs-view-transitions-activity-and-more" }, - { - "title": "React Compiler RC", - "titleForHomepage": "React Compiler RC", - "icon": "blog", - "date": "April 21, 2025", - "path": "/blog/2025/04/21/react-compiler-rc" - }, { "title": "Sunsetting Create React App", "titleForHomepage": "Sunsetting Create React App", diff --git a/src/sidebarReference.json b/src/sidebarReference.json index 74acac4d4..622fa6874 100644 --- a/src/sidebarReference.json +++ b/src/sidebarReference.json @@ -422,80 +422,65 @@ }, { "title": "component-hook-factories", - "path": "/reference/eslint-plugin-react-hooks/lints/component-hook-factories", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/component-hook-factories" }, { "title": "config", - "path": "/reference/eslint-plugin-react-hooks/lints/config", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/config" }, { "title": "error-boundaries", - "path": "/reference/eslint-plugin-react-hooks/lints/error-boundaries", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/error-boundaries" }, { "title": "gating", - "path": "/reference/eslint-plugin-react-hooks/lints/gating", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/gating" }, { "title": "globals", - "path": "/reference/eslint-plugin-react-hooks/lints/globals", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/globals" }, { "title": "immutability", - "path": "/reference/eslint-plugin-react-hooks/lints/immutability", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/immutability" }, { "title": "incompatible-library", - "path": "/reference/eslint-plugin-react-hooks/lints/incompatible-library", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/incompatible-library" }, { "title": "preserve-manual-memoization", - "path": "/reference/eslint-plugin-react-hooks/lints/preserve-manual-memoization", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/preserve-manual-memoization" }, { "title": "purity", - "path": "/reference/eslint-plugin-react-hooks/lints/purity", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/purity" }, { "title": "refs", - "path": "/reference/eslint-plugin-react-hooks/lints/refs", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/refs" }, { "title": "set-state-in-effect", - "path": "/reference/eslint-plugin-react-hooks/lints/set-state-in-effect", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/set-state-in-effect" }, { "title": "set-state-in-render", - "path": "/reference/eslint-plugin-react-hooks/lints/set-state-in-render", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/set-state-in-render" }, { "title": "static-components", - "path": "/reference/eslint-plugin-react-hooks/lints/static-components", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/static-components" }, { "title": "unsupported-syntax", - "path": "/reference/eslint-plugin-react-hooks/lints/unsupported-syntax", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/unsupported-syntax" }, { "title": "use-memo", - "path": "/reference/eslint-plugin-react-hooks/lints/use-memo", - "version": "rc" + "path": "/reference/eslint-plugin-react-hooks/lints/use-memo" } ] }, diff --git a/vercel.json b/vercel.json index 70ddefbe8..e467632b0 100644 --- a/vercel.json +++ b/vercel.json @@ -253,6 +253,11 @@ "source": "/reference/react/experimental_useEffectEvent", "destination": "/reference/react/useEffectEvent", "permanent": true + }, + { + "source": "/blog/2025/04/21/react-compiler-rc", + "destination": "/blog/2025/10/07/react-compiler-1", + "permanent": true } ], "headers": [ From 6346efd905da8f3262ed2b776342878c7fc506f0 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 11 Oct 2025 16:04:45 +0100 Subject: [PATCH 621/829] Reorder compiler post a bit (#8071) --- .../blog/2025/10/07/react-compiler-1.md | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/content/blog/2025/10/07/react-compiler-1.md b/src/content/blog/2025/10/07/react-compiler-1.md index 5474c50d3..a53acb1ab 100644 --- a/src/content/blog/2025/10/07/react-compiler-1.md +++ b/src/content/blog/2025/10/07/react-compiler-1.md @@ -20,17 +20,15 @@ The React team is excited to share new updates: 2. Compiler-powered lint rules ship in `eslint-plugin-react-hooks`'s `recommended` and `recommended-latest` preset. 3. We've published an incremental adoption guide, and partnered with Expo, Vite, and Next.js so new apps can start with the compiler enabled. ---- - We are releasing the compiler's first stable release today. React Compiler works on both React and React Native, and automatically optimizes components and hooks without requiring rewrites. The compiler has been battle tested on major apps at Meta and is fully production-ready. -[React Compiler](/learn/react-compiler) is a build-time tool that optimizes your React app through automatic memoization. Last year, we published React Compiler's [first beta](/blog/2024/10/21/react-compiler-beta-release) and received lots of great feedback and contributions. We're excited about the wins we've seen from folks adopting the compiler (see case studies from [Sanity Studio](https://github.com/reactwg/react-compiler/discussions/33) and [Wakelet](https://github.com/reactwg/react-compiler/discussions/52)) and are excited to bring the compiler to more users in the React community. +--- -This release is the culmination of a huge and complex engineering effort spanning almost a decade. The React team's first exploration into compilers started with [Prepack](https://github.com/facebookarchive/prepack) in 2017. While this project was eventually shut down, there were many learnings that informed the team on the design of Hooks, which were designed with a future compiler in mind. In 2021, [Xuan Huang](https://x.com/Huxpro) demoed the [first iteration](https://www.youtube.com/watch?v=lGEMwh32soc) of a new take on React Compiler. +## What is React Compiler? {/*what-is-react-compiler*/} -Although this first version of the new React Compiler was eventually rewritten, the first prototype gave us increased confidence that this was a tractable problem, and the learnings that an alternative compiler architecture could precisely give us the memoization characteristics we wanted. [Joe Savona](https://x.com/en_JS), [Sathya Gunasekaran](https://x.com/_gsathya), [Mofei Zhang](https://x.com/zmofei), and [Lauren Tan](https://x.com/potetotes) worked through our first rewrite, moving the compiler's architecture into a Control Flow Graph (CFG) based High-Level Intermediate Representation (HIR). This paved the way for much more precise analysis and even type inference within React Compiler. Since then, many significant portions of the compiler have been rewritten, with each rewrite informed by our learnings from the previous attempt. And we have received significant help and contributions from many members of the [React team](/community/team) along the way. +[React Compiler](/learn/react-compiler) is a build-time tool that optimizes your React app through automatic memoization. -This stable release is our first of many. The compiler will continue to evolve and improve, and we expect to see it become a new foundation and era for the next decade and more of React. +You can get an intuitive sense of how the Compiler works by [looking at the playground](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEAKhACYQAyeYOAFMEThRGADRFp4A2OCMIgF8AlEWAAdYkTiE6XXvxgJyZSmCIBeZqzAA6bnwH0cWgHzM9dAIY4oGzY4VGYIgNxSiRT1yy4CxAAW1pjkPAgAwjx4cADW9HjkYpLSXrKYkOF6PBAA5glJPkLexD7KdjDEADw08nj8ALZgmsCGSipqbMWEUTGxLcGh4b1xxQD0Zh6YQiDsIOncuSggeA0ADhAwpjgAnmsI4kQACjxQuXiYAPJr+HLCXDAQDUQA5ABG1m8IPAC0a6fnTA-ZTWXA-WTrXgCMbkWg4F5TKSMHxjMYQta8WwBACyFAQyG8IGsPB4EhAUmKYCxYG4CA0JzOF2utwy7lm4ECEAA7gBJTBKTDEsAoHAwKAIIRAA). Fundamentally, React Compiler relies on an old idea from functional programming: pure functions don't "do" anything (they only compute things), so it is safe to reorder their calls, or to reuse their past output for the same inputs. React Compiler checks that your code follows the [Rules of React](https://react.dev/reference/rules) which ensure your code can be reordered this way. You can jump straight to the [quickstart](/learn/react-compiler), or read on for the highlights from React Conf 2025. @@ -138,7 +136,7 @@ To enable React Compiler rules, we recommend using the `recommended` preset. You - Flagging expensive work inside effects via [`set-state-in-effect`](/reference/eslint-plugin-react-hooks/lints/set-state-in-effect). - Preventing unsafe ref access during render with [`refs`](/reference/eslint-plugin-react-hooks/lints/refs). -## What should I do about useMemo, useCallback, and React.memo? {/*what-should-i-do-about-usememo-usecallback-and-reactmemo*/} +## What should I do about `useMemo`, `useCallback`, and `React.memo`? {/*what-should-i-do-about-usememo-usecallback-and-reactmemo*/} By default, React Compiler will memoize your code based on its analysis and heuristics. In most cases, this memoization will be as precise, or moreso, than what you may have written — and as noted above, the compiler can memoize even in cases where `useMemo`/`useCallback` cannot be used, such as after an early return. However, in some cases developers may need more control over memoization. The `useMemo` and `useCallback` hooks can continue to be used with React Compiler as an escape hatch to provide control over which values are memoized. A common use-case for this is if a memoized value is used as an effect dependency, in order to ensure that an effect does not fire repeatedly even when its dependencies do not meaningfully change. @@ -191,4 +189,16 @@ If you don't have good test coverage, we recommend pinning the compiler to an ex --- +## Looking back at the road to 1.0 {/*looking-back-at-the-road-to-10*/} + +Last year, we published React Compiler's [first beta](/blog/2024/10/21/react-compiler-beta-release) and received lots of great feedback and contributions. We're excited about the wins we've seen from folks adopting the compiler (see case studies from [Sanity Studio](https://github.com/reactwg/react-compiler/discussions/33) and [Wakelet](https://github.com/reactwg/react-compiler/discussions/52)) and are excited to bring the compiler to more users in the React community. + +This release is the culmination of a huge and complex engineering effort spanning almost a decade. The React team's first exploration into compilers started with [Prepack](https://github.com/facebookarchive/prepack) in 2017. While this project was eventually shut down, there were many learnings that informed the team on the design of Hooks, which were designed with a future compiler in mind. In 2021, [Xuan Huang](https://x.com/Huxpro) demoed the [first iteration](https://www.youtube.com/watch?v=lGEMwh32soc) of a new take on React Compiler. + +Although this first version of the new React Compiler was eventually rewritten, the first prototype gave us increased confidence that this was a tractable problem, and the learnings that an alternative compiler architecture could precisely give us the memoization characteristics we wanted. [Joe Savona](https://x.com/en_JS), [Sathya Gunasekaran](https://x.com/_gsathya), [Mofei Zhang](https://x.com/zmofei), and [Lauren Tan](https://x.com/potetotes) worked through our first rewrite, moving the compiler's architecture into a Control Flow Graph (CFG) based High-Level Intermediate Representation (HIR). This paved the way for much more precise analysis and even type inference within React Compiler. Since then, many significant portions of the compiler have been rewritten, with each rewrite informed by our learnings from the previous attempt. We also received significant help and contributions from many members of the [React team](/community/team). + +This stable release is our first of many. The compiler will continue to evolve and improve, and we expect to see it become a new foundation and era for the next decade and more of React. + +--- + Thanks to [Jason Bonta](https://x.com/someextent), [Jimmy Lai](https://x.com/feedthejim), [Kang Dongyoon](https://x.com/kdy1dev) (@kdy1dev), and [Dan Abramov](https://bsky.app/profile/danabra.mov) for reviewing and editing this post. From 16e97fad43319f10032f7e22d6614fd122b64e9b Mon Sep 17 00:00:00 2001 From: mdj-uk <101579982+mdj-uk@users.noreply.github.com> Date: Sat, 11 Oct 2025 16:09:33 +0100 Subject: [PATCH 622/829] Fix server/client typo in docs (#6627) * Fix server/client typo in docs Fixes #6601 * Update form.md * Update form.md * Update form.md --- src/content/reference/react-dom/components/form.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md index b17b1a40b..1043b13a0 100644 --- a/src/content/reference/react-dom/components/form.md +++ b/src/content/reference/react-dom/components/form.md @@ -278,7 +278,7 @@ export default function Search() { Displaying a form submission error message before the JavaScript bundle loads for progressive enhancement requires that: -1. `` be rendered by a [Server Component](/reference/rsc/use-client) +1. `` be rendered by a [Client Component](/reference/rsc/use-client) 1. the function passed to the ``'s `action` prop be a [Server Function](/reference/rsc/server-functions) 1. the `useActionState` Hook be used to display the error message From 7e24db5f6ac42095c6ebc33f0a02296ca4363875 Mon Sep 17 00:00:00 2001 From: Uladzislau Hramyka Date: Sat, 11 Oct 2025 18:23:02 +0300 Subject: [PATCH 623/829] fix: correct example link to minified error on /errors index page (#8070) --- src/content/errors/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/errors/index.md b/src/content/errors/index.md index 25746d25d..d4fc3927a 100644 --- a/src/content/errors/index.md +++ b/src/content/errors/index.md @@ -7,4 +7,4 @@ In the minified production build of React, we avoid sending down full error mess We highly recommend using the development build locally when debugging your app since it tracks additional debug info and provides helpful warnings about potential problems in your apps, but if you encounter an exception while using the production build, the error message will include just a link to the docs for the error. -For an example, see: [https://react.dev/errors/149](/errors/421). +For an example, see: [https://react.dev/errors/149](/errors/149). From 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 11 Oct 2025 17:39:53 +0100 Subject: [PATCH 624/829] Revert "Reorder compiler post a bit (#8071)" (#8074) This reverts commit 6346efd905da8f3262ed2b776342878c7fc506f0. --- .../blog/2025/10/07/react-compiler-1.md | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/content/blog/2025/10/07/react-compiler-1.md b/src/content/blog/2025/10/07/react-compiler-1.md index a53acb1ab..5474c50d3 100644 --- a/src/content/blog/2025/10/07/react-compiler-1.md +++ b/src/content/blog/2025/10/07/react-compiler-1.md @@ -20,15 +20,17 @@ The React team is excited to share new updates: 2. Compiler-powered lint rules ship in `eslint-plugin-react-hooks`'s `recommended` and `recommended-latest` preset. 3. We've published an incremental adoption guide, and partnered with Expo, Vite, and Next.js so new apps can start with the compiler enabled. +--- + We are releasing the compiler's first stable release today. React Compiler works on both React and React Native, and automatically optimizes components and hooks without requiring rewrites. The compiler has been battle tested on major apps at Meta and is fully production-ready. ---- +[React Compiler](/learn/react-compiler) is a build-time tool that optimizes your React app through automatic memoization. Last year, we published React Compiler's [first beta](/blog/2024/10/21/react-compiler-beta-release) and received lots of great feedback and contributions. We're excited about the wins we've seen from folks adopting the compiler (see case studies from [Sanity Studio](https://github.com/reactwg/react-compiler/discussions/33) and [Wakelet](https://github.com/reactwg/react-compiler/discussions/52)) and are excited to bring the compiler to more users in the React community. -## What is React Compiler? {/*what-is-react-compiler*/} +This release is the culmination of a huge and complex engineering effort spanning almost a decade. The React team's first exploration into compilers started with [Prepack](https://github.com/facebookarchive/prepack) in 2017. While this project was eventually shut down, there were many learnings that informed the team on the design of Hooks, which were designed with a future compiler in mind. In 2021, [Xuan Huang](https://x.com/Huxpro) demoed the [first iteration](https://www.youtube.com/watch?v=lGEMwh32soc) of a new take on React Compiler. -[React Compiler](/learn/react-compiler) is a build-time tool that optimizes your React app through automatic memoization. +Although this first version of the new React Compiler was eventually rewritten, the first prototype gave us increased confidence that this was a tractable problem, and the learnings that an alternative compiler architecture could precisely give us the memoization characteristics we wanted. [Joe Savona](https://x.com/en_JS), [Sathya Gunasekaran](https://x.com/_gsathya), [Mofei Zhang](https://x.com/zmofei), and [Lauren Tan](https://x.com/potetotes) worked through our first rewrite, moving the compiler's architecture into a Control Flow Graph (CFG) based High-Level Intermediate Representation (HIR). This paved the way for much more precise analysis and even type inference within React Compiler. Since then, many significant portions of the compiler have been rewritten, with each rewrite informed by our learnings from the previous attempt. And we have received significant help and contributions from many members of the [React team](/community/team) along the way. -You can get an intuitive sense of how the Compiler works by [looking at the playground](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEAKhACYQAyeYOAFMEThRGADRFp4A2OCMIgF8AlEWAAdYkTiE6XXvxgJyZSmCIBeZqzAA6bnwH0cWgHzM9dAIY4oGzY4VGYIgNxSiRT1yy4CxAAW1pjkPAgAwjx4cADW9HjkYpLSXrKYkOF6PBAA5glJPkLexD7KdjDEADw08nj8ALZgmsCGSipqbMWEUTGxLcGh4b1xxQD0Zh6YQiDsIOncuSggeA0ADhAwpjgAnmsI4kQACjxQuXiYAPJr+HLCXDAQDUQA5ABG1m8IPAC0a6fnTA-ZTWXA-WTrXgCMbkWg4F5TKSMHxjMYQta8WwBACyFAQyG8IGsPB4EhAUmKYCxYG4CA0JzOF2utwy7lm4ECEAA7gBJTBKTDEsAoHAwKAIIRAA). Fundamentally, React Compiler relies on an old idea from functional programming: pure functions don't "do" anything (they only compute things), so it is safe to reorder their calls, or to reuse their past output for the same inputs. React Compiler checks that your code follows the [Rules of React](https://react.dev/reference/rules) which ensure your code can be reordered this way. +This stable release is our first of many. The compiler will continue to evolve and improve, and we expect to see it become a new foundation and era for the next decade and more of React. You can jump straight to the [quickstart](/learn/react-compiler), or read on for the highlights from React Conf 2025. @@ -136,7 +138,7 @@ To enable React Compiler rules, we recommend using the `recommended` preset. You - Flagging expensive work inside effects via [`set-state-in-effect`](/reference/eslint-plugin-react-hooks/lints/set-state-in-effect). - Preventing unsafe ref access during render with [`refs`](/reference/eslint-plugin-react-hooks/lints/refs). -## What should I do about `useMemo`, `useCallback`, and `React.memo`? {/*what-should-i-do-about-usememo-usecallback-and-reactmemo*/} +## What should I do about useMemo, useCallback, and React.memo? {/*what-should-i-do-about-usememo-usecallback-and-reactmemo*/} By default, React Compiler will memoize your code based on its analysis and heuristics. In most cases, this memoization will be as precise, or moreso, than what you may have written — and as noted above, the compiler can memoize even in cases where `useMemo`/`useCallback` cannot be used, such as after an early return. However, in some cases developers may need more control over memoization. The `useMemo` and `useCallback` hooks can continue to be used with React Compiler as an escape hatch to provide control over which values are memoized. A common use-case for this is if a memoized value is used as an effect dependency, in order to ensure that an effect does not fire repeatedly even when its dependencies do not meaningfully change. @@ -189,16 +191,4 @@ If you don't have good test coverage, we recommend pinning the compiler to an ex --- -## Looking back at the road to 1.0 {/*looking-back-at-the-road-to-10*/} - -Last year, we published React Compiler's [first beta](/blog/2024/10/21/react-compiler-beta-release) and received lots of great feedback and contributions. We're excited about the wins we've seen from folks adopting the compiler (see case studies from [Sanity Studio](https://github.com/reactwg/react-compiler/discussions/33) and [Wakelet](https://github.com/reactwg/react-compiler/discussions/52)) and are excited to bring the compiler to more users in the React community. - -This release is the culmination of a huge and complex engineering effort spanning almost a decade. The React team's first exploration into compilers started with [Prepack](https://github.com/facebookarchive/prepack) in 2017. While this project was eventually shut down, there were many learnings that informed the team on the design of Hooks, which were designed with a future compiler in mind. In 2021, [Xuan Huang](https://x.com/Huxpro) demoed the [first iteration](https://www.youtube.com/watch?v=lGEMwh32soc) of a new take on React Compiler. - -Although this first version of the new React Compiler was eventually rewritten, the first prototype gave us increased confidence that this was a tractable problem, and the learnings that an alternative compiler architecture could precisely give us the memoization characteristics we wanted. [Joe Savona](https://x.com/en_JS), [Sathya Gunasekaran](https://x.com/_gsathya), [Mofei Zhang](https://x.com/zmofei), and [Lauren Tan](https://x.com/potetotes) worked through our first rewrite, moving the compiler's architecture into a Control Flow Graph (CFG) based High-Level Intermediate Representation (HIR). This paved the way for much more precise analysis and even type inference within React Compiler. Since then, many significant portions of the compiler have been rewritten, with each rewrite informed by our learnings from the previous attempt. We also received significant help and contributions from many members of the [React team](/community/team). - -This stable release is our first of many. The compiler will continue to evolve and improve, and we expect to see it become a new foundation and era for the next decade and more of React. - ---- - Thanks to [Jason Bonta](https://x.com/someextent), [Jimmy Lai](https://x.com/feedthejim), [Kang Dongyoon](https://x.com/kdy1dev) (@kdy1dev), and [Dan Abramov](https://bsky.app/profile/danabra.mov) for reviewing and editing this post. From 02ecdeda7caf45ac950c01b6cc9be275571f8130 Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister Date: Mon, 13 Oct 2025 11:13:24 +0200 Subject: [PATCH 625/829] Update caveats for Activity rendering behavior (#8067) Co-authored-by: Sebastian "Sebbie" Silbermann --- src/content/reference/react/Activity.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/content/reference/react/Activity.md b/src/content/reference/react/Activity.md index cf73efb26..53c38f64f 100644 --- a/src/content/reference/react/Activity.md +++ b/src/content/reference/react/Activity.md @@ -48,6 +48,7 @@ In this way, Activity can be thought of as a mechanism for rendering "background #### Caveats {/*caveats*/} - If an Activity is rendered inside of a [ViewTransition](/reference/react/ViewTransition), and it becomes visible as a result of an update caused by [startTransition](/reference/react/startTransition), it will activate the ViewTransition's `enter` animation. If it becomes hidden, it will activate its `exit` animation. +- An Activity that just renders text will not render anything rather than rendering hidden text, because there’s no corresponding DOM element to apply visibility changes to. For example, `` will not produce any output in the DOM for `const ComponentThatJustReturnsText = () => "Hello, World!"`. --- @@ -1248,4 +1249,4 @@ When an `` is "hidden", all its children's Effects are cleaned up. Con If you're relying on an Effect mounting to clean up a component's side effects, refactor the Effect to do the work in the returned cleanup function instead. -To eagerly find problematic Effects, we recommend adding [``](/reference/react/StrictMode) which will eagerly perform Activity unmounts and mounts to catch any unexpected side-effects. \ No newline at end of file +To eagerly find problematic Effects, we recommend adding [``](/reference/react/StrictMode) which will eagerly perform Activity unmounts and mounts to catch any unexpected side-effects. From a677ba342473ada89cfd6730595ca90d6055fc41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Mon, 13 Oct 2025 12:39:04 +0200 Subject: [PATCH 626/829] Fragment refs - Remove unused ref from focus fragment example (#8056) --- src/content/reference/react/Fragment.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/content/reference/react/Fragment.md b/src/content/reference/react/Fragment.md index 3b771d408..7399ee240 100644 --- a/src/content/reference/react/Fragment.md +++ b/src/content/reference/react/Fragment.md @@ -317,8 +317,6 @@ Fragment refs provide focus management methods that work across all DOM nodes wi import { Fragment, useRef } from 'react'; function FocusFragment({ children }) { - const fragmentRef = useRef(null); - return ( fragmentInstance?.focus()}> {children} From 9ef1c4741776a14b034711cc03e4124ccc53e337 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 15 Oct 2025 13:52:59 +0530 Subject: [PATCH 627/829] fix: Breaking up a sentence to make it easier to understand (#8078) --- src/content/learn/understanding-your-ui-as-a-tree.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/understanding-your-ui-as-a-tree.md b/src/content/learn/understanding-your-ui-as-a-tree.md index 2abf7affc..afc38cd33 100644 --- a/src/content/learn/understanding-your-ui-as-a-tree.md +++ b/src/content/learn/understanding-your-ui-as-a-tree.md @@ -20,7 +20,7 @@ React, and many other UI libraries, model UI as a tree. Thinking of your app as ## Your UI as a tree {/*your-ui-as-a-tree*/} -Trees are a relationship model between items and UI is often represented using tree structures. For example, browsers use tree structures to model HTML ([DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction)) and CSS ([CSSOM](https://developer.mozilla.org/docs/Web/API/CSS_Object_Model)). Mobile platforms also use trees to represent their view hierarchy. +Trees are a relationship model between items. The UI is often represented using tree structures. For example, browsers use tree structures to model HTML ([DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction)) and CSS ([CSSOM](https://developer.mozilla.org/docs/Web/API/CSS_Object_Model)). Mobile platforms also use trees to represent their view hierarchy. From 3b8acebf3853ac84a1a018ea029a666f1c9f43da Mon Sep 17 00:00:00 2001 From: hg-pyun Date: Thu, 16 Oct 2025 10:36:03 +0900 Subject: [PATCH 628/829] fix: resolve conflict --- package.json | 28 +++------------- src/components/MDX/Sandpack/NavigationBar.tsx | 4 --- src/sidebarBlog.json | 4 --- src/sidebarHome.json | 4 --- src/sidebarLearn.json | 6 ---- yarn.lock | 33 ++++++------------- 6 files changed, 14 insertions(+), 65 deletions(-) diff --git a/package.json b/package.json index 8581484e0..43a55a005 100644 --- a/package.json +++ b/package.json @@ -4,42 +4,29 @@ "scripts": { "analyze": "ANALYZE=true next build", "dev": "next-remote-watch ./src/content", -<<<<<<< HEAD "build": "yarn cache-reset && next build && node --experimental-modules ./scripts/downloadFonts.mjs", - "lint": "next lint", - "lint:fix": "next lint --fix", -======= - "build": "next build && node --experimental-modules ./scripts/downloadFonts.mjs", "lint": "next lint && eslint \"src/content/**/*.md\"", "lint:fix": "next lint --fix && eslint \"src/content/**/*.md\" --fix", ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 "format:source": "prettier --config .prettierrc --write \"{plugins,src}/**/*.{js,ts,jsx,tsx,css}\"", "nit:source": "prettier --config .prettierrc --list-different \"{plugins,src}/**/*.{js,ts,jsx,tsx,css}\"", "prettier": "yarn format:source", "prettier:diff": "yarn nit:source", "lint-heading-ids": "node scripts/headingIdLinter.js", "fix-headings": "node scripts/headingIdLinter.js --fix", -<<<<<<< HEAD - "ci-check": "npm-run-all prettier:diff --parallel lint tsc lint-heading-ids rss lint-editorconfig", -======= - "ci-check": "npm-run-all prettier:diff --parallel lint tsc lint-heading-ids rss deadlinks", ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 + "ci-check": "npm-run-all prettier:diff --parallel lint tsc lint-heading-ids rss deadlinks lint-editorconfig", "tsc": "tsc --noEmit", "start": "next start", "postinstall": "yarn --cwd eslint-local-rules install && is-ci || husky install .husky", "check-all": "npm-run-all prettier lint:fix tsc rss", "rss": "node scripts/generateRss.js", -<<<<<<< HEAD "cache-reset": "rm -rf node_modules/.cache && rm -rf .next && yarn cache clean", "lint-editorconfig": "yarn editorconfig-checker", "textlint-test": "yarn mocha ./textlint/tests/utils && yarn mocha ./textlint/tests/rules", "textlint-docs": "node ./textlint/generators/genTranslateGlossaryDocs.js && git add wiki/translate-glossary.md", - "textlint-lint": "yarn textlint ./src/content --rulesdir ./textlint/rules -f pretty-error && npx --yes eslint@9 -c eslint.config.mjs" -======= + "textlint-lint": "yarn textlint ./src/content --rulesdir ./textlint/rules -f pretty-error && npx --yes eslint@9 -c eslint.config.mjs", "deadlinks": "node scripts/deadLinkChecker.js", "copyright": "node scripts/copyright.js", "test:eslint-local-rules": "yarn --cwd eslint-local-rules test" ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 }, "dependencies": { "@codesandbox/sandpack-react": "2.13.5", @@ -79,24 +66,17 @@ "asyncro": "^3.0.0", "autoprefixer": "^10.4.2", "babel-eslint": "10.x", -<<<<<<< HEAD "babel-plugin-react-compiler": "19.0.0-beta-e552027-20250112", - "editorconfig-checker": "^6.0.1", -======= - "babel-plugin-react-compiler": "^1.0.0", "chalk": "4.1.2", ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 + "editorconfig-checker": "^6.0.1", "eslint": "7.x", "eslint-config-next": "12.0.3", "eslint-config-react-app": "^5.2.1", "eslint-plugin-flowtype": "4.x", "eslint-plugin-import": "2.x", "eslint-plugin-jsx-a11y": "6.x", -<<<<<<< HEAD - "eslint-plugin-mark": "^0.1.0-canary.2", -======= "eslint-plugin-local-rules": "link:eslint-local-rules", ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 + "eslint-plugin-mark": "^0.1.0-canary.2", "eslint-plugin-react": "7.x", "eslint-plugin-react-compiler": "^19.0.0-beta-e552027-20250112", "eslint-plugin-react-hooks": "^0.0.0-experimental-fabef7a6b-20221215", diff --git a/src/components/MDX/Sandpack/NavigationBar.tsx b/src/components/MDX/Sandpack/NavigationBar.tsx index 22790e4ce..184ed2675 100644 --- a/src/components/MDX/Sandpack/NavigationBar.tsx +++ b/src/components/MDX/Sandpack/NavigationBar.tsx @@ -111,14 +111,10 @@ export function NavigationBar({providedFiles}: {providedFiles: Array}) { * * Plus, it should only prompt if there's any file changes */ -<<<<<<< HEAD if ( sandpack.editorState === 'dirty' && confirm('모든 수정 사항이 초기화됩니다. 계속하시겠습니까?') ) { -======= - if (sandpack.editorState === 'dirty' && confirm('Clear all your edits?')) { ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 sandpack.resetAllFiles(); } refresh(); diff --git a/src/sidebarBlog.json b/src/sidebarBlog.json index e28fb957d..3cd33b669 100644 --- a/src/sidebarBlog.json +++ b/src/sidebarBlog.json @@ -33,7 +33,6 @@ "path": "/blog/2025/04/23/react-labs-view-transitions-activity-and-more" }, { -<<<<<<< HEAD "title": "React Compiler RC", "titleForHomepage": "React Compiler RC", "icon": "blog", @@ -42,9 +41,6 @@ }, { "title": "Create React App 지원 종료", -======= - "title": "Sunsetting Create React App", ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 "titleForHomepage": "Sunsetting Create React App", "icon": "blog", "date": "February 14, 2025", diff --git a/src/sidebarHome.json b/src/sidebarHome.json index 1c0b89f58..afdb148c1 100644 --- a/src/sidebarHome.json +++ b/src/sidebarHome.json @@ -84,9 +84,6 @@ }, { "hasSectionHeader": true, -<<<<<<< HEAD - "sectionHeader": "참여하기" -======= "sectionHeader": "REACT COMPILER API" }, { @@ -104,7 +101,6 @@ { "hasSectionHeader": true, "sectionHeader": "GET INVOLVED" ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 }, { "title": "React 커뮤니티", diff --git a/src/sidebarLearn.json b/src/sidebarLearn.json index 6adbbebb2..ebb432e2c 100644 --- a/src/sidebarLearn.json +++ b/src/sidebarLearn.json @@ -66,11 +66,6 @@ "path": "/learn/react-compiler/introduction" }, { -<<<<<<< HEAD - "title": "React 컴파일러", - "path": "/learn/react-compiler", - "canary": true -======= "title": "Installation", "path": "/learn/react-compiler/installation" }, @@ -81,7 +76,6 @@ { "title": "Debugging and Troubleshooting", "path": "/learn/react-compiler/debugging" ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 } ] }, diff --git a/yarn.lock b/yarn.lock index 759ec9722..0c1375c67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2521,12 +2521,12 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-react-compiler@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz#bdf7360a23a4d5ebfca090255da3893efd07425f" - integrity sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw== +babel-plugin-react-compiler@19.0.0-beta-e552027-20250112: + version "19.0.0-beta-e552027-20250112" + resolved "https://registry.yarnpkg.com/babel-plugin-react-compiler/-/babel-plugin-react-compiler-19.0.0-beta-e552027-20250112.tgz#f06f0436420bd09df5abf37337ecd8fb43b0d847" + integrity sha512-pUTT0mAZ4XLewC6bvqVeX015nVRLVultcSQlkzGdC10G6YV6K2h4E7cwGlLAuLKWTj3Z08mTO9uTnPP/opUBsg== dependencies: - "@babel/types" "^7.26.0" + "@babel/types" "^7.19.0" bail@^1.0.0: version "1.0.5" @@ -2733,7 +2733,7 @@ ccount@^2.0.0: resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz" integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== -chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0: +chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2750,22 +2750,11 @@ chalk@^2.0.0, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -<<<<<<< HEAD -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8" integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w== -======= ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 character-entities-html4@^1.0.0: version "1.1.4" resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz" @@ -3883,7 +3872,10 @@ eslint-plugin-jsx-a11y@^6.4.1: safe-regex-test "^1.0.3" string.prototype.includes "^2.0.0" -<<<<<<< HEAD +"eslint-plugin-local-rules@link:eslint-local-rules": + version "0.0.0" + uid "" + eslint-plugin-mark@^0.1.0-canary.2: version "0.1.0-canary.2" resolved "https://registry.yarnpkg.com/eslint-plugin-mark/-/eslint-plugin-mark-0.1.0-canary.2.tgz#b7b05eb6201aab0f3225c99f1c7274c4a0fde3e3" @@ -3893,11 +3885,6 @@ eslint-plugin-mark@^0.1.0-canary.2: "@types/mdast" "^4.0.4" cheerio "^1.0.0" emoji-regex "^10.4.0" -======= -"eslint-plugin-local-rules@link:eslint-local-rules": - version "0.0.0" - uid "" ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 eslint-plugin-react-compiler@^19.0.0-beta-e552027-20250112: version "19.0.0-beta-e552027-20250112" From 046696c23018f8fc14e249b27313919707340165 Mon Sep 17 00:00:00 2001 From: hg-pyun Date: Thu, 16 Oct 2025 10:57:44 +0900 Subject: [PATCH 629/829] fix: type using english var --- src/components/DocsFooter.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/DocsFooter.tsx b/src/components/DocsFooter.tsx index 8d13ec825..158a54971 100644 --- a/src/components/DocsFooter.tsx +++ b/src/components/DocsFooter.tsx @@ -37,7 +37,7 @@ export const DocsPageFooter = memo(
    {prevRoute?.path ? ( @@ -47,7 +47,7 @@ export const DocsPageFooter = memo( {nextRoute?.path ? ( @@ -70,7 +70,7 @@ function FooterLink({ }: { href: string; title: string; - type: '이전' | '다음'; + type: 'Previous' | 'Next'; }) { return (
    From 26bcd440c1e61b4029f698cb028624148f148b89 Mon Sep 17 00:00:00 2001 From: hg-pyun Date: Thu, 16 Oct 2025 12:23:57 +0900 Subject: [PATCH 630/829] Resolve conflicts: accept English content from react.dev sync Resolved all conflict markers in 56 MD files by accepting English content (theirs) over existing Korean translations (ours) as part of PR #1342 sync. - Processed 56 files with 150 total conflicts - Accepted upstream English content from react.dev @ 0d05d9b6 - Fixed orphaned conflict markers and linting errors - Korean translations will be updated in subsequent commits --- ...t-we-have-been-working-on-february-2024.md | 4 - ...labs-view-transitions-activity-and-more.md | 77 ---- src/content/blog/index.md | 12 - src/content/community/conferences.md | 36 +- .../learn/add-react-to-an-existing-project.md | 4 - .../learn/build-a-react-app-from-scratch.md | 4 - src/content/learn/escape-hatches.md | 10 - .../learn/manipulating-the-dom-with-refs.md | 4 - .../learn/removing-effect-dependencies.md | 10 - .../learn/reusing-logic-with-custom-hooks.md | 17 - .../learn/separating-events-from-effects.md | 34 -- .../learn/synchronizing-with-effects.md | 13 - src/content/learn/tutorial-tic-tac-toe.md | 6 - src/content/learn/typescript.md | 45 -- .../learn/you-might-not-need-an-effect.md | 8 - .../reference/react-dom/client/createRoot.md | 4 - .../reference/react-dom/client/index.md | 4 - .../reference/react-dom/components/common.md | 4 - .../reference/react-dom/components/form.md | 16 - .../reference/react-dom/components/index.md | 18 - .../reference/react-dom/components/input.md | 4 - .../reference/react-dom/components/link.md | 4 - .../reference/react-dom/components/meta.md | 4 - .../reference/react-dom/components/option.md | 4 - .../react-dom/components/progress.md | 4 - .../reference/react-dom/components/script.md | 4 - .../reference/react-dom/components/select.md | 4 - .../reference/react-dom/components/style.md | 8 - .../react-dom/components/textarea.md | 4 - .../reference/react-dom/components/title.md | 4 - .../reference/react-dom/createPortal.md | 4 - .../reference/react-dom/server/index.md | 19 - .../reference/react-dom/static/index.md | 13 - .../reference/react-dom/static/prerender.md | 7 - .../react-dom/static/prerenderToNodeStream.md | 7 - src/content/reference/react/Activity.md | 405 ------------------ src/content/reference/react/Fragment.md | 8 - src/content/reference/react/Profiler.md | 8 - src/content/reference/react/StrictMode.md | 90 ---- src/content/reference/react/ViewTransition.md | 25 -- .../reference/react/addTransitionType.md | 28 -- src/content/reference/react/cache.md | 63 --- .../reference/react/captureOwnerStack.md | 4 - src/content/reference/react/forwardRef.md | 4 - src/content/reference/react/index.md | 4 - src/content/reference/react/memo.md | 9 - src/content/reference/react/use.md | 4 - src/content/reference/react/useCallback.md | 15 - .../reference/react/useDeferredValue.md | 8 - src/content/reference/react/useEffect.md | 27 -- .../reference/react/useInsertionEffect.md | 4 - .../reference/react/useLayoutEffect.md | 4 - src/content/reference/react/useMemo.md | 4 - src/content/reference/react/useTransition.md | 12 - src/content/reference/rsc/server-functions.md | 8 - src/content/reference/rsc/use-server.md | 4 - src/content/versions.md | 10 - 57 files changed, 1 insertion(+), 1171 deletions(-) diff --git a/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md b/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md index 5a956cf46..64312dfe1 100644 --- a/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md +++ b/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md @@ -107,11 +107,7 @@ Activity는 여전히 연구 중이며, 라이브러리 개발자에게 노출 이번 업데이트 외에도 우리 팀은 컨퍼런스에서 발표하고 팟캐스트 출연을 통해 우리의 작업에 관해 이야기를 나누고 질문에 답변했습니다. -<<<<<<< HEAD -- [Sathya Gunasekaran](/community/team#sathya-gunasekaran)은 [React India](https://www.youtube.com/watch?v=kjOacmVsLSE) 컨퍼런스에서 React 컴파일러에 관해 이야기했습니다. -======= - [Sathya Gunasekaran](https://github.com/gsathya) spoke about the React Compiler at the [React India](https://www.youtube.com/watch?v=kjOacmVsLSE) conference ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 - [Dan Abramov](/community/team#dan-abramov)은 [RemixConf](https://www.youtube.com/watch?v=zMf_xeGPn6s)에서 "다른 차원의 React"를 주제로 강연했습니다. 이곳에서 React 서버 컴포넌트와 액션을 어떻게 만들었는지에 관한 대안적인 역사를 탐구했습니다. diff --git a/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md b/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md index 15157d51f..e8b3b22e1 100644 --- a/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md +++ b/src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md @@ -18,17 +18,9 @@ React Labs 게시글에는 활발히 연구 개발 중인 프로젝트에 대한 -<<<<<<< HEAD -React Conf 2025가 네바다주 헨더슨에서 10월 7-8일에 개최될 예정입니다! - -이번 게시글에서 다루는 기능들에 대한 발표를 준비해주실 연사분들을 찾고 있습니다. ReactConf에서 발표에 관심이 있으시다면 [여기에서 지원해주세요](https://forms.reform.app/react-conf/call-for-speakers/) (발표 제안서 제출은 필요하지 않습니다). - -티켓, 무료 스트리밍, 후원 등에 대한 더 많은 정보는 [React Conf 웹사이트](https://conf.react.dev)를 참고하세요. -======= React Conf 2025 is scheduled for October 7–8 in Henderson, Nevada! Watch the livestream on [the React Conf website](https://conf.react.dev). ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 @@ -74,11 +66,7 @@ React View Transitions는 앱의 UI 전환에 애니메이션을 더 쉽게 추 ``` -<<<<<<< HEAD -이 새로운 컴포넌트를 사용하면 애니메이션이 활성화될 때 무엇을 애니메이션할지 선언적으로 정의할 수 있습니다. -======= This new component lets you declaratively define "what" to animate when an animation is activated. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 View Transition에 대한 다음 세 가지 트리거 중 하나를 사용해서 "언제" 애니메이션할지 정의할 수 있습니다. @@ -111,15 +99,9 @@ const deferred = useDeferredValue(value); `startTransition`, `useDeferredValue`, 또는 `Suspense` 폴백이 콘텐츠로 전환되는 것과 같은 애니메이션 트리거로 인해 DOM이 업데이트되면, React는 [선언적 휴리스틱](/reference/react/ViewTransition#viewtransition)을 사용해서 애니메이션을 위해 활성화할 `` 컴포넌트를 자동으로 결정합니다. 그러면 브라우저가 CSS에서 정의된 애니메이션을 실행합니다. -<<<<<<< HEAD -브라우저의 View Transition API에 익숙하고 React가 이를 어떻게 지원하는지 알고 싶다면, 문서의 [How does `` Work](/reference/react/ViewTransition#how-does-viewtransition-work)를 확인해보세요. - -이번 게시글에서는 View Transitions를 사용하는 몇 가지 예시를 살펴보겠습니다. -======= If you're familiar with the browser's View Transition API and want to know how React supports it, check out [How does `` Work](/reference/react/ViewTransition#how-does-viewtransition-work) in the docs. In this post, let's take a look at a few examples of how to use View Transitions. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 다음과 같은 상호작용을 애니메이션하지 않는 앱부터 시작하겠습니다. - 비디오를 클릭해서 세부 정보를 봅니다. @@ -1312,11 +1294,7 @@ function navigate(url) { `url`이 변경되면, ``과 새로운 라우트가 렌더링됩니다. ``이 `startTransition` 내부에서 업데이트되었으므로, ``이 애니메이션을 위해 활성화됩니다. -<<<<<<< HEAD -기본적으로, View Transitions는 브라우저 기본 크로스 페이드 애니메이션을 포함합니다. 이를 예시에 추가하면, 이제 페이지 간 네비게이션할 때마다 크로스 페이드가 적용됩니다. -======= By default, View Transitions include the browser default cross-fade animation. Adding this to our example, we now have a cross-fade whenever we navigate between pages: ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 @@ -2479,11 +2457,7 @@ root.render( -<<<<<<< HEAD -라우터가 이미 `startTransition`을 사용해서 라우트를 업데이트하고 있기 때문에, ``을 한 줄 추가하는 것만으로 기본 크로스 페이드 애니메이션이 활성화됩니다. -======= Since our router already updates the route using `startTransition`, this one line change to add `` activates with the default cross-fade animation. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 어떻게 동작하는지 궁금하다면 [How does `` work?](/reference/react/ViewTransition#how-does-viewtransition-work) 문서를 참고하세요. @@ -2491,11 +2465,7 @@ Since our router already updates the route using `startTransition`, this one lin #### `` 애니메이션 건너뛰기 {/*opting-out-of-viewtransition-animations*/} -<<<<<<< HEAD -이 예시에서 단순화를 위해 앱의 루트를 ``으로 감싸고 있지만, 이렇게 하면 앱 내의 모든 트랜지션이 애니메이션 되어 예상치 못한 애니메이션이 발생할 수 있습니다. -======= In this example, we're wrapping the root of the app in `` for simplicity, but this means that all transitions in the app will be animated, which can lead to unexpected animations. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 이를 해결하기 위해 각 페이지에서 자체적으로 애니메이션을 제어할 수 있도록 라우트 자식 요소를 `"none"`으로 감싸고 있습니다. @@ -2506,11 +2476,7 @@ In this example, we're wrapping the root of the app in `` for si ``` -<<<<<<< HEAD -실제로 네비게이션은 "enter"와 "exit" Props 또는 Transition Types를 사용해서 처리하는 것이 좋습니다. -======= In practice, navigations should be done via "enter" and "exit" props, or by using Transition Types. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 @@ -2528,11 +2494,7 @@ In practice, navigations should be done via "enter" and "exit" props, or by usin ``` -<<<<<<< HEAD -그리고 [View Transition 클래스](/reference/react/ViewTransition#view-transition-classes)를 사용하여 CSS에서 `slow-fade`를 정의합니다. -======= And define `slow-fade` in CSS using [view transition classes](/reference/react/ViewTransition#view-transition-class): ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ```css ::view-transition-old(.slow-fade) { @@ -6250,11 +6212,7 @@ root.render( ### Suspense Boundaries 애니메이팅 {/*animating-suspense-boundaries*/} -<<<<<<< HEAD -Suspense 역시 View Transition을 활성화합니다. -======= Suspense will also activate View Transitions. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 콘텐츠에 대한 폴백 애니메이션을 적용하려면 `Suspense`를 ``으로 래핑하면 됩니다. @@ -11506,9 +11464,6 @@ _View Transition을 구축한 배경에 대한 자세한 내용은 다음을 참 ## Activity {/*activity*/} -<<<<<<< HEAD -[지난](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022#offscreen) [업데이트](/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024#offscreen-renamed-to-activity)에서, 컴포넌트를 시각적으로 숨기고 우선순위를 지정 해제할 수 있는 API를 연구 중이며, CSS로 마운트 해제하거나 숨기는 것에 비해 성능 비용을 줄이면서 UI 상태를 유지할 수 있다고 공유한 바 있습니다. -======= **`` is now available in React’s Canary channel.** @@ -11518,7 +11473,6 @@ _View Transition을 구축한 배경에 대한 자세한 내용은 다음을 참 In [past](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022#offscreen) [updates](/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024#offscreen-renamed-to-activity), we shared that we were researching an API to allow components to be visually hidden and deprioritized, preserving UI state with reduced performance costs relative to unmounting or hiding with CSS. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 이제 API와 그 작동 방식을 공유할 준비가 되었고, 실험적인 React 버전에서 테스트를 시작할 수 있습니다. @@ -14265,15 +14219,6 @@ Activity에서 고려 중인 또 다른 모드는 메모리가 너무 많이 사 # 개발 중인 기능 {/*features-in-development*/} -<<<<<<< HEAD -저희는 아래의 일반적인 문제들을 해결하는 데 도움이 되는 기능들도 개발하고 있습니다. - -가능한 솔루션을 반복 개발하면서, 저희가 진행하고 있는 PR을 기반으로 테스트 중인 잠재적 API들이 공유되는 것을 보실 수 있습니다. 다양한 아이디어를 시도하면서, 시도해본 후 다른 솔루션을 자주 변경하거나 제거한다는 점을 기억해 주세요. - -저희가 작업하고 있는 솔루션을 너무 일찍 공유하면, 커뮤니티에 혼란과 혼동을 일으킬 수 있습니다. 투명성과 혼란 제한 사이의 균형을 맞추기 위해, 염두에 두고 있는 특정 솔루션을 공유하지 않고 현재 솔루션을 개발하고 있는 문제들을 공유합니다. - -이러한 기능들이 진전을 보이면, 여러분이 시도해볼 수 있도록 문서와 함께 블로그에서 발표하겠습니다. -======= We're also developing features to help solve the common problems below. As we iterate on possible solutions, you may see some potential APIs we're testing being shared based on the PRs we are landing. Please keep in mind that as we try different ideas, we often change or remove different solutions after trying them out. @@ -14281,7 +14226,6 @@ As we iterate on possible solutions, you may see some potential APIs we're testi When the solutions we're working on are shared too early, it can create churn and confusion in the community. To balance being transparent and limiting confusion, we're sharing the problems we're currently developing solutions for, without sharing a particular solution we have in mind. As these features progress, we'll announce them on the blog with docs included so you can try them out. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ## React Performance Tracks {/*react-performance-tracks*/} @@ -14314,11 +14258,7 @@ hooks를 출시했을 때, 저희는 세 가지 동기가 있었습니다: - **생명주기가 아닌 함수의 관점에서 사고**: hooks는 생명주기 메서드를 기반으로 한 분할을 강제하는 것이 아니라 관련된 부분(구독 설정이나 데이터 가져오기 등)을 기반으로 하나의 컴포넌트를 더 작은 함수로 분할할 수 있게 해주었습니다. - **사전 컴파일 지원**: hooks는 생명주기 메서드로 인한 의도하지 않은 최적화 해제 문제와 클래스의 제약사항을 줄이면서 사전 컴파일을 지원하도록 설계되었습니다. -<<<<<<< HEAD -출시 이후 hooks는 *컴포넌트 간 코드 공유*에서 성공적이었습니다. Hooks는 이제 컴포넌트 간 로직을 공유하는 선호되는 방법이 되었고, 렌더링 props와 고차 컴포넌트의 사용 사례는 줄어들었습니다. Hooks는 또한 클래스 컴포넌트로는 불가능했던 Fast Refresh와 같은 기능을 지원하는 데도 성공적이었습니다. -======= Since their release, hooks have been successful at *sharing code between components*. Hooks are now the favored way to share logic between components, and there are less use cases for render props and higher order components. Hooks have also been successful at supporting features like Fast Refresh that were not possible with class components. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ### Effects는 어려울 수 있습니다 {/*effects-can-be-hard*/} @@ -14359,31 +14299,18 @@ useEffect(() => { return () => { connection.disconnect(); }; -<<<<<<< HEAD -}); // 컴파일러가 의존성을 삽입했습니다. -``` - -이 코드를 사용하면, React Compiler가 의존성을 추론하고 자동으로 삽입하므로 보거나 작성할 필요가 없습니다. [IDE 확장 프로그램](#compiler-ide-extension)과 [`useEffectEvent`](/reference/react/experimental_useEffectEvent) 같은 기능을 통해, 디버깅이 필요한 시점이나 의존성을 제거하여 최적화할 때 Compiler가 삽입한 것을 보여주는 CodeLens를 제공할 수 있습니다. 이는 언제든지 실행되어 컴포넌트나 hook의 상태를 다른 것과 동기화할 수 있는 Effects를 작성하는 올바른 멘탈 모델을 강화하는 데 도움이 됩니다. - -저희의 희망은 의존성을 자동으로 삽입하는 것이 작성하기 더 쉬울 뿐만 아니라, 컴포넌트 생명주기가 아닌 Effect가 하는 일의 관점에서 생각하도록 강제함으로써 이해하기도 더 쉽게 만든다는 것입니다. -======= }); // compiler inserted dependencies. ``` With this code, the React Compiler can infer the dependencies for you and insert them automatically so you don't need to see or write them. With features like [the IDE extension](#compiler-ide-extension) and [`useEffectEvent`](/reference/react/useEffectEvent), we can provide a CodeLens to show you what the Compiler inserted for times you need to debug, or to optimize by removing a dependency. This helps reinforce the correct mental model for writing Effects, which can run at any time to synchronize your component or hook's state with something else. Our hope is that automatically inserting dependencies is not only easier to write, but that it also makes them easier to understand by forcing you to think in terms of what the Effect does, and not in component lifecycles. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 --- ## Compiler IDE Extension {/*compiler-ide-extension*/} -<<<<<<< HEAD -이번 주 초에 [React Compiler 릴리스 후보를 공유했으며](/blog/2025/04/21/react-compiler-rc), 앞으로 몇 달 안에 컴파일러의 첫 번째 SemVer 안정 버전을 출시하기 위해 작업하고 있습니다. -======= Later in 2025 [we shared](/blog/2025/10/07/react-compiler-1) the first stable release of React Compiler, and we're continuing to invest in shipping more improvements. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 또한 React Compiler를 사용해서 코드 이해와 디버깅을 향상시킬 수 있는 정보를 제공하는 방법을 탐구하기 시작했습니다. 저희가 탐구하기 시작한 아이디어 중 하나는 [Lauren Tan의 React Conf 발표](https://conf2024.react.dev/talks/5)에서 사용된 확장 프로그램과 유사한, React Compiler를 기반으로 하는 새로운 실험적 LSP 기반 React IDE 확장 프로그램입니다. @@ -14405,11 +14332,7 @@ Fragment refs는 아직 연구 중입니다. 최종 API가 완성에 가까워 ## Gesture Animations {/*gesture-animations*/} -<<<<<<< HEAD -저희는 또한 메뉴를 열기 위한 스와이프나 사진 캐러셀을 스크롤하는 것과 같은 제스처 애니메이션을 지원하기 위해 View Transitions를 향상시키는 방법을 연구하고 있습니다. -======= We're also researching ways to enhance View Transitions to support gesture animations such as swiping to open a menu, or scroll through a photo carousel. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 제스처는 몇 가지 이유로 새로운 도전을 제시합니다: diff --git a/src/content/blog/index.md b/src/content/blog/index.md index dc7ee1631..1d86f3125 100644 --- a/src/content/blog/index.md +++ b/src/content/blog/index.md @@ -10,17 +10,6 @@ title: React 블로그
    -<<<<<<< HEAD - - -React Labs 게시글에서는 현재 연구 개발 중인 프로젝트에 대한 글을 작성합니다. 이번 포스팅에서는 지금 바로 사용해 볼 수 있는 두 가지 새로운 실험적 기능을 공유하고, 현재 작업 중인 다른 영역에 대해서도 공유하고자 합니다. - - - - - -컴파일러의 첫 번째 릴리즈 후보(Release Candidate, RC)를 공개합니다. -======= We're releasing the compiler's first stable release today, plus linting and tooling improvements to make adoption easier. @@ -42,7 +31,6 @@ React 19.2 adds new features like Activity, React Performance Tracks, useEffectE In React Labs posts, we write about projects in active research and development. In this post, we're sharing two new experimental features that are ready to try today, and sharing other areas we're working on now ... ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 diff --git a/src/content/community/conferences.md b/src/content/community/conferences.md index c53dd7d17..8ccb4dcfc 100644 --- a/src/content/community/conferences.md +++ b/src/content/community/conferences.md @@ -9,40 +9,6 @@ React.js 관련 컨퍼런스를 알고 계신가요? 이곳에 추가해주세 ## 예정 컨퍼런스 {/*upcoming-conferences*/} -<<<<<<< HEAD -### CityJS London 2025 {/*cityjs-london*/} - -April 23 - 25, 2025. In-person in London, UK - -[Website](https://london.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social) - -### App.js Conf 2025 {/*appjs-conf-2025*/} -May 28 - 30, 2025. In-person in Kraków, Poland + remote - -[Website](https://appjs.co) - [Twitter](https://twitter.com/appjsconf) - -### CityJS Athens 2025 {/*cityjs-athens*/} -May 27 - 31, 2025. In-person in Athens, Greece - -[Website](https://athens.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social) - -### React Norway 2025 {/*react-norway-2025*/} -June 13, 2025. In-person in Oslo, Norway + remote (virtual event) - -[Website](https://reactnorway.com/) - [Twitter](https://x.com/ReactNorway) - -### React Summit 2025 {/*react-summit-2025*/} -June 13 - 17, 2025. In-person in Amsterdam, Netherlands + remote (hybrid event) - -[Website](https://reactsummit.com/) - [Twitter](https://x.com/reactsummit) - -### React Nexus 2025 {/*react-nexus-2025*/} -July 03 - 05, 2025. In-person in Bangalore, India - -[Website](https://reactnexus.com/) - [Twitter](https://x.com/ReactNexus) - [Bluesky](https://bsky.app/profile/reactnexus.com) - [Linkedin](https://www.linkedin.com/company/react-nexus) - [YouTube](https://www.youtube.com/reactify_in) - -======= ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ### React Universe Conf 2025 {/*react-universe-conf-2025*/} September 2-4, 2025. Wrocław, Poland. @@ -70,7 +36,7 @@ October 31 - November 01, 2025. In-person in Goa, India (hybrid event) + Oct 15 ### CityJS New Delhi 2025 {/*cityjs-newdelhi*/} -November 6-7, 2025. In-person in New Delhi, India +November 6-7, 2025. In-person in New Delhi, India [Website](https://india.cityjsconf.org/) - [Twitter](https://x.com/cityjsconf) - [Bluesky](https://bsky.app/profile/cityjsconf.bsky.social) diff --git a/src/content/learn/add-react-to-an-existing-project.md b/src/content/learn/add-react-to-an-existing-project.md index b67447c18..aeefb5459 100644 --- a/src/content/learn/add-react-to-an-existing-project.md +++ b/src/content/learn/add-react-to-an-existing-project.md @@ -24,11 +24,7 @@ title: 기존 프로젝트에 React 추가하기 2. 사용하는 프레임워크 설정에서 **`/some-app` 을 *기본 경로**Base Path*로 명시하세요**. (이때, [Next.js](https://nextjs.org/docs/app/api-reference/config/next-config-js/basePath), [Gatsby](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/path-prefix/)를 사용하세요!) 3. **서버 또는 프록시를 구성**하여 `/some-app/` 하위의 모든 요청이 React 앱에서 처리되도록 하세요. -<<<<<<< HEAD -이는 앱의 React 부분이 이러한 프레임워크에 내장된 [최고의 사례들Best Practices로부터 이점을 얻을 수 있습니다.](/learn/start-a-new-react-project#can-i-use-react-without-a-framework) -======= This ensures the React part of your app can [benefit from the best practices](/learn/build-a-react-app-from-scratch#consider-using-a-framework) baked into those frameworks. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 많은 React 기반의 프레임워크는 풀스택이며 React 앱이 서버를 활용할 수 있도록 합니다. 그러나 서버에서 자바스크립트를 실행할 수 없거나 실행하고 싶지 않은 경우에도 동일한 접근방식을 사용할 수 있습니다. 이러한 경우에는 HTML/CSS/JS 내보내기(Next.js의 경우 [`next export` output](https://nextjs.org/docs/advanced-features/static-html-export), Gatsby의 경우 기본값)를 `/some-app/`에서 대신 제공하세요. diff --git a/src/content/learn/build-a-react-app-from-scratch.md b/src/content/learn/build-a-react-app-from-scratch.md index 4ecd051ea..4a0d19f57 100644 --- a/src/content/learn/build-a-react-app-from-scratch.md +++ b/src/content/learn/build-a-react-app-from-scratch.md @@ -122,11 +122,7 @@ GraphQL API에서 데이터를 가져온다면 다음을 사용할 것을 제안 ### 애플리케이션 성능 향상 {/*improving-application-performance*/} -<<<<<<< HEAD -선택한 빌드 도구가 단일 페이지 앱(SPA)만 지원하므로, 서버 측 렌더링(SSR), 정적 사이트 생성(SSG), 그리고/또는 React 서버 컴포넌트(RSC)와 같은 다른 [렌더링 패턴](https://www.patterns.dev/vanilla/rendering-patterns)을 구현해야 합니다. 처음에는 이러한 기능이 필요 없더라도, 나중에는 일부 라우트가 SSR, SSG 또는 RSC의 이점을 얻을 수 있습니다. -======= Since the build tool you select only supports 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. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 * **단일 페이지 앱 (SPA)** 은 단일 HTML 페이지를 로드하고 사용자가 앱과 상호작용을 할 때 페이지를 동적으로 업데이트합니다. SPA는 시작하기는 더 쉽지만, 초기 로드 시간이 느릴 수 있습니다. SPA는 대부분의 빌드 도구에서 기본 아키텍처입니다. diff --git a/src/content/learn/escape-hatches.md b/src/content/learn/escape-hatches.md index 40ec851e3..e2ed70054 100644 --- a/src/content/learn/escape-hatches.md +++ b/src/content/learn/escape-hatches.md @@ -312,17 +312,7 @@ Effect의 생명주기가 컴포넌트와 어떻게 다른지를 배우려면 - -이 섹션에서는 아직 안정된 버전의 React로 **출시하지 않은 실험적인 API**에 대해 설명합니다. - - - -이벤트 핸들러는 같은 상호작용을 반복하는 경우에만 다시 실행됩니다. Effect는 이벤트 핸들러와 달리 Prop이나 State 변수 등 읽은 값이 마지막 렌더링 때와 다르면 다시 동기화합니다. 때로는 두 동작이 섞여서 어떤 값에는 반응해 다시 실행되지만, 다른 값에는 그러지 않는 Effect를 원할 때도 있습니다. 이 페이지에서 그 방법을 알려드리겠습니다. -======= 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. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 Effect 내의 모든 코드는 반응형이며, 읽은 반응형 값이 다시 렌더링되는 것으로 인해 변경되면 다시 실행됩니다. 예를 들어 다음의 Effect는 `roomId` 또는 `theme`이 변경되면 채팅에 다시 연결됩니다. diff --git a/src/content/learn/manipulating-the-dom-with-refs.md b/src/content/learn/manipulating-the-dom-with-refs.md index e7e3bc880..0c5437b10 100644 --- a/src/content/learn/manipulating-the-dom-with-refs.md +++ b/src/content/learn/manipulating-the-dom-with-refs.md @@ -211,11 +211,7 @@ li { 이 문제를 해결하는 한 방법은 부모 요소에서 단일 ref를 얻고, [`querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll)과 같은 DOM 조작 메서드를 사용하여 그 안에서 개별 자식 노드를 "찾는" 것입니다. 하지만 이는 다루기가 힘들며 DOM 구조가 바뀌는 경우 작동하지 않을 수 있습니다. -<<<<<<< HEAD -또 다른 해결책은 **`ref` 어트리뷰트에 함수를 전달하는 것**입니다. 이것을 [`ref` 콜백](/reference/react-dom/components/common#ref-callback)이라고 합니다. React는 ref를 설정할 때 DOM 노드와 함께 ref 콜백을 호출하며, ref를 지울 때에는 null을 전달합니다. 이를 통해 자체 배열이나 [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)을 유지하고, 인덱스나 특정 ID를 사용하여 어떤 ref에든 접근할 수 있습니다. -======= Another solution is to **pass a function to the `ref` attribute.** This is called a [`ref` callback.](/reference/react-dom/components/common#ref-callback) React will call your ref callback with the DOM node when it's time to set the ref, and call the cleanup function returned from the callback when it's time to clear it. This lets you maintain your own array or a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), and access any ref by its index or some kind of ID. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 아래 예시는 긴 목록에서 특정 노드에 스크롤 하기 위해 앞에서 말한 접근법을 사용합니다. diff --git a/src/content/learn/removing-effect-dependencies.md b/src/content/learn/removing-effect-dependencies.md index 34cba31c5..5a28eeb04 100644 --- a/src/content/learn/removing-effect-dependencies.md +++ b/src/content/learn/removing-effect-dependencies.md @@ -610,17 +610,7 @@ function ChatRoom({ roomId }) { ### 값의 변경에 '반응'하지 않고 값을 읽고 싶으신가요? {/*do-you-want-to-read-a-value-without-reacting-to-its-changes*/} -<<<<<<< HEAD - - -이 섹션에서는 아직 안정된 버전의 React로 **출시되지 않은 실험적인 API**에 대해 설명합니다. - - - -사용자가 새 메시지를 수신할 때 `isMuted`가 `true`가 아닌 경우 사운드를 재생하고 싶다고 가정해 보겠습니다. -======= Suppose that you want to play a sound when the user receives a new message unless `isMuted` is `true`: ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ```js {3,10-12} function ChatRoom({ roomId }) { diff --git a/src/content/learn/reusing-logic-with-custom-hooks.md b/src/content/learn/reusing-logic-with-custom-hooks.md index 07699649a..7b1e8f177 100644 --- a/src/content/learn/reusing-logic-with-custom-hooks.md +++ b/src/content/learn/reusing-logic-with-custom-hooks.md @@ -836,17 +836,7 @@ export default function ChatRoom({ roomId }) { ### 커스텀 Hook에 이벤트 핸들러 넘겨주기 {/*passing-event-handlers-to-custom-hooks*/} -<<<<<<< HEAD - - -이 섹션은 React의 안정화 버전에 **아직 반영되지 않은 실험적인 API**를 설명하고 있습니다. - - - -만약 `useChatRoom`을 더 많은 컴포넌트에서 사용하길 원한다면, 컴포넌트가 본인의 동작을 커스텀할 수 있길 바랄 것입니다. 예를 들어, 최근 메시지가 도착했을 때 무엇을 해야 하는지에 대한 로직이 Hook 안에 하드코딩 되어있다고 해봅시다. -======= As you start using `useChatRoom` in more components, you might want to let components customize its behavior. For example, currently, the logic for what to do when a message arrives is hardcoded inside the Hook: ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ```js {9-11} export function useChatRoom({ serverUrl, roomId }) { @@ -1422,12 +1412,6 @@ function SaveButton() { #### React가 데이터 패칭을 위한 내부 해결책을 제공할까요? {/*will-react-provide-any-built-in-solution-for-data-fetching*/} -<<<<<<< HEAD -아직 세부적인 사항을 작업 중이지만, 앞으로는 이와 같이 데이터 가져오도록 작성하게 될 것으로 예상합니다. - -```js {1,4,6} -import { use } from 'react'; // 아직 사용 불가능합니다! -======= Today, with the [`use`](/reference/react/use#streaming-data-from-server-to-client) API, data can be read in render by passing a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to `use`: ```js {1,4,11} @@ -1451,7 +1435,6 @@ We're still working out the details, but we expect that in the future, you'll wr ```js {1,4,6} import { use } from 'react'; ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 function ShippingForm({ country }) { const cities = use(fetch(`/api/cities?country=${country}`)); diff --git a/src/content/learn/separating-events-from-effects.md b/src/content/learn/separating-events-from-effects.md index 6c3c89bee..003bd696d 100644 --- a/src/content/learn/separating-events-from-effects.md +++ b/src/content/learn/separating-events-from-effects.md @@ -400,17 +400,7 @@ label { display: block; margin-top: 10px; } ### Effect 이벤트 선언하기 {/*declaring-an-effect-event*/} -<<<<<<< HEAD - - -이 단락에서는 **아직 안정된 버전의 React로 출시되지 않은 실험적인 API**를 설명합니다. - - - -이 비반응형 로직을 Effect에서 추출하려면 [`useEffectEvent`](/reference/react/experimental_useEffectEvent)라는 특수한 Hook을 사용하세요. -======= Use a special Hook called [`useEffectEvent`](/reference/react/useEffectEvent) to extract this non-reactive logic out of your Effect: ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ```js {1,4-6} import { useEffect, useEffectEvent } from 'react'; @@ -582,17 +572,7 @@ Effect 이벤트가 이벤트 핸들러와 아주 비슷하다고 생각할 수 ### Effect 이벤트로 최근 props와 state 읽기 {/*reading-latest-props-and-state-with-effect-events*/} -<<<<<<< HEAD - - -이 단락에서는 **아직 안정된 버전의 React로 출시되지 않은 실험적인 API**를 설명합니다. - - - -Effect 이벤트는 의존성 린터를 억제하고 싶었을 많은 패턴을 수정하게 합니다. -======= Effect Events let you fix many patterns where you might be tempted to suppress the dependency linter. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 예를 들어 페이지 방문을 기록하기 위한 Effect가 있다고 해보겠습니다. @@ -733,11 +713,7 @@ function Page({ url }) { } ``` -<<<<<<< HEAD -`useEffectEvent`가 React의 안정적인 기능이 되면 **린터를 절대로 억제하지 않을 것**을 추천합니다. -======= We recommend **never suppressing the linter**. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 규칙을 억제하는 것의 첫 번째 단점은 코드에 추가한 새로운 반응형 의존성에 Effect가 "반응"해야 할 때 React가 더 이상 경고하지 않는다는 것입니다. 이전 예시에서는 React가 의존성에 `url`을 추가하라고 상기시켜 주었기 *때문에* 그렇게 했습니다. 린터를 억제하면 해당 Effect에 대한 향후 편집에 대해 이러한 알림을 더 이상 받지 않게 됩니다. 이는 버그로 이어집니다. @@ -874,17 +850,7 @@ body { ### Effect 이벤트의 한계 {/*limitations-of-effect-events*/} -<<<<<<< HEAD - - -이 단락에서는 **아직 안정된 버전의 React로 출시되지 않은 실험적인 API**를 설명합니다. - - - -Effect 이벤트는 사용할 수 있는 방법이 매우 제한적입니다. -======= Effect Events are very limited in how you can use them: ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 * **Effect 내부에서만 호출하세요.** * **절대로 다른 컴포넌트나 Hook에 전달하지 마세요.** diff --git a/src/content/learn/synchronizing-with-effects.md b/src/content/learn/synchronizing-with-effects.md index 73aaf0dbc..738ce0e0a 100644 --- a/src/content/learn/synchronizing-with-effects.md +++ b/src/content/learn/synchronizing-with-effects.md @@ -617,11 +617,7 @@ Effect가 개발 모드에서 두 번 실행되는 것을 막으려다 흔히 이렇게 하면 개발 모드에서 `"✅ 연결 중..."`이 한 번만 보이지만 버그가 수정된 건 아닙니다. -<<<<<<< HEAD -사용자가 다른 곳에 가더라도 연결이 끊어지지 않고 사용자가 다시 돌아왔을 때 새로운 연결이 생성됩니다. 사용자가 앱을 탐색하면 버그가 수정되기 전처럼 연결이 계속 쌓이게 됩니다. -======= When the user navigates away, the connection still isn't closed and when they navigate back, a new connection is created. As the user navigates across the app, the connections would keep piling up, the same as it would before the "fix". ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 버그를 수정하기 위해선 Effect를 단순히 한 번만 실행되도록 만드는 것으로는 부족합니다. Effect는 위에 있는 예시가 연결을 클린업 한것처럼 다시 마운트된 이후에도 제대로 동작해야 합니다. @@ -736,13 +732,8 @@ Effect 안에서 `fetch` 호출을 작성하는 것은 [데이터를 가져오 이 단점 목록은 React에만 해당되는 것은 아닙니다. 어떤 라이브러리에서든 마운트 시에 데이터를 가져온다면 비슷한 단점이 존재합니다. 마운트 시에 데이터를 페칭하는 것도 라우팅과 마찬가지로 잘 수행하기 어려운 작업이므로 다음 접근 방식을 권장합니다. -<<<<<<< HEAD -- **[프레임워크](/learn/start-a-new-react-project#production-grade-react-frameworks)를 사용하는 경우 해당 프레임워크의 내장 데이터 페칭 메커니즘을 사용하세요.** 현대적인 React 프레임워크에는 위의 단점을 겪지 않는 효율적이고 통합적인 데이터 페칭 메커니즘이 포함되어 있습니다. -- **그렇지 않은 경우 클라이언트 측 캐시를 사용하거나 구축하는 것을 고려하세요.** 인기 있는 오픈 소스 솔루션으로는 [React Query](https://tanstack.com/query/latest), [useSWR](https://swr.vercel.app/) 및 [React Router 6.4+](https://beta.reactrouter.com/en/main/start/overview)이 있습니다. 직접 솔루션을 구축할 수도 있으며 이 경우 Effect를 내부적으로 사용하면서 요청 중복을 제거하고 응답을 캐시하고 네트워크 폭포를 피하는 로직을 추가할 것입니다. (데이터를 사전에 로드하거나 데이터 요구 사항을 라우트) -======= - **If you use a [framework](/learn/start-a-new-react-project#full-stack-frameworks), use its built-in data fetching mechanism.** Modern React frameworks have integrated data fetching mechanisms that are efficient and don't suffer from the above pitfalls. - **Otherwise, consider using or building a client-side cache.** Popular open source solutions include [React Query](https://tanstack.com/query/latest), [useSWR](https://swr.vercel.app/), and [React Router 6.4+.](https://beta.reactrouter.com/en/main/start/overview) You can build your own solution too, in which case you would use Effects under the hood, but add logic for deduplicating requests, caching responses, and avoiding network waterfalls (by preloading data or hoisting data requirements to routes). ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 이러한 접근 방식 중 어느 것도 적합하지 않은 경우, Effect 내에서 데이터를 직접 가져오는 것을 계속하셔도 됩니다. @@ -1013,11 +1004,7 @@ import { useEffect, useRef } from 'react'; export default function MyInput({ value, onChange }) { const ref = useRef(null); -<<<<<<< HEAD - // TODO: 작동하지 않는다. 고쳐야함 -======= // TODO: This doesn't quite work. Fix it. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 // ref.current.focus() return ( diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index f640c072e..682e600f1 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -288,15 +288,9 @@ CodeSandBox에는 세 가지 주요 구역이 있습니다. ![CodeSandBox의 초기 코드](../images/tutorial/react-starter-code-codesandbox.png) -<<<<<<< HEAD -1. `App.js`, `index.js`, `style.css` 와 같은 파일 목록과 `public` 폴더가 있는 _파일_ 구역 -1. 선택한 파일의 소스 코드를 볼 수 있는 _코드 편집기_ -1. 작성한 코드가 어떻게 보이는지 확인할 수 있는 _브라우저_ 구역 -======= 1. The _Files_ section with a list of files like `App.js`, `index.js`, `styles.css` in `src` folder and a folder called `public` 1. The _code editor_ where you'll see the source code of your selected file 1. The _browser_ section where you'll see how the code you've written will be displayed ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 _파일_ 구역에서 `App.js` 파일을 선택하세요. _코드 편집기_ 에서 해당 파일의 내용이 있어야 합니다. diff --git a/src/content/learn/typescript.md b/src/content/learn/typescript.md index dc8d79220..f6e7797be 100644 --- a/src/content/learn/typescript.md +++ b/src/content/learn/typescript.md @@ -11,27 +11,16 @@ TypeScript는 JavaScript 코드 베이스에 타입 정의를 추가하는 데 -<<<<<<< HEAD -* [React 컴포넌트가 있는 TypeScript](/learn/typescript#typescript-with-react-components) -* [Hooks 타이핑 예시](/learn/typescript#example-hooks) -* [`@types/react`의 일반적인 타입](/learn/typescript/#useful-types) -* [추가 학습 위치](/learn/typescript/#further-learning) -======= * [TypeScript with React Components](/learn/typescript#typescript-with-react-components) * [Examples of typing with Hooks](/learn/typescript#example-hooks) * [Common types from `@types/react`](/learn/typescript#useful-types) * [Further learning locations](/learn/typescript#further-learning) ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ## 설치 {/*installation*/} -<<<<<<< HEAD -모든 [프로덕션 수준의 React 프레임워크](/learn/start-a-new-react-project#production-grade-react-frameworks)는 TypeScript 사용을 지원합니다. 프레임워크별 설치 가이드를 따르세요. -======= All [production-grade React frameworks](/learn/start-a-new-react-project#full-stack-frameworks) offer support for using TypeScript. Follow the framework specific guide for installation: ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 - [Next.js](https://nextjs.org/docs/app/building-your-application/configuring/typescript) - [Remix](https://remix.run/docs/en/1.19.2/guides/typescript) @@ -48,15 +37,9 @@ npm install --save-dev @types/react @types/react-dom 다음 컴파일러 옵션을 `tsconfig.json`에 설정해야 합니다. -<<<<<<< HEAD -1. `dom`은 [`lib`](https://www.typescriptlang.org/ko/tsconfig/#lib)에 포함되어야 합니다(주의: `lib` 옵션이 지정되지 않으면, 기본적으로 `dom`이 포함됩니다). -1. [`jsx`](https://www.typescriptlang.org/ko/tsconfig/#jsx)를 유효한 옵션 중 하나로 설정해야 합니다. 대부분의 애플리케이션에서는 `preserve`로 충분합니다. - 라이브러리를 게시하는 경우 어떤 값을 선택해야 하는지 [`jsx` 설명서](https://www.typescriptlang.org/ko/tsconfig/#jsx)를 참조하세요. -======= 1. `dom` must be included in [`lib`](https://www.typescriptlang.org/tsconfig/#lib) (Note: If no `lib` option is specified, `dom` is included by default). 2. [`jsx`](https://www.typescriptlang.org/tsconfig/#jsx) must be set to one of the valid options. `preserve` should suffice for most applications. If you're publishing a library, consult the [`jsx` documentation](https://www.typescriptlang.org/tsconfig/#jsx) on what value to choose. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ## React 컴포넌트가 있는 TypeScript {/*typescript-with-react-components*/} @@ -141,11 +124,7 @@ export default App = AppTSX; ## Hooks 예시 {/*example-hooks*/} -<<<<<<< HEAD -`@types/react`의 타입 정의에는 내장 Hooks에 대한 타입이 포함되어 있으므로 추가 설정 없이 컴포넌트에 사용할 수 있습니다. 컴포넌트에 작성한 코드를 고려하도록 만들어졌기 때문에 대부분의 경우 [추론된 타입](https://www.typescriptlang.org/ko/docs/handbook/type-inference.html)을 얻을 수 있으며, 이상적으로는 타입을 제공하는 사소한 작업을 처리할 필요가 없습니다. -======= The type definitions from `@types/react` include types for the built-in Hooks, so you can use them in your components without any additional setup. They are built to take into account the code you write in your component, so you will get [inferred types](https://www.typescriptlang.org/docs/handbook/type-inference.html) a lot of the time and ideally do not need to handle the minutiae of providing the types. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 하지만, hooks에 타입을 제공하는 방법의 몇 가지 예시를 볼 수 있습니다. @@ -161,11 +140,7 @@ const [enabled, setEnabled] = useState(false); `boolean` 타입이 `enabled`에 할당되고, `setEnabled` 는 `boolean` 인수나 `boolean`을 반환하는 함수를 받는 함수가 됩니다. state에 대한 타입을 명시적으로 제공하려면 `useState` 호출에 타입 인수를 제공하면 됩니다. ```ts -<<<<<<< HEAD -// 명시적으로 타입을 "boolean"으로 설정합니다 -======= // Explicitly set the type to "boolean" ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 const [enabled, setEnabled] = useState(false); ``` @@ -309,11 +284,7 @@ export default App = AppTSX; -<<<<<<< HEAD -이 기술은 합리적인 기본값이 있을 때 효과적이지만 그렇지 않은 경우도 간혹 있으며, 그러한 경우 `null`이 기본값으로 합리적이라고 느낄 수 있습니다. 그러나, 타입 시스템이 코드를 이해할 수 있도록 하려면 `createContext`에서 `ContextShape | null`을 명시적으로 설정해야 합니다. -======= This technique works when you have a default value which makes sense - but there are occasionally cases when you do not, and in those cases `null` can feel reasonable as a default value. However, to allow the type-system to understand your code, you need to explicitly set `ContextShape | null` on the `createContext`. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 이에 따라 context 소비자에 대한 타입에서 `| null`을 제거해야 하는 문제가 발생합니다. 권장 사항은 Hook이 런타임에 존재 여부를 검사하고 존재하지 않을 경우 에러를 throw 하는 것입니다. @@ -358,9 +329,6 @@ function MyComponent() { ### `useMemo` {/*typing-usememo*/} -<<<<<<< HEAD -[`useMemo`](/reference/react/useMemo) Hooks는 함수 호출로부터 memorized 된 값을 생성/재접근하여, 두 번째 매개변수로 전달된 종속성이 변경될 때만 함수를 다시 실행합니다. Hook을 호출한 결과는 첫 번째 매개변수에 있는 함수의 반환 값에서 추론됩니다. Hook에 타입 인수를 제공하여 더욱더 명확하게 할 수 있습니다. -======= [React Compiler](/learn/react-compiler) automatically memoizes values and functions, reducing the need for manual `useMemo` calls. You can use the compiler to handle memoization automatically. @@ -368,7 +336,6 @@ function MyComponent() { The [`useMemo`](/reference/react/useMemo) Hooks will create/re-access a memorized value from a function call, re-running the function only when dependencies passed as the 2nd parameter are changed. The result of calling the Hook is inferred from the return value from the function in the first parameter. You can be more explicit by providing a type argument to the Hook. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ```ts // visibleTodos의 타입은 filterTodos의 반환 값에서 추론됩니다. @@ -378,9 +345,6 @@ const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]); ### `useCallback` {/*typing-usecallback*/} -<<<<<<< HEAD -[`useCallback`](/reference/react/useCallback)는 두 번째 매개변수로 전달되는 종속성이 같다면 함수에 대한 안정적인 참조를 제공합니다. `useMemo`와 마찬가지로, 함수의 타입은 첫 번째 매개변수에 있는 함수의 반환 값에서 추론되며, Hook에 타입 인수를 제공하여 더욱더 명확하게 할 수 있습니다. -======= [React Compiler](/learn/react-compiler) automatically memoizes values and functions, reducing the need for manual `useCallback` calls. You can use the compiler to handle memoization automatically. @@ -388,7 +352,6 @@ const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]); The [`useCallback`](/reference/react/useCallback) provide a stable reference to a function as long as the dependencies passed into the second parameter are the same. Like `useMemo`, the function's type is inferred from the return value of the function in the first parameter, and you can be more explicit by providing a type argument to the Hook. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ```ts @@ -399,11 +362,7 @@ const handleClick = useCallback(() => { TypeScript strict mode에서 작업할 때 `useCallback`을 사용하려면 콜백에 매개변수를 위한 타입을 추가해야 합니다. 콜백의 타입은 함수의 반환 값에서 추론되고, 매개변수 없이는 타입을 완전히 이해할 수 없기 때문입니다. -<<<<<<< HEAD -코드 스타일 선호도에 따라, 콜백을 정의하는 동시에 이벤트 핸들러의 타입을 제공하기 위해 React 타입의 `*EventHandler` 함수를 사용할 수 있습니다. -======= Depending on your code-style preferences, you could use the `*EventHandler` functions from the React types to provide the type for the event handler at the same time as defining the callback: ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 ```ts import { useState, useCallback } from 'react'; @@ -486,11 +445,7 @@ interface ModalRendererProps { } ``` -<<<<<<< HEAD -자식이 특정 JSX 엘리먼트 타입이라고 설명하기 위해 TypeScript를 사용할 수 없으므로, `
  • ` 자식만 허용하는 컴포넌트를 설명하기 위해 타입 시스템을 사용할 수 없다는 점에 주의하세요. -======= Note, that you cannot use TypeScript to describe that the children are a certain type of JSX elements, so you cannot use the type-system to describe a component which only accepts `
  • ` children. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 [TypeScript 플레이그라운드](https://www.typescriptlang.org/ko/play?#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgIilQ3wChSB6CxYmAOmXRgDkIATJOdNJMGAZzgwAFpxAR+8YADswAVwGkZMJFEzpOjDKw4AFHGEEBvUnDhphwADZsi0gFw0mDWjqQBuUgF9yaCNMlENzgAXjgACjADfkctFnYkfQhDAEpQgD44AB42YAA3dKMo5P46C2tbJGkvLIpcgt9-QLi3AEEwMFCItJDMrPTTbIQ3dKywdIB5aU4kKyQQKpha8drhhIGzLLWODbNs3b3s8YAxKBQAcwXpAThMaGWDvbH0gFloGbmrgQfBzYpd1YjQZbEYARkB6zMwO2SHSAAlZlYIBCdtCRkZpHIrFYahQYQD8UYYFA5EhcfjyGYqHAXnJAsIUHlOOUbHYhMIIHJzsI0Qk4P9SLUBuRqXEXEwAKKfRZcNA8PiCfxWACecAAUgBlAAacFm80W-CU11U6h4TgwUv11yShjgJjMLMqDnN9Dilq+nh8pD8AXgCHdMrCkWisVoAet0R6fXqhWKhjKllZVVxMcavpd4Zg7U6Qaj+2hmdG4zeRF10uu-Aeq0LBfLMEe-V+T2L7zLVu+FBWLdLeq+lc7DYFf39deFVOotMCACNOCh1dq219a+30uC8YWoZsRyuEdjkevR8uvoVMdjyTWt4WiSSydXD4NqZP4AymeZE072ZzuUeZQKheQgA)에서 타입 체커를 사용하여 `React.ReactNode`와 `React.ReactElement`의 모든 예시를 확인할 수 있습니다. diff --git a/src/content/learn/you-might-not-need-an-effect.md b/src/content/learn/you-might-not-need-an-effect.md index 1df1e94f9..d92165a81 100644 --- a/src/content/learn/you-might-not-need-an-effect.md +++ b/src/content/learn/you-might-not-need-an-effect.md @@ -26,11 +26,7 @@ Effect가 필요하지 않은 두 가지 일반적인 경우가 있습니다. * **렌더링을 위해 데이터를 변환하는 데 Effect가 필요하지 않습니다.** 예를 들어 리스트를 표시하기 전에 필터링하고 싶다고 가정해 보겠습니다. 리스트가 변경될 때 state 변수를 업데이트하는 Effect를 작성하고 싶을 수 있습니다. 하지만 이는 비효율적입니다. state를 업데이트할 때 React는 먼저 컴포넌트 함수를 호출해 화면에 표시될 내용을 계산합니다. 그런 다음 React는 이러한 변경 사항을 DOM에 ["commit"](/learn/render-and-commit)하여 화면을 업데이트합니다. 그리고 나서 React가 Effect를 실행합니다. 만약 Effect도 *즉시* state를 업데이트한다면 전체 프로세스가 처음부터 다시 시작됩니다! 불필요한 렌더링 패스를 피하려면, 컴포넌트의 최상위 레벨에서 모든 데이터를 변환하세요. 그러면 props나 state가 변경될 때마다 해당 코드가 자동으로 다시 실행됩니다. * **사용자 이벤트를 처리하는 데 Effect가 필요하지 않습니다.** 예를 들어 사용자가 제품을 구매할 때 `/api/buy` POST 요청을 전송하고 알림을 표시하고 싶다고 가정해 보겠습니다. 구매 버튼 클릭 이벤트 핸들러에서는 정확히 어떤 일이 일어났는지 알 수 있습니다. Effect가 실행될 때까지 사용자가 무엇을 했는지 (예: 어떤 버튼을 클릭 했는지) 알 수 없습니다. 그렇기 때문에 일반적으로 해당되는 이벤트 핸들러에서 사용자 이벤트를 처리합니다. -<<<<<<< HEAD -외부 시스템과 [동기화](/learn/synchronizing-with-effects#what-are-effects-and-how-are-they-different-from-events)하려면 Effect가 *반드시* 필요합니다. 예를 들어 jQuery 위젯이 React State와 동기화되도록 유지하는 Effect를 작성할 수 있습니다. Effect로 데이터를 가져올 수도 있습니다: 예를 들어 검색 결과를 현재 검색 쿼리와 동기화할 수 있습니다. 모던 [프레임워크](/learn/start-a-new-react-project#production-grade-react-frameworks)는 컴포넌트에 직접 Effect를 작성하는 것보다 더 효율적인 내장 데이터 가져오기 메커니즘을 제공한다는 점을 명심하세요. -======= You *do* need Effects to [synchronize](/learn/synchronizing-with-effects#what-are-effects-and-how-are-they-different-from-events) with external systems. For example, you can write an Effect that keeps a jQuery widget synchronized with the React state. You can also fetch data with Effects: for example, you can synchronize the search results with the current search query. Keep in mind that modern [frameworks](/learn/start-a-new-react-project#full-stack-frameworks) provide more efficient built-in data fetching mechanisms than writing Effects directly in your components. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 올바른 직관을 얻기 위해, 몇 가지 일반적이고 구체적인 예를 살펴봅시다! @@ -762,11 +758,7 @@ function SearchResults({ query }) { 데이터 가져오기를 구현할 때 경쟁 조건을 처리하는 것만이 어려운 것은 아닙니다. 응답 캐싱(사용자가 뒤로가기 버튼을 클릭하여 이전 화면을 즉시 볼 수 있도록), 서버에서 데이터를 가져오는 방법(초기 서버 렌더링 HTML에 스피너 대신 가져온 콘텐츠가 포함되도록), 네트워크 워터폴을 피하는 방법(자식이 모든 부모를 기다리지 않고 데이터를 가져올 수 있도록)도 고려해야 합니다. -<<<<<<< HEAD -**이러한 문제는 React뿐만 아니라 모든 UI 라이브러리에 적용됩니다. 이러한 문제를 해결하는 것은 간단하지 않기 때문에 모던 [프레임워크](/learn/start-a-new-react-project#production-grade-react-frameworks)는 Effect에서 데이터를 가져오는 것보다 더 효율적인 내장 데이터 가져오기 메커니즘을 제공합니다.** -======= **These issues apply to any UI library, not just React. Solving them is not trivial, which is why modern [frameworks](/learn/start-a-new-react-project#full-stack-frameworks) provide more efficient built-in data fetching mechanisms than fetching data in Effects.** ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 프레임워크를 사용하지 않고(그리고 직접 빌드하고 싶지 않고) Effect에서 데이터를 보다 인체공학적으로 가져오고 싶다면 이 예시처럼 가져오기 로직을 사용자 정의 Hook으로 추출하는 것을 고려하세요. diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index 10b5c30ff..7c0cefd78 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -207,11 +207,7 @@ HTML이 비어있으면, 앱의 자바스크립트 코드가 로드되고 실행
    ``` -<<<<<<< HEAD -이것은 매우 느리게 느껴질 수 있습니다! 이 문제를 해결하기 위해 [서버에서 또는 빌드 중에](/reference/react-dom/server) 컴포넌트로부터 초기 HTML을 생성할 수 있습니다. 그러면 방문자는 자바스크립트 코드가 로드되기 전에 텍스트를 읽고, 이미지를 보고, 링크를 클릭할 수 있습니다. 이 최적화를 기본적으로 수행하는 [프레임워크를 사용](/learn/start-a-new-react-project#production-grade-react-frameworks)하는 것이 좋습니다. 실행 시점에 따라 이를 *서버 측 렌더링SSR* 또는 *정적 사이트 생성SSG* 이라고 합니다. -======= This can feel very slow! To solve this, you can generate the initial HTML from your components [on the server or during the build.](/reference/react-dom/server) Then your visitors can read text, see images, and click links before any of the JavaScript code loads. We recommend [using a framework](/learn/start-a-new-react-project#full-stack-frameworks) that does this optimization out of the box. Depending on when it runs, this is called *server-side rendering (SSR)* or *static site generation (SSG).* ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 diff --git a/src/content/reference/react-dom/client/index.md b/src/content/reference/react-dom/client/index.md index fb06ac8e6..0707d8009 100644 --- a/src/content/reference/react-dom/client/index.md +++ b/src/content/reference/react-dom/client/index.md @@ -4,12 +4,8 @@ title: Client React DOM APIs -<<<<<<< HEAD -`react-dom/client` API를 사용하면 클라이언트(브라우저)에서 React 컴포넌트를 렌더링 할 수 있습니다. 이러한 API는 일반적으로 앱의 최상위 수준에서 React 트리를 초기화하기 위해 사용합니다. [프레임워크](/learn/start-a-new-react-project#production-grade-react-frameworks)가 대신 호출할 수도 있습니다. 대부분의 컴포넌트는 이를 가져오거나 사용할 필요가 없습니다. -======= The `react-dom/client` APIs let you render React components on the client (in the browser). These APIs are typically used at the top level of your app to initialize your React tree. A [framework](/learn/start-a-new-react-project#full-stack-frameworks) may call them for you. Most of your components don't need to import or use them. ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 --- diff --git a/src/content/reference/react-dom/components/common.md b/src/content/reference/react-dom/components/common.md index 4a4b29881..0406bd43a 100644 --- a/src/content/reference/react-dom/components/common.md +++ b/src/content/reference/react-dom/components/common.md @@ -917,11 +917,7 @@ export default function Form() { -<<<<<<< HEAD -[ref로 DOM 조작하기](/learn/manipulating-the-dom-with-refs) 및 [더 많은 예시](/reference/react/useRef#examples-dom)에 대해 더 자세히 읽어보세요. -======= Read more about [manipulating DOM with refs](/learn/manipulating-the-dom-with-refs) and [check out more examples.](/reference/react/useRef#usage) ->>>>>>> 0d05d9b6ef0f115ec0b96a2726ab0699a9ebafe1 고급 사용 사례의 경우 `ref` 어트리뷰트는 [콜백 함수](#ref-callback)도 허용합니다. diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md index 035b4e260..ad85b90d6 100644 --- a/src/content/reference/react-dom/components/form.md +++ b/src/content/reference/react-dom/components/form.md @@ -36,15 +36,9 @@ title: "" #### Props {/*props*/} -<<<<<<< HEAD -``은 모든 [공통 엘리먼트 Props](/reference/react-dom/components/common#props)를 지원합니다. - -[`action`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action): URL 혹은 함수. URL을 `action`을 통해 전달하면, 폼은 HTML 폼 컴포넌트처럼 동작합니다. 함수를 `action`을 통해 전달하면, 해당 함수는 폼 제출을 처리합니다. `action`을 통한 함수는 비동기로 동작할 수 있으며, 폼을 통해 제출된 [`formData`](https://developer.mozilla.org/ko/docs/Web/API/FormData)를 포함한 단일 인수로 호출됩니다. `action`의 프로퍼티는 `formAction`의 속성인 `