From 1fa205704ec3841c4e85bc152aa04050b7e2195b Mon Sep 17 00:00:00 2001 From: Homyee King Date: Mon, 6 May 2024 13:17:59 +0800 Subject: [PATCH 0001/1059] Update react-19.md (#6838) --- src/content/blog/2024/04/25/react-19.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/blog/2024/04/25/react-19.md b/src/content/blog/2024/04/25/react-19.md index 0670eaa80..1ccffa1c8 100644 --- a/src/content/blog/2024/04/25/react-19.md +++ b/src/content/blog/2024/04/25/react-19.md @@ -112,7 +112,7 @@ The async transition will immediately set the `isPending` state to true, make th Actions automatically manage submitting data for you: - **Pending state**: Actions provide a pending state that starts at the beginning of a request and automatically resets when the final state update is committed. -- **Optimistic updates**: Actions support the new [`useOptimistic`](#new-feature-optimistic-updates) hook so you can show users instant feedback while the requests are submitting. +- **Optimistic updates**: Actions support the new [`useOptimistic`](#new-hook-optimistic-updates) hook so you can show users instant feedback while the requests are submitting. - **Error handling**: Actions provide error handling so you can display Error Boundaries when a request fails, and revert optimistic updates to their original value automatically. - **Forms**: `
` elements now support passing functions to the `action` and `formAction` props. Passing functions to the `action` props use Actions by default and reset the form automatically after submission. From 46437c2b12b14073d614b94befc012c21013327a Mon Sep 17 00:00:00 2001 From: Jack Spiva Date: Tue, 7 May 2024 10:25:41 -0500 Subject: [PATCH 0002/1059] Add missing period to React v18.0 blog post (#6842) --- src/content/blog/2022/03/29/react-v18.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/blog/2022/03/29/react-v18.md b/src/content/blog/2022/03/29/react-v18.md index 27899fdde..d21eeb1f5 100644 --- a/src/content/blog/2022/03/29/react-v18.md +++ b/src/content/blog/2022/03/29/react-v18.md @@ -240,7 +240,7 @@ With Strict Mode in React 18, React will simulate unmounting and remounting the #### useTransition {/*usetransition*/} -`useTransition` and `startTransition` let you mark some state updates as not urgent. Other state updates are considered urgent by default. React will allow urgent state updates (for example, updating a text input) to interrupt non-urgent state updates (for example, rendering a list of search results). [See docs here](/reference/react/useTransition) +`useTransition` and `startTransition` let you mark some state updates as not urgent. Other state updates are considered urgent by default. React will allow urgent state updates (for example, updating a text input) to interrupt non-urgent state updates (for example, rendering a list of search results). [See docs here](/reference/react/useTransition). #### useDeferredValue {/*usedeferredvalue*/} From 0b9ae66066cccce35832c35097d6cafacd99c098 Mon Sep 17 00:00:00 2001 From: Ricky Date: Thu, 9 May 2024 10:43:42 -0400 Subject: [PATCH 0003/1059] Add docs for useRef no no (#6846) --- .../learn/synchronizing-with-effects.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/content/learn/synchronizing-with-effects.md b/src/content/learn/synchronizing-with-effects.md index f1aa98438..4218171d4 100644 --- a/src/content/learn/synchronizing-with-effects.md +++ b/src/content/learn/synchronizing-with-effects.md @@ -598,6 +598,33 @@ Usually, the answer is to implement the cleanup function. The cleanup function Most of the Effects you'll write will fit into one of the common patterns below. + + +#### Don't use refs to prevent Effects from firing {/*dont-use-refs-to-prevent-effects-from-firing*/} + +A common pitfall for preventing Effects firing twice in development is to use a `ref` to prevent the Effect from running more than once. For example, you could "fix" the above bug with a `useRef`: + +```js {1,3-4} + const connectionRef = useRef(null); + useEffect(() => { + // ๐Ÿšฉ This wont fix the bug!!! + if (!connectionRef.current) { + connectionRef.current = createConnection(); + connectionRef.current.connect(); + } + }, []); +``` + +This makes it so you only see `"โœ… Connecting..."` once in development, but it doesn't fix the bug. + +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". + +To fix the bug, it is not enough to just make the Effect run once. The effect needs to work after re-mounting, which means the connection needs to be cleaned up like in the solution above. + +See the examples below for how to handle common patterns. + + + ### Controlling non-React widgets {/*controlling-non-react-widgets*/} Sometimes you need to add UI widgets that aren't written to React. For example, let's say you're adding a map component to your page. It has a `setZoomLevel()` method, and you'd like to keep the zoom level in sync with a `zoomLevel` state variable in your React code. Your Effect would look similar to this: From f1b0f862332334f0e9439ca996767ad648e064ea Mon Sep 17 00:00:00 2001 From: Linda Date: Thu, 9 May 2024 18:01:57 -0700 Subject: [PATCH 0004/1059] Fix typo on tutorial-tic-tac-toe.md (#6843) Change the tense of "build" to "building". --- src/content/learn/tutorial-tic-tac-toe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index d37791456..f18ec4939 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -2915,4 +2915,4 @@ If you have extra time or want to practice your new React skills, here are some 1. When someone wins, highlight the three squares that caused the win (and when no one wins, display a message about the result being a draw). 1. Display the location for each move in the format (row, col) in the move history list. -Throughout this tutorial, you've touched on React concepts including elements, components, props, and state. Now that you've seen how these concepts work when building a game, check out [Thinking in React](/learn/thinking-in-react) to see how the same React concepts work when build an app's UI. +Throughout this tutorial, you've touched on React concepts including elements, components, props, and state. Now that you've seen how these concepts work when building a game, check out [Thinking in React](/learn/thinking-in-react) to see how the same React concepts work when building an app's UI. From f9b9b66e0bbba6f54a92d867555c8b8669774bec Mon Sep 17 00:00:00 2001 From: Batuhan Tomo <91488737+Rekl0w@users.noreply.github.com> Date: Fri, 10 May 2024 11:26:43 +0300 Subject: [PATCH 0005/1059] Fix #6852: navigation link fix (#6853) --- 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 afdddc749..d5f656073 100644 --- a/src/content/reference/react-dom/components/form.md +++ b/src/content/reference/react-dom/components/form.md @@ -386,7 +386,7 @@ export async function signUpNewUser(newEmail) { -Learn more about updating state from a form action with the [`useActionState`](/reference/react/hooks/useActionState) docs +Learn more about updating state from a form action with the [`useActionState`](/reference/react/useActionState) docs ### Handling multiple submission types {/*handling-multiple-submission-types*/} From 4f1d98577df19e3734fa66b8f0ca28a47dab49f7 Mon Sep 17 00:00:00 2001 From: Muhammad Saqib Date: Fri, 10 May 2024 19:19:44 +0500 Subject: [PATCH 0006/1059] Update synchronizing-with-effects.md (#6856) * Update synchronizing-with-effects.md Currently documentation says: By default, your Effect will run after every render. Which is in contrast with another section of the same page where it says: Effects run at the end of a commit after the screen updates * Update src/content/learn/synchronizing-with-effects.md --------- Co-authored-by: Ricky --- src/content/learn/synchronizing-with-effects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/synchronizing-with-effects.md b/src/content/learn/synchronizing-with-effects.md index 4218171d4..9ca109656 100644 --- a/src/content/learn/synchronizing-with-effects.md +++ b/src/content/learn/synchronizing-with-effects.md @@ -45,7 +45,7 @@ Here and later in this text, capitalized "Effect" refers to the React-specific d To write an Effect, follow these three steps: -1. **Declare an Effect.** By default, your Effect will run after every render. +1. **Declare an Effect.** By default, your Effect will run after every [commit](/learn/render-and-commit). 2. **Specify the Effect dependencies.** Most Effects should only re-run *when needed* rather than after every render. For example, a fade-in animation should only trigger when a component appears. Connecting and disconnecting to a chat room should only happen when the component appears and disappears, or when the chat room changes. You will learn how to control this by specifying *dependencies.* 3. **Add cleanup if needed.** Some Effects need to specify how to stop, undo, or clean up whatever they were doing. For example, "connect" needs "disconnect", "subscribe" needs "unsubscribe", and "fetch" needs either "cancel" or "ignore". You will learn how to do this by returning a *cleanup function*. From b7bf6c16fb3152626a71c115b3242df6eb93bc6e Mon Sep 17 00:00:00 2001 From: Batuhan Tomo <91488737+Rekl0w@users.noreply.github.com> Date: Fri, 10 May 2024 17:33:45 +0300 Subject: [PATCH 0007/1059] Fix Node.js version update at `package.json` (#6855) * Fix #6854: node.js version upgrade * Fix #6854: node.js version update --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ddbe92505..26bb39657 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "webpack-bundle-analyzer": "^4.5.0" }, "engines": { - "node": "^16.8.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0" + "node": ">=16.8.0" }, "nextBundleAnalysis": { "budget": null, From a81e41555457e82e367c914b8cc84785f4144d1d Mon Sep 17 00:00:00 2001 From: Rajat Jindal <78809406+includerajat@users.noreply.github.com> Date: Mon, 13 May 2024 17:17:37 +0530 Subject: [PATCH 0008/1059] Change React dependency version in page fix (#6858) Co-authored-by: Rajat Jindal --- src/content/reference/react-dom/components/form.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md index d5f656073..8f6ab00e0 100644 --- a/src/content/reference/react-dom/components/form.md +++ b/src/content/reference/react-dom/components/form.md @@ -375,8 +375,8 @@ export async function signUpNewUser(newEmail) { ```json package.json hidden { "dependencies": { - "react": "18.3.0-canary-6db7f4209-20231021", - "react-dom": "18.3.0-canary-6db7f4209-20231021", + "react": "canary", + "react-dom": "canary", "react-scripts": "^5.0.0" }, "main": "/index.js", From f053b53b0501a6c9a4ec2d4de80a633e01ec2174 Mon Sep 17 00:00:00 2001 From: Jason Bonta Date: Mon, 13 May 2024 19:40:55 -0700 Subject: [PATCH 0009/1059] Update team.md: Jason Bonta (#6862) * Update team.md: Jason Bonta * Update src/content/community/team.md Lauren's suggestion Co-authored-by: lauren --------- Co-authored-by: lauren --- src/content/community/team.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/community/team.md b/src/content/community/team.md index 060e9c841..6004476e2 100644 --- a/src/content/community/team.md +++ b/src/content/community/team.md @@ -31,7 +31,7 @@ Current members of the React team are listed in alphabetical order below. - Jason likes having large volumes of Amazon packages delivered to the office so that he can build forts. Despite literally walling himself off from his team at times and not understanding how for-of loops work, we appreciate him for the unique qualities he brings to his work. + Jason abandoned embedded C for a career in front-end engineering and never looked back. Armed with esoteric CSS knowledge and a passion for beautiful UI, Jason joined Facebook in 2010, where he now feels privileged to have seen JavaScript development come of age. Though he may not understand how `for...of` loops work, he loves getting to work with brilliant people on projects that enable amazing UX. From e0c667feefa809feebb0e702e3612cf91c34780d Mon Sep 17 00:00:00 2001 From: Ricky Date: Wed, 15 May 2024 13:13:36 -0400 Subject: [PATCH 0010/1059] Add React Compiler Docs (#6869) * Add initial skeleton * Scaffold compiler docs structure * Braindump for getting started * Add intro * tweaks * add experimental tag * flesh more out of index page * flesh out installation * add installation intro * update install instrs * add section on eslint plugin * reorg * add incremental guide * [debugging] Add section about devtools badge * [debugging] Add section about using logger * Update next.js instructions * reporting issues * [debugging] Add section on useEffect over firing * [debugging] Add section about conditional hook call * Latest updates * Remove ununsed reference pages * adding extra context for Remix --------- Co-authored-by: Sathya Gunasekaran Co-authored-by: Lauren Tan Co-authored-by: Jason Bonta --- src/content/learn/react-compiler.md | 282 ++++++++++++++++++++++++++++ src/sidebarLearn.json | 7 +- 2 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 src/content/learn/react-compiler.md diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md new file mode 100644 index 000000000..5918e45bc --- /dev/null +++ b/src/content/learn/react-compiler.md @@ -0,0 +1,282 @@ +--- +title: React Compiler +--- + + +This page will give you an introduction to the new experimental React Compiler and how to try it out successfully. + + + +These docs are still a work in progress. More documentation is available in the [React Compiler Working Group repo](https://github.com/reactwg/react-compiler/discussions), and will be upstreamed into these docs when they are more stable. + + + + +* Getting started with the compiler +* Installing the compiler and eslint plugin +* Troubleshooting + + + + +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 Beta. + + +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. + +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. + +### What does the compiler do? {/*what-does-the-compiler-do*/} + +The compiler understands your code at a deep level through its understanding of plain JavaScript semantics and the [Rules of React](/reference/rules). This allows it to add automatic optimizations to your code. + +You may be familiar today with manual memoization through [`useMemo`](/reference/react/useMemo), [`useCallback`](/reference/react/useCallback), and [`React.memo`](/reference/react/memo). The compiler can automatically do this for you, if your code follows the [Rules of React](/reference/rules). If it detects breakages of the rules, it will automatically skip over just those components or hooks, and continue safely compiling other code. + +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. + +### 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). + +**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. + +## Getting Started {/*getting-started*/} + +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. + +### Rolling out the compiler to your codebase {/*using-the-compiler-effectively*/} + +#### Existing projects {/*existing-projects*/} +The compiler is designed to compile functional components and hooks that follows the [Rules of React](/reference/rules). It can also handle code that breaks those rules by bailing out (skipping over) those components or hooks. However, due to the flexible nature of JavaScript, the compiler cannot catch every possible violation and may compile with false negatives: that is, the compiler may accidentally compile a component/hook that breaks the Rules of React which can lead to undefined behavior. + +For this reason, to adopt the compiler successfully on existing projects, we recommend running it on a small directory in your product code first. You can do by configuring the compiler to only run on specific set of directories: + +```js {3} +const ReactCompilerConfig = { + sources: (filename) => { + return filename.indexOf('src/path/to/dir') !== -1; + }, +}; +``` + +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", +}; + +// src/app.jsx +export default function App() { + "use memo"; + // ... +} +``` + +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. + +## Installation {/*installation*/} + +### Checking compatibility {/*checking-compatibility*/} + +Prior to installing the compiler, you can first check to see if your codebase is compatible: + + +npx react-compiler-healthcheck + + +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 libaries 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. + + +npm install eslint-plugin-react-compiler + + +Then, add it to your eslint config: + +```js +module.exports = { + plugins: [ + 'eslint-plugin-react-compiler', + ], + rules: { + 'react-compiler/react-compiler': 2, + }, +} +``` + +### Usage with Babel {/*usage-with-babel*/} + + +npm install babel-plugin-react-compiler + + +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: + +```js {7} +// babel.config.js +const ReactCompilerConfig = { /* ... */ }; + +module.exports = function () { + return { + plugins: [ + ['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. + +### Usage with Vite {/*usage-with-vite*/} + +If you use Vite, you can add the plugin to vite-plugin-react: + +```js {10} +// vite.config.js +const ReactCompilerConfig = { /* ... */ }; + +export default defineConfig(() => { + return { + plugins: [ + react({ + babel: { + plugins: [ + ["babel-plugin-react-compiler", ReactCompilerConfig], + ], + }, + }), + ], + // ... + }; +}); +``` + +### Usage with Next.js {/*usage-with-nextjs*/} + +Next.js allows for a slower build pipeline via Babel, which can be enabled by [configuring Babel](#usage-with-babel) by adding a `babel.config.js` file. + +### Usage with Remix {/*usage-with-remix*/} +Install `vite-plugin-babel`, and add the compiler's Babel plugin to it: + + +npm install vite-plugin-babel + + +```js {2,14} +// vite.config.js +import babel from "vite-plugin-babel"; + +const ReactCompilerConfig = { /* ... */ }; + +export default defineConfig({ + plugins: [ + remix({ /* ... */}), + babel({ + filter: /\.[jt]sx?$/, + babelConfig: { + presets: ["@babel/preset-typescript"], // if you use TypeScript + plugins: [ + ["babel-plugin-react-compiler", ReactCompilerConfig], + ], + }, + }), + ], +}); +``` + +### Usage with 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; +``` + +### Usage with Expo {/*usage-with-expo*/} + +Expo uses Babel via Metro, so refer to the [Usage with Babel](#usage-with-babel) section for installation instructions. + +### Usage with React Native (Metro) {/*usage-with-react-native-metro*/} + +React Native uses Babel via Metro, so refer to the [Usage with Babel](#usage-with-babel) section for installation instructions. + +## Troubleshooting {/*troubleshooting*/} + +### Reporting Issues {/*reporting-issues*/} + +To report issues, please first create a minimal repro on the [React Compiler Playground](https://0xeac7-forget.vercel.app/) and include it in your bug report. + +You can open issues in the [facebook/react](https://github.com/facebook/react/issues) repo. + +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). + +### Common Issues {/*common-issues*/} + +#### `(0 , _c) is not a function` error {/*0--_c-is-not-a-function-error*/} + +This occurs during JavaScript module evaluation when you are not using React 19 Beta and up. To fix this, [upgrade your app to React 19 Beta](https://react.dev/blog/2024/04/25/react-19-upgrade-guide) first. + +### Debugging {/*debugging*/} + +#### Checking if components have been optimized {/*checking-if-components-have-been-optimized*/} +##### React DevTools {/*react-devtools*/} + +React Devtools (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. + +##### Other issues {/*other-issues*/} + +Please see https://github.com/reactwg/react-compiler/discussions/7. \ No newline at end of file diff --git a/src/sidebarLearn.json b/src/sidebarLearn.json index 02806dc0c..335fc3556 100644 --- a/src/sidebarLearn.json +++ b/src/sidebarLearn.json @@ -43,6 +43,11 @@ { "title": "React Developer Tools", "path": "/learn/react-developer-tools" + }, + { + "title": "React Compiler", + "path": "/learn/react-compiler", + "canary": true } ] }, @@ -194,7 +199,7 @@ }, { "title": "Removing Effect Dependencies", - "path": "/learn/removing-effect-dependencies" + "path": "/learn/removing-effect-dependencies" }, { "title": "Reusing Logic with Custom Hooks", From fa19b7fc83464ba1062857bf919b16d8edf9199a Mon Sep 17 00:00:00 2001 From: Jason Bonta Date: Wed, 15 May 2024 11:26:59 -0700 Subject: [PATCH 0011/1059] compiler playground link --- src/content/learn/react-compiler.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 5918e45bc..686e9d75b 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -258,7 +258,7 @@ React Native uses Babel via Metro, so refer to the [Usage with Babel](#usage-wit ### Reporting Issues {/*reporting-issues*/} -To report issues, please first create a minimal repro on the [React Compiler Playground](https://0xeac7-forget.vercel.app/) and include it in your bug report. +To report issues, please first create a minimal repro on the [React Compiler Playground](https://playground.react.dev/) and include it in your bug report. You can open issues in the [facebook/react](https://github.com/facebook/react/issues) repo. @@ -279,4 +279,4 @@ React Devtools (v5.0+) has built-in support for React Compiler and will display ##### Other issues {/*other-issues*/} -Please see https://github.com/reactwg/react-compiler/discussions/7. \ No newline at end of file +Please see https://github.com/reactwg/react-compiler/discussions/7. From 8d69e6ebf9a89114c8cafc78b4464a74a384aa33 Mon Sep 17 00:00:00 2001 From: Shrey Sudhir Date: Fri, 17 May 2024 02:37:45 +1000 Subject: [PATCH 0012/1059] Clearer rule severity for React Compiler eslint plugin (#6870) Using "off", "warn", "error" has been supported for many years now - I think this helps improve the readability :) I completely forgot what rule: 2 meant - had to find it at https://eslint.org/docs/latest/use/configure/rules --- src/content/learn/react-compiler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 686e9d75b..9c698db78 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -121,7 +121,7 @@ module.exports = { 'eslint-plugin-react-compiler', ], rules: { - 'react-compiler/react-compiler': 2, + 'react-compiler/react-compiler': "error", }, } ``` From 4e3d63a923ca5608561766e1f9526e31eeabdc24 Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Fri, 17 May 2024 09:19:46 +0300 Subject: [PATCH 0013/1059] Fix typos in React Compiler guide (#6875) --- src/content/learn/react-compiler.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 9c698db78..1a6aaccb7 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -49,9 +49,9 @@ In addition to these docs, we recommend checking the [React Compiler Working Gro ### Rolling out the compiler to your codebase {/*using-the-compiler-effectively*/} #### Existing projects {/*existing-projects*/} -The compiler is designed to compile functional components and hooks that follows the [Rules of React](/reference/rules). It can also handle code that breaks those rules by bailing out (skipping over) those components or hooks. However, due to the flexible nature of JavaScript, the compiler cannot catch every possible violation and may compile with false negatives: that is, the compiler may accidentally compile a component/hook that breaks the Rules of React which can lead to undefined behavior. +The compiler is designed to compile functional components and hooks that follow the [Rules of React](/reference/rules). It can also handle code that breaks those rules by bailing out (skipping over) those components or hooks. However, due to the flexible nature of JavaScript, the compiler cannot catch every possible violation and may compile with false negatives: that is, the compiler may accidentally compile a component/hook that breaks the Rules of React which can lead to undefined behavior. -For this reason, to adopt the compiler successfully on existing projects, we recommend running it on a small directory in your product code first. You can do by configuring the compiler to only run on specific set of directories: +For this reason, to adopt the compiler successfully on existing projects, we recommend running it on a small directory in your product code first. You can do this by configuring the compiler to only run on a specific set of directories: ```js {3} const ReactCompilerConfig = { From 3a46a6e435ac90054fc2cb1b3c7ee2dcf504645f Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 17 May 2024 14:34:43 +0200 Subject: [PATCH 0014/1059] Update instructions for setting up the React Compiler in Next.js (#6877) --- src/content/learn/react-compiler.md | 31 ++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 1a6aaccb7..378756f29 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -178,7 +178,36 @@ export default defineConfig(() => { ### Usage with Next.js {/*usage-with-nextjs*/} -Next.js allows for a slower build pipeline via Babel, which can be enabled by [configuring Babel](#usage-with-babel) by adding a `babel.config.js` file. +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 + + +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, + }, +}; + +export default nextConfig; +``` + +Using the experimental option ensures support for the React Compiler in: + +- App Router +- Pages Router +- Webpack (default) +- Turbopack (opt-in through `--turbo`) + ### Usage with Remix {/*usage-with-remix*/} Install `vite-plugin-babel`, and add the compiler's Babel plugin to it: From 70a7b64e8068ad7b8fd9073a7b565e61b60ac435 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 17 May 2024 15:10:25 +0200 Subject: [PATCH 0015/1059] Update export of next.config.js (#6878) --- src/content/learn/react-compiler.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 378756f29..23c7f86a3 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -198,7 +198,7 @@ const nextConfig = { }, }; -export default nextConfig; +module.exports = nextConfig; ``` Using the experimental option ensures support for the React Compiler in: From ee068ace26603117e2f7924f8cbfcd9a15f8acdc Mon Sep 17 00:00:00 2001 From: Kid Max <41998473+officialkidmax@users.noreply.github.com> Date: Sun, 19 May 2024 07:13:41 +0600 Subject: [PATCH 0016/1059] Update separating-events-from-effects.md (#6880) Removed ; as it's unnecessary in jsx component --- src/content/learn/separating-events-from-effects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/separating-events-from-effects.md b/src/content/learn/separating-events-from-effects.md index ac65d2b60..21276c287 100644 --- a/src/content/learn/separating-events-from-effects.md +++ b/src/content/learn/separating-events-from-effects.md @@ -44,7 +44,7 @@ function ChatRoom({ roomId }) { return ( <> setMessage(e.target.value)} /> - ; + ); } From 8bb3eb3c44f6691ef7d496c8d330c673cca84122 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sun, 19 May 2024 10:56:42 +0900 Subject: [PATCH 0017/1059] Fix typo (spreadsheet => stylesheet) (#6750) --- src/content/reference/react-dom/components/link.md | 4 ++-- src/content/reference/react-dom/components/style.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/reference/react-dom/components/link.md b/src/content/reference/react-dom/components/link.md index c3331d94c..9172a66e7 100644 --- a/src/content/reference/react-dom/components/link.md +++ b/src/content/reference/react-dom/components/link.md @@ -44,12 +44,12 @@ To link to external resources such as stylesheets, fonts, and icons, or to annot These props apply when `rel="stylesheet"`: * `precedence`: a string. Tells React where to rank the `` DOM node relative to others in the document ``, which determines which stylesheet can override the other. Its value can be (in order of precedence) `"reset"`, `"low"`, `"medium"`, `"high"`. Stylesheets with the same precedence go together whether they are `` or inline ` @@ -23,53 +23,54 @@ The [built-in browser ` ``` -[See more examples below.](#usage) +[์•„๋ž˜์— ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.](#usage) #### Props {/*props*/} -` @@ -37,7 +37,7 @@ React์˜ `` ํ™•์žฅ์€ ํ˜„์žฌ React์˜ ์นด๋‚˜๋ฆฌ(Canary) ๋ฒ„์ „ ๋ฐ ์‹คํ—˜ #### Props {/*props*/} -`<style>`์€ [๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ ์†์„ฑ](/reference/react-dom/components/common#props)์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. +`<style>`์€ [๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ ์†์„ฑ](/reference/react-dom/components/common#props)์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. * `children`: ๋ฌธ์ž์—ด ํƒ€์ž…. ํ•„์ˆ˜ ํ•ญ๋ชฉ. ์Šคํƒ€์ผ์‹œํŠธ์˜ ๋‚ด์šฉ. * `precedence`: ๋ฌธ์ž์—ด ํƒ€์ž…. ๋ฌธ์„œ์˜ `<head>` ๋‚ด ๋‹ค๋ฅธ ์š”์†Œ๋“ค์— ๋น„ํ•ด `<style>` DOM ๋…ธ๋“œ์˜ ์ˆœ์œ„๋ฅผ ์ง€์ •ํ•˜์—ฌ, ์–ด๋–ค ์Šคํƒ€์ผ์‹œํŠธ๊ฐ€ ๋‹ค๋ฅธ ์Šคํƒ€์ผ์‹œํŠธ๋ฅผ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. React๋Š” ๋จผ์ € ๋ฐœ๊ฒฌํ•œ ์šฐ์„ ์ˆœ์œ„๋ฅผ "๋‚ฎ๊ฒŒ", ๋‚˜์ค‘์— ๋ฐœ๊ฒฌํ•œ ์šฐ์„ ์ˆœ์œ„๋ฅผ "๋†’๊ฒŒ" ์ถ”๋ก ํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ์Šคํƒ€์ผ ์‹œ์Šคํ…œ์€ ์Šคํƒ€์ผ ๊ทœ์น™์ด ์›์ž์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์ผ ์šฐ์„ ์ˆœ์œ„ ๊ฐ’์„ ์‚ฌ์šฉํ•ด๋„ ์ž˜ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์ผํ•œ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ€์ง€๋Š” ์Šคํƒ€์ผ์‹œํŠธ๋Š” `<link>` ํƒœ๊ทธ์ธ์ง€ ์ธ๋ผ์ธ `<style>` ํƒœ๊ทธ์ธ์ง€ [`preinit`](/reference/react-dom/preinit) ํ•จ์ˆ˜๋กœ ๋กœ๋“œ๋œ ๊ฒƒ์ธ์ง€์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ํ•จ๊ป˜ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. diff --git a/src/content/reference/react-dom/components/textarea.md b/src/content/reference/react-dom/components/textarea.md index 8bdb8360c..f4d2365cb 100644 --- a/src/content/reference/react-dom/components/textarea.md +++ b/src/content/reference/react-dom/components/textarea.md @@ -51,9 +51,9 @@ title: "<textarea>" * [`disabled`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#disabled): ๋ถˆ๋ฆฌ์–ธ ํƒ€์ž…. `true`์ผ ๊ฒฝ์šฐ input์€ ์ƒํ˜ธ์ž‘์šฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•ด์ง€๋ฉฐ ํ๋ฆฟํ•˜๊ฒŒ ๋ณด์ž…๋‹ˆ๋‹ค. * [`form`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#form): ๋ฌธ์ž์—ด ํƒ€์ž…. ํ…์ŠคํŠธ ์˜์—ญ input์ด ์†ํ•˜๋Š” `<form>`์˜ `id`๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ƒ๋žต ์‹œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ถ€๋ชจ ํผ์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. * [`maxLength`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#maxlength): ์ˆซ์ž ํƒ€์ž…. ํ…์ŠคํŠธ์˜ ์ตœ๋Œ€ ๊ธธ์ด๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. -* [`minLength`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#minlength): ์ˆซ์ž ํƒ€์ž…. ํ…์ŠคํŠธ์˜ ์ตœ์†Œ ๊ธธ์ด๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. +* [`minLength`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#minlength): ์ˆซ์ž ํƒ€์ž…. ํ…์ŠคํŠธ์˜ ์ตœ์†Œ ๊ธธ์ด๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. * [`name`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#name): ๋ฌธ์ž์—ด ํƒ€์ž…. [ํผ๊ณผ ์ œ์ถœ](#reading-the-textarea-value-when-submitting-a-form)๋˜๋Š” input์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. -* `onChange`: [`์ด๋ฒคํŠธ` ํ•ธ๋“ค๋Ÿฌ](/reference/react-dom/components/common#event-handler) ํ•จ์ˆ˜. [์ œ์–ด๋˜๋Š” ํ…์ŠคํŠธ ์˜์—ญ](#controlling-a-text-area-with-a-state-variable) ํ•„์ˆ˜ ์š”์†Œ๋กœ ๊ฐ€๋ น ์‚ฌ์šฉ์ž๊ฐ€ ํ‚ค๋ณด๋“œ๋ฅผ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ input ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ์ฆ‰์‹œ ์‹คํ–‰๋˜๋ฉฐ ๋ธŒ๋ผ์šฐ์ € [`input` ์ด๋ฒคํŠธ](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event)์ฒ˜๋Ÿผ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +* `onChange`: [`์ด๋ฒคํŠธ` ํ•ธ๋“ค๋Ÿฌ](/reference/react-dom/components/common#event-handler) ํ•จ์ˆ˜. [์ œ์–ด๋˜๋Š” ํ…์ŠคํŠธ ์˜์—ญ](#controlling-a-text-area-with-a-state-variable) ํ•„์ˆ˜ ์š”์†Œ๋กœ ๊ฐ€๋ น ์‚ฌ์šฉ์ž๊ฐ€ ํ‚ค๋ณด๋“œ๋ฅผ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ input ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ์ฆ‰์‹œ ์‹คํ–‰๋˜๋ฉฐ ๋ธŒ๋ผ์šฐ์ € [`input` ์ด๋ฒคํŠธ](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event)์ฒ˜๋Ÿผ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. * `onChangeCapture`: [์บก์ฒ˜ ๋‹จ๊ณ„](/learn/responding-to-events#capture-phase-events)์—์„œ ์‹คํ–‰๋˜๋Š” `onChange` * [`onInput`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event): [`์ด๋ฒคํŠธ` ํ•ธ๋“ค๋Ÿฌ](/reference/react-dom/components/common#event-handler) ํ•จ์ˆ˜. ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ์ฆ‰์‹œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€์˜ ์šฉ๋ฒ•์— ๋น„์ถฐ๋ดค์„ ๋•Œ React์—์„œ๋Š” ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋Š” `onChange`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ด€์Šต์ ์ž…๋‹ˆ๋‹ค. * `onInputCapture`: [์บก์ฒ˜ ๋‹จ๊ณ„](/learn/responding-to-events#capture-phase-events)์—์„œ ์‹คํ–‰๋˜๋Š” `onInput` diff --git a/src/content/reference/react-dom/createPortal.md b/src/content/reference/react-dom/createPortal.md index 43aa9035c..0395fd492 100644 --- a/src/content/reference/react-dom/createPortal.md +++ b/src/content/reference/react-dom/createPortal.md @@ -46,15 +46,15 @@ Portal์€ DOM ๋…ธ๋“œ์˜ ๋ฌผ๋ฆฌ์  ๋ฐฐ์น˜๋งŒ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} -* `children` : JSX์˜ ์ผ๋ถ€(์˜ˆ๋ฅผ ๋“ค์–ด `<div />` ๋˜๋Š” `<SomeComponent />`), [Fragment](/reference/react/Fragment)(`<>...</>`), ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž ๋˜๋Š” ์ด๋“ค์˜ ๋ฐฐ์—ด๊ณผ ๊ฐ™์ด React๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +* `children` : JSX์˜ ์ผ๋ถ€(์˜ˆ๋ฅผ ๋“ค์–ด `<div />` ๋˜๋Š” `<SomeComponent />`), [Fragment](/reference/react/Fragment)(`<>...</>`), ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž ๋˜๋Š” ์ด๋“ค์˜ ๋ฐฐ์—ด๊ณผ ๊ฐ™์ด React๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์ž…๋‹ˆ๋‹ค. * `domNode` : `document.getElementById()`๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ผ๋ถ€ DOM ๋…ธ๋“œ. ๋…ธ๋“œ๊ฐ€ ๋ฏธ๋ฆฌ ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ ์ค‘์— ๋‹ค๋ฅธ DOM ๋…ธ๋“œ๋ฅผ ์ „๋‹ฌํ•˜๋ฉด portal ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ค์‹œ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. -* **optional** `key`: Portal์˜ [key](/learn/rendering-lists/#keeping-list-items-in-order-with-key)๋กœ ์‚ฌ์šฉํ•  ๊ณ ์œ ํ•œ ๋ฌธ์ž์—ด ๋˜๋Š” ์ˆซ์ž์ž…๋‹ˆ๋‹ค. +* **optional** `key`: Portal์˜ [key](/learn/rendering-lists/#keeping-list-items-in-order-with-key)๋กœ ์‚ฌ์šฉํ•  ๊ณ ์œ ํ•œ ๋ฌธ์ž์—ด ๋˜๋Š” ์ˆซ์ž์ž…๋‹ˆ๋‹ค. #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} -`createPortal`์€ JSX์— ํฌํ•จํ•˜๊ฑฐ๋‚˜ React ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” React ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. React๊ฐ€ ๋ Œ๋”๋ง ์ถœ๋ ฅ์—์„œ ์ด๋ฅผ ๋ฐœ๊ฒฌํ•˜๋ฉด, ์ œ๊ณต๋œ `children`์„ ์ œ๊ณต๋œ `domNode` ์•ˆ์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค. +`createPortal`์€ JSX์— ํฌํ•จํ•˜๊ฑฐ๋‚˜ React ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” React ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. React๊ฐ€ ๋ Œ๋”๋ง ์ถœ๋ ฅ์—์„œ ์ด๋ฅผ ๋ฐœ๊ฒฌํ•˜๋ฉด, ์ œ๊ณต๋œ `children`์„ ์ œ๊ณต๋œ `domNode` ์•ˆ์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค. #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} diff --git a/src/content/reference/react-dom/flushSync.md b/src/content/reference/react-dom/flushSync.md index 703c6f4aa..8cf724d44 100644 --- a/src/content/reference/react-dom/flushSync.md +++ b/src/content/reference/react-dom/flushSync.md @@ -61,7 +61,7 @@ flushSync(() => { ### ์„œ๋“œ ํŒŒํ‹ฐ ํ†ตํ•ฉ์„ ์œ„ํ•œ ์—…๋ฐ์ดํŠธ flushing {/*flushing-updates-for-third-party-integrations*/} -๋ธŒ๋ผ์šฐ์ € API ๋˜๋Š” UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ฐ™์€ ์„œ๋“œ ํŒŒํ‹ฐ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ฉํ•  ๋•Œ React๊ฐ€ ์—…๋ฐ์ดํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๊ฐ•์ œํ•  ํ•„์š”๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `flushSync`๋ฅผ ์‚ฌ์šฉํ•ด์„œ React๊ฐ€ ์ฝœ๋ฐฑ ๋‚ด๋ถ€์˜ ๋ชจ๋“  <CodeStep step={1}>state updates</CodeStep>๋ฅผ ๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ธŒ๋ผ์šฐ์ € API ๋˜๋Š” UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ฐ™์€ ์„œ๋“œ ํŒŒํ‹ฐ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ฉํ•  ๋•Œ React๊ฐ€ ์—…๋ฐ์ดํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๊ฐ•์ œํ•  ํ•„์š”๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `flushSync`๋ฅผ ์‚ฌ์šฉํ•ด์„œ React๊ฐ€ ์ฝœ๋ฐฑ ๋‚ด๋ถ€์˜ ๋ชจ๋“  <CodeStep step={1}>state updates</CodeStep>๋ฅผ ๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js [[1, 2, "setSomething(123)"]] flushSync(() => { diff --git a/src/content/reference/react-dom/hooks/useFormStatus.md b/src/content/reference/react-dom/hooks/useFormStatus.md index d067fc2a3..7d4bffbfb 100644 --- a/src/content/reference/react-dom/hooks/useFormStatus.md +++ b/src/content/reference/react-dom/hooks/useFormStatus.md @@ -129,7 +129,7 @@ export async function submitForm(query) { "devDependencies": {} } ``` -</Sandpack> +</Sandpack> <Pitfall> @@ -151,7 +151,7 @@ function Form() { ```js function Submit() { // โœ… `pending`์€ Submit ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ์‹ธ๋Š” ํผ์—์„œ ํŒŒ์ƒ๋ฉ๋‹ˆ๋‹ค - const { pending } = useFormStatus(); + const { pending } = useFormStatus(); return <button disabled={pending}>...</button>; } @@ -245,7 +245,7 @@ button { "devDependencies": {} } ``` -</Sandpack> +</Sandpack> --- diff --git a/src/content/reference/react-dom/preinit.md b/src/content/reference/react-dom/preinit.md index 49791b104..ffe254f47 100644 --- a/src/content/reference/react-dom/preinit.md +++ b/src/content/reference/react-dom/preinit.md @@ -54,10 +54,10 @@ The `preinit` function provides the browser with a hint that it should start dow * `href`: a string. The URL of the resource you want to download and execute. * `options`: an object. It contains the following properties: * `as`: a required string. The type of resource. Its possible values are `script` and `style`. - * `precedence`: a string. Required with stylesheets. Says where to insert the stylesheet relative to others. Stylesheets with higher precedence can override those with lower precedence. The possible values are `reset`, `low`, `medium`, `high`. + * `precedence`: a string. Required with stylesheets. Says where to insert the stylesheet relative to others. Stylesheets with higher precedence can override those with lower precedence. The possible values are `reset`, `low`, `medium`, `high`. * `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`. It is required when `as` is set to `"fetch"`. * `integrity`: a string. A cryptographic hash of the resource, to [verify its authenticity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity). - * `nonce`: a string. A cryptographic [nonce to allow the resource](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) when using a strict Content Security Policy. + * `nonce`: a string. A cryptographic [nonce to allow the resource](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) when using a strict Content Security Policy. * `fetchPriority`: a string. Suggests a relative priority for fetching the resource. The possible values are `auto` (the default), `high`, and `low`. #### Returns {/*returns*/} diff --git a/src/content/reference/react-dom/preinitModule.md b/src/content/reference/react-dom/preinitModule.md index 5f9be6d50..6039970c9 100644 --- a/src/content/reference/react-dom/preinitModule.md +++ b/src/content/reference/react-dom/preinitModule.md @@ -56,7 +56,7 @@ The `preinitModule` function provides the browser with a hint that it should sta * `as`: a required string. It must be `'script'`. * `crossOrigin`: a string. The [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) to use. Its possible values are `anonymous` and `use-credentials`. * `integrity`: a string. A cryptographic hash of the module, to [verify its authenticity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity). - * `nonce`: a string. A cryptographic [nonce to allow the module](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) when using a strict Content Security Policy. + * `nonce`: a string. A cryptographic [nonce to allow the module](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) when using a strict Content Security Policy. #### Returns {/*returns*/} diff --git a/src/content/reference/react-dom/preloadModule.md b/src/content/reference/react-dom/preloadModule.md index 44cb27a37..108701c26 100644 --- a/src/content/reference/react-dom/preloadModule.md +++ b/src/content/reference/react-dom/preloadModule.md @@ -67,7 +67,7 @@ function AppRoot() { #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} * ๋™์ผํ•œ `href`๋กœ `preloadModule`์„ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ํšจ๊ณผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -* ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์ค‘์ด๊ฑฐ๋‚˜, Effect, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋“ฑ ์–ด๋–ค ์ƒํ™ฉ์—์„œ๋„ `preloadModule`์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์ค‘์ด๊ฑฐ๋‚˜, Effect, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋“ฑ ์–ด๋–ค ์ƒํ™ฉ์—์„œ๋„ `preloadModule`์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง์ด๋‚˜ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ, `preloadModule`์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜, ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง์—์„œ ์‹œ์ž‘๋œ ๋น„๋™๊ธฐ ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ ํ˜ธ์ถœํ•  ๋•Œ๋งŒ ํšจ๊ณผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์™ธ์˜ ํ˜ธ์ถœ์€ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค. --- diff --git a/src/content/reference/react-dom/server/renderToPipeableStream.md b/src/content/reference/react-dom/server/renderToPipeableStream.md index 2f3e95334..0f3a78da4 100644 --- a/src/content/reference/react-dom/server/renderToPipeableStream.md +++ b/src/content/reference/react-dom/server/renderToPipeableStream.md @@ -401,7 +401,7 @@ const { pipe } = renderToPipeableStream(<App />, { onShellError(error) { response.statusCode = 500; response.setHeader('content-type', 'text/html'); - response.send('<h1>Something went wrong</h1>'); + response.send('<h1>Something went wrong</h1>'); }, onError(error) { console.error(error); @@ -433,8 +433,8 @@ function ProfilePage() { `Posts` ์ปดํฌ๋„ŒํŠธ ๋˜๋Š” ๊ทธ ๋‚ด๋ถ€ ์–ด๋”˜๊ฐ€์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด React๋Š” [์ด๋ฅผ ๋ณต๊ตฌํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content) -1. ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<Suspense>` ๊ฒฝ๊ณ„(`PostsGlimmer`)์— ๋Œ€ํ•œ ๋กœ๋”ฉ ํด๋ฐฑ์„ HTML๋กœ ๋ฐฉ์ถœํ•ฉ๋‹ˆ๋‹ค. -2. ๋” ์ด์ƒ ์„œ๋ฒ„์—์„œ `Posts` ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์„ "ํฌ๊ธฐ"ํ•ฉ๋‹ˆ๋‹ค. +1. ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<Suspense>` ๊ฒฝ๊ณ„(`PostsGlimmer`)์— ๋Œ€ํ•œ ๋กœ๋”ฉ ํด๋ฐฑ์„ HTML๋กœ ๋ฐฉ์ถœํ•ฉ๋‹ˆ๋‹ค. +2. ๋” ์ด์ƒ ์„œ๋ฒ„์—์„œ `Posts` ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์„ "ํฌ๊ธฐ"ํ•ฉ๋‹ˆ๋‹ค. 3. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋กœ๋“œ๋˜๋ฉด React๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ `Posts` ๋ Œ๋”๋ง์„ *์žฌ์‹œ๋„*ํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ `Posts` ๋ Œ๋”๋ง์„ *๋‹ค์‹œ ์‹œ๋„ํ•ด๋„* ์‹คํŒจํ•˜๋ฉด React๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์—๋Ÿฌ๋ฅผ ๋˜์ง‘๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ์—๋Ÿฌ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, [๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ถ€๋ชจ ์—๋Ÿฌ ๊ฒฝ๊ณ„](/reference/react/Component#static-getderivedstatefromerror)์— ๋”ฐ๋ผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์—๋Ÿฌ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ณต๊ตฌํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด ํ™•์‹คํ•ด์งˆ ๋•Œ๊นŒ์ง€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋กœ๋”ฉ ํ‘œ์‹œ๊ธฐ๊ฐ€ ํ‘œ์‹œ๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. @@ -460,7 +460,7 @@ const { pipe } = renderToPipeableStream(<App />, { onShellError(error) { response.statusCode = 500; response.setHeader('content-type', 'text/html'); - response.send('<h1>Something went wrong</h1>'); + response.send('<h1>Something went wrong</h1>'); }, onError(error) { console.error(error); @@ -486,7 +486,7 @@ const { pipe } = renderToPipeableStream(<App />, { onShellError(error) { response.statusCode = 500; response.setHeader('content-type', 'text/html'); - response.send('<h1>Something went wrong</h1>'); + response.send('<h1>Something went wrong</h1>'); }, onError(error) { didError = true; @@ -531,7 +531,7 @@ const { pipe } = renderToPipeableStream(<App />, { onShellError(error) { response.statusCode = getStatusCode(); response.setHeader('content-type', 'text/html'); - response.send('<h1>Something went wrong</h1>'); + response.send('<h1>Something went wrong</h1>'); }, onError(error) { didError = true; @@ -570,13 +570,13 @@ const { pipe } = renderToPipeableStream(<App />, { onShellError(error) { response.statusCode = 500; response.setHeader('content-type', 'text/html'); - response.send('<h1>Something went wrong</h1>'); + response.send('<h1>Something went wrong</h1>'); }, onAllReady() { if (isCrawler) { response.statusCode = didError ? 500 : 200; response.setHeader('content-type', 'text/html'); - pipe(response); + pipe(response); } }, onError(error) { diff --git a/src/content/reference/react-dom/server/renderToStaticMarkup.md b/src/content/reference/react-dom/server/renderToStaticMarkup.md index d44986bb7..af49f806a 100644 --- a/src/content/reference/react-dom/server/renderToStaticMarkup.md +++ b/src/content/reference/react-dom/server/renderToStaticMarkup.md @@ -37,7 +37,7 @@ const html = renderToStaticMarkup(<Page />); * `reactNode`: HTML๋กœ ๋ Œ๋”๋งํ•  React ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `<Page />`์™€ ๊ฐ™์€ JSX ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. * **optional** `options`: ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์œ„ํ•œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. * **optional** `identifierPrefix`: [`useId`.](/reference/react/useId)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ID์— ๋Œ€ํ•ด React๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ ‘๋‘์‚ฌ์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ ๋ฃจํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. - + #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} HTML ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. diff --git a/src/content/reference/react/Children.md b/src/content/reference/react/Children.md index 9ce29cb57..d1955b689 100644 --- a/src/content/reference/react/Children.md +++ b/src/content/reference/react/Children.md @@ -863,7 +863,7 @@ export default function App() { return ( <Row isHighlighted={index % 2 === 0}> <p>This is the {id} item.</p> - </Row> + </Row> ); }} /> diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index 9c8047539..367380d9f 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -129,7 +129,7 @@ class Counter extends Component { handleAgeChange = () => { this.setState({ - age: this.state.age + 1 + age: this.state.age + 1 }); }; @@ -1174,7 +1174,7 @@ export default class Counter extends Component { handleAgeChange = () => { this.setState({ - age: this.state.age + 1 + age: this.state.age + 1 }); }; @@ -1199,7 +1199,7 @@ export default class Counter extends Component { button { display: block; margin-top: 10px; } ``` -</Sandpack> +</Sandpack> <Pitfall> @@ -1283,7 +1283,7 @@ export default class ChatRoom extends Component { this.state.serverUrl, this.props.roomId ); - this.connection.connect(); + this.connection.connect(); } destroyConnection() { @@ -1496,7 +1496,7 @@ export default class Counter extends Component { handleAgeChange = (e) => { this.setState({ - age: this.state.age + 1 + age: this.state.age + 1 }); }; @@ -1663,7 +1663,7 @@ export default class ChatRoom extends Component { this.state.serverUrl, this.props.roomId ); - this.connection.connect(); + this.connection.connect(); } destroyConnection() { @@ -1852,7 +1852,7 @@ class Panel extends Component { <h1>{this.props.title}</h1> {this.props.children} </section> - ); + ); } } diff --git a/src/content/reference/react/Profiler.md b/src/content/reference/react/Profiler.md index cf6100acf..03c3e3174 100644 --- a/src/content/reference/react/Profiler.md +++ b/src/content/reference/react/Profiler.md @@ -125,7 +125,7 @@ React ํŠธ๋ฆฌ๋ฅผ `<Profiler>` ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ์‹ธ์„œ ๋ Œ๋”๋ง ์„ฑ๋Šฅ์„ ์ธก </App> ``` -`<Profiler>`๋Š” ๊ฐ€๋ฒผ์šด ์ปดํฌ๋„ŒํŠธ์ด์ง€๋งŒ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์•ฝ๊ฐ„์˜ CPU ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +`<Profiler>`๋Š” ๊ฐ€๋ฒผ์šด ์ปดํฌ๋„ŒํŠธ์ด์ง€๋งŒ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์•ฝ๊ฐ„์˜ CPU ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. --- diff --git a/src/content/reference/react/PureComponent.md b/src/content/reference/react/PureComponent.md index 39b1c6806..7a58eddd6 100644 --- a/src/content/reference/react/PureComponent.md +++ b/src/content/reference/react/PureComponent.md @@ -204,6 +204,6 @@ label { <Note> -`PureComponent`์™€ ๋‹ฌ๋ฆฌ [`memo`](/reference/react/memo)๋Š” ์ƒˆ state์™€ ์ด์ „ state๋ฅผ ๋น„๊ตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋™์ผํ•œ state๋กœ [`set` ํ•จ์ˆ˜](/reference/react/useState#setstate)๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด [๊ธฐ๋ณธ์ ์œผ๋กœ `memo` ์—†์ด๋„ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.](/reference/react/memo#updating-a-memoized-component-using-state) +`PureComponent`์™€ ๋‹ฌ๋ฆฌ [`memo`](/reference/react/memo)๋Š” ์ƒˆ state์™€ ์ด์ „ state๋ฅผ ๋น„๊ตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋™์ผํ•œ state๋กœ [`set` ํ•จ์ˆ˜](/reference/react/useState#setstate)๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด [๊ธฐ๋ณธ์ ์œผ๋กœ `memo` ์—†์ด๋„ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.](/reference/react/memo#updating-a-memoized-component-using-state) </Note> diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index 9c0fa1a4c..4ca6cebbd 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -24,7 +24,7 @@ title: <Suspense> ### `<Suspense>` {/*suspense*/} #### Props {/*props*/} -* `children`: ๊ถ๊ทน์ ์œผ๋กœ ๋ Œ๋”๋งํ•˜๋ ค๋Š” ์‹ค์ œ UI์ž…๋‹ˆ๋‹ค. `children`์˜ ๋ Œ๋”๋ง์ด ์ง€์—ฐ๋˜๋ฉด, Suspense๋Š” `fallback`์„ ๋Œ€์‹  ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. +* `children`: ๊ถ๊ทน์ ์œผ๋กœ ๋ Œ๋”๋งํ•˜๋ ค๋Š” ์‹ค์ œ UI์ž…๋‹ˆ๋‹ค. `children`์˜ ๋ Œ๋”๋ง์ด ์ง€์—ฐ๋˜๋ฉด, Suspense๋Š” `fallback`์„ ๋Œ€์‹  ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. * `fallback`: ์‹ค์ œ UI๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „๊นŒ์ง€ ๋Œ€์‹  ๋ Œ๋”๋ง ๋˜๋Š” ๋Œ€์ฒด UI์ž…๋‹ˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ React node ํ˜•์‹์€ ๋ฌด์—‡์ด๋“  ๋Œ€์ฒด UI๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” ๋ณดํ†ต ๋กœ๋”ฉ ์Šคํ”ผ๋„ˆ๋‚˜ ์Šค์ผˆ๋ ˆํ†ค์ฒ˜๋Ÿผ ๊ฐ„๋‹จํ•œ placeholder๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. Suspense๋Š” `children`์˜ ๋ Œ๋”๋ง์ด ์ง€์—ฐ๋˜๋ฉด ์ž๋™์œผ๋กœ `fallback`์œผ๋กœ ์ „ํ™˜ํ•˜๊ณ , ๋ฐ์ดํ„ฐ๊ฐ€ ์ค€๋น„๋˜๋ฉด `children`์œผ๋กœ ๋‹ค์‹œ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ `fallback`์˜ ๋ Œ๋”๋ง์ด ์ง€์—ฐ๋˜๋ฉด, ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ถ€๋ชจ Suspense๊ฐ€ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} @@ -155,7 +155,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -397,7 +397,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -445,7 +445,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -482,9 +482,9 @@ async function getBio() { setTimeout(resolve, 1500); }); - return `The Beatles were an English rock band, - formed in Liverpool in 1960, that comprised - John Lennon, Paul McCartney, George Harrison + return `The Beatles were an English rock band, + formed in Liverpool in 1960, that comprised + John Lennon, Paul McCartney, George Harrison and Ringo Starr.`; } @@ -734,7 +734,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -782,7 +782,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -819,9 +819,9 @@ async function getBio() { setTimeout(resolve, 500); }); - return `The Beatles were an English rock band, - formed in Liverpool in 1960, that comprised - John Lennon, Paul McCartney, George Harrison + return `The Beatles were an English rock band, + formed in Liverpool in 1960, that comprised + John Lennon, Paul McCartney, George Harrison and Ringo Starr.`; } @@ -1011,7 +1011,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -1143,7 +1143,7 @@ export default function App() { ```js {2} <div style={{ - opacity: query !== deferredQuery ? 0.5 : 1 + opacity: query !== deferredQuery ? 0.5 : 1 }}> <SearchResults query={deferredQuery} /> </div> @@ -1239,7 +1239,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -1519,7 +1519,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -1563,7 +1563,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -1610,9 +1610,9 @@ async function getBio() { setTimeout(resolve, 500); }); - return `The Beatles were an English rock band, - formed in Liverpool in 1960, that comprised - John Lennon, Paul McCartney, George Harrison + return `The Beatles were an English rock band, + formed in Liverpool in 1960, that comprised + John Lennon, Paul McCartney, George Harrison and Ringo Starr.`; } @@ -1734,7 +1734,7 @@ function Router() { function navigate(url) { startTransition(() => { - setPage(url); + setPage(url); }); } // ... @@ -1906,7 +1906,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -1950,7 +1950,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -1997,9 +1997,9 @@ async function getBio() { setTimeout(resolve, 500); }); - return `The Beatles were an English rock band, - formed in Liverpool in 1960, that comprised - John Lennon, Paul McCartney, George Harrison + return `The Beatles were an English rock band, + formed in Liverpool in 1960, that comprised + John Lennon, Paul McCartney, George Harrison and Ringo Starr.`; } @@ -2292,7 +2292,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -2336,7 +2336,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -2383,9 +2383,9 @@ async function getBio() { setTimeout(resolve, 500); }); - return `The Beatles were an English rock band, - formed in Liverpool in 1960, that comprised - John Lennon, Paul McCartney, George Harrison + return `The Beatles were an English rock band, + formed in Liverpool in 1960, that comprised + John Lennon, Paul McCartney, George Harrison and Ringo Starr.`; } diff --git a/src/content/reference/react/act.md b/src/content/reference/react/act.md index c01f3cd69..019a3a761 100644 --- a/src/content/reference/react/act.md +++ b/src/content/reference/react/act.md @@ -96,12 +96,12 @@ import Counter from './Counter'; it('can render and update a counter', async () => { container = document.createElement('div'); document.body.appendChild(container); - + // โœ… Render the component inside act(). await act(() => { ReactDOMClient.createRoot(container).render(<Counter />); }); - + const button = container.querySelector('button'); const label = container.querySelector('p'); expect(label.textContent).toBe('You clicked 0 times'); @@ -125,11 +125,11 @@ import Counter from './Counter'; it.only('can render and update a counter', async () => { const container = document.createElement('div'); document.body.appendChild(container); - + await act( async () => { ReactDOMClient.createRoot(container).render(<Counter />); }); - + // โœ… Dispatch the event inside act(). await act(async () => { button.dispatchEvent(new MouseEvent('click', { bubbles: true })); diff --git a/src/content/reference/react/cache.md b/src/content/reference/react/cache.md index cf9befad9..5f6ee0b89 100644 --- a/src/content/reference/react/cache.md +++ b/src/content/reference/react/cache.md @@ -194,7 +194,7 @@ async function MinimalWeatherCard({city}) { `AnimatedWeatherCard`์™€ `MinimalWeatherCard`๊ฐ€ ๊ฐ™์€ <CodeStep step={1}>city</CodeStep>๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ, <CodeStep step={2}>๋ฉ”๋ชจํ™”๋œ ํ•จ์ˆ˜</CodeStep>๋กœ ๋ถ€ํ„ฐ ๊ฐ™์€ ๋ฐ์ดํ„ฐ์˜ ์Šค๋ƒ…์ƒท์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -`AnimatedWeatherCard`์™€ `MinimalWeatherCard`๊ฐ€ ๋‹ค๋ฅธ <CodeStep step={1}>city</CodeStep>๋ฅผ <CodeStep step={2}>`getTemperature`</CodeStep>์˜ ์ธ์ž๋กœ ๋ฐ›๊ฒŒ ๋œ๋‹ค๋ฉด, `fetchTemperature`๋Š” ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋˜๊ณ  ํ˜ธ์ถœ๋งˆ๋‹ค ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +`AnimatedWeatherCard`์™€ `MinimalWeatherCard`๊ฐ€ ๋‹ค๋ฅธ <CodeStep step={1}>city</CodeStep>๋ฅผ <CodeStep step={2}>`getTemperature`</CodeStep>์˜ ์ธ์ž๋กœ ๋ฐ›๊ฒŒ ๋œ๋‹ค๋ฉด, `fetchTemperature`๋Š” ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋˜๊ณ  ํ˜ธ์ถœ๋งˆ๋‹ค ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. <CodeStep step={1}>city</CodeStep>๊ฐ€ ์บ์‹œ ํ‚ค์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. @@ -243,7 +243,7 @@ function Page({id}) { } ``` -`Page`๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ, ์ปดํฌ๋„ŒํŠธ๋Š” <CodeStep step={1}>`getUser`</CodeStep>๋ฅผ ํ˜ธ์ถœํ•˜์ง€๋งŒ, ๋ฐ˜ํ™˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”. ์ด ์ดˆ๊ธฐ <CodeStep step={1}>`getUser`</CodeStep> ํ˜ธ์ถœ์€ ํŽ˜์ด์ง€๊ฐ€ ๋‹ค๋ฅธ ๊ณ„์‚ฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ž์‹์„ ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ ๋ฐœ์ƒํ•˜๋Š”, ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฟผ๋ฆฌ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. +`Page`๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ, ์ปดํฌ๋„ŒํŠธ๋Š” <CodeStep step={1}>`getUser`</CodeStep>๋ฅผ ํ˜ธ์ถœํ•˜์ง€๋งŒ, ๋ฐ˜ํ™˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”. ์ด ์ดˆ๊ธฐ <CodeStep step={1}>`getUser`</CodeStep> ํ˜ธ์ถœ์€ ํŽ˜์ด์ง€๊ฐ€ ๋‹ค๋ฅธ ๊ณ„์‚ฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ž์‹์„ ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ ๋ฐœ์ƒํ•˜๋Š”, ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฟผ๋ฆฌ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. `Profile`์„ ๋ Œ๋”๋งํ•  ๋•Œ, <CodeStep step={2}>`getUser`</CodeStep>๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ดˆ๊ธฐ <CodeStep step={1}>`getUser`</CodeStep> ํ˜ธ์ถœ์ด ์ด๋ฏธ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ์— ๋ฐ˜ํ™˜๋˜๊ณ  ์บ์‹ฑ ๋˜์—ˆ๋‹ค๋ฉด, `Profile`์ด <CodeStep step={2}>ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ณ  ๊ธฐ๋‹ค๋ฆด ๋•Œ</CodeStep>, ๋‹ค๋ฅธ ์›๊ฒฉ ํ”„๋กœ์‹œ์ € ํ˜ธ์ถœ ์—†์ด ์‰ฝ๊ฒŒ ์บ์‹œ์—์„œ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <CodeStep step={1}> ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ ์š”์ฒญ</CodeStep>์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ์ด ํŒจํ„ด์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ฌ ๋•Œ ์ƒ๊ธฐ๋Š” ์ง€์—ฐ์ด ์ค„์–ด๋“ญ๋‹ˆ๋‹ค. @@ -264,7 +264,7 @@ const getData = cache(fetchData); async function MyComponent() { getData(); - // ... some computational work + // ... some computational work await getData(); // ... } @@ -274,7 +274,7 @@ async function MyComponent() { ์ฒซ ๋ฒˆ์งธ <CodeStep step={2}>`getData`</CodeStep> ํ˜ธ์ถœ์€ `๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์ง€๋งŒ(await)` <CodeStep step={3}>๋‘ ๋ฒˆ์งธ</CodeStep>๋Š” ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. [`await`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/await) ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—ฐ์‚ฐ์ž๋กœ, ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ํ™•์ •๋œ Promise์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ <CodeStep step={2}>`getData`</CodeStep>์€ ๋‹จ์ˆœํžˆ ์กฐํšŒํ•  ๋‘ ๋ฒˆ์งธ <CodeStep step={3}>`getData`</CodeStep>์— ๋Œ€ํ•œ Promise๋ฅผ ์บ์‹ฑํ•˜๊ธฐ ์œ„ํ•ด `fetch`๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. -<CodeStep step={3}>๋‘ ๋ฒˆ์งธ ํ˜ธ์ถœ</CodeStep>์—์„œ Promise๊ฐ€ ์—ฌ์ „ํžˆ <em>๋ณด๋ฅ˜ ์ค‘</em>์ด๋ฉด, ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ `await`๊ฐ€ ์ผ์‹œ ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค. ์ด ์ตœ์ ํ™”๋Š” ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ React๊ฐ€ ๊ณ„์‚ฐ ์ž‘์—…์„ ๊ณ„์†ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด <CodeStep step={3}>๋‘ ๋ฒˆ์งธ ํ˜ธ์ถœ</CodeStep>์— ๋Œ€ํ•œ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. +<CodeStep step={3}>๋‘ ๋ฒˆ์งธ ํ˜ธ์ถœ</CodeStep>์—์„œ Promise๊ฐ€ ์—ฌ์ „ํžˆ <em>๋ณด๋ฅ˜ ์ค‘</em>์ด๋ฉด, ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ `await`๊ฐ€ ์ผ์‹œ ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค. ์ด ์ตœ์ ํ™”๋Š” ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ React๊ฐ€ ๊ณ„์‚ฐ ์ž‘์—…์„ ๊ณ„์†ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด <CodeStep step={3}>๋‘ ๋ฒˆ์งธ ํ˜ธ์ถœ</CodeStep>์— ๋Œ€ํ•œ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. _์™„๋ฃŒ๋œ_ ๊ฒฐ๊ณผ๋‚˜ ์—๋Ÿฌ์— ๋Œ€ํ•œ Promise๊ฐ€ ์ด๋ฏธ ์ •ํ•ด์ง„ ๊ฒฝ์šฐ, `await`๋Š” ์ฆ‰์‹œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฒฐ๊ณผ ๋ชจ๋‘ ์„ฑ๋Šฅ์ƒ์˜ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. </DeepDive> @@ -373,7 +373,7 @@ function App() { 'use client'; function WeatherReport({record}) { - const avgTemp = calculateAvg(record); + const avgTemp = calculateAvg(record); // ... } diff --git a/src/content/reference/react/cloneElement.md b/src/content/reference/react/cloneElement.md index 767585af2..99cc1c514 100644 --- a/src/content/reference/react/cloneElement.md +++ b/src/content/reference/react/cloneElement.md @@ -103,7 +103,7 @@ export default function List({ children }) { <div className="List"> {Children.map(children, (child, index) => cloneElement(child, { - isHighlighted: index === selectedIndex + isHighlighted: index === selectedIndex }) )} ``` @@ -124,15 +124,15 @@ export default function List({ children }) { <List> <Row title="Cabbage" - isHighlighted={true} + isHighlighted={true} /> <Row title="Garlic" - isHighlighted={false} + isHighlighted={false} /> <Row title="Apple" - isHighlighted={false} + isHighlighted={false} /> </List> ``` @@ -152,7 +152,7 @@ export default function App() { {products.map(product => <Row key={product.id} - title={product.title} + title={product.title} /> )} </List> @@ -169,7 +169,7 @@ export default function List({ children }) { <div className="List"> {Children.map(children, (child, index) => cloneElement(child, { - isHighlighted: index === selectedIndex + isHighlighted: index === selectedIndex }) )} <hr /> @@ -280,15 +280,15 @@ export default function List({ items, renderItem }) { <List> <Row title="Cabbage" - isHighlighted={true} + isHighlighted={true} /> <Row title="Garlic" - isHighlighted={false} + isHighlighted={false} /> <Row title="Apple" - isHighlighted={false} + isHighlighted={false} /> </List> ``` diff --git a/src/content/reference/react/createElement.md b/src/content/reference/react/createElement.md index ddf8dc12a..9d5e2f8e2 100644 --- a/src/content/reference/react/createElement.md +++ b/src/content/reference/react/createElement.md @@ -39,7 +39,7 @@ function Greeting({ name }) { #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} * `type`: `type` ์ธ์ˆ˜๋Š” ์œ ํšจํ•œ React ์ปดํฌ๋„ŒํŠธ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํƒœ๊ทธ ์ด๋ฆ„ ๋ฌธ์ž์—ด (์˜ˆ: 'div', 'span') ๋˜๋Š” React ์ปดํฌ๋„ŒํŠธ(ํ•จ์ˆ˜, ํด๋ž˜์Šค, [`Fragment`](/reference/react/Fragment) ๊ฐ™์€ ํŠน์ˆ˜ ์ปดํฌ๋„ŒํŠธ)๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - + * `props`: `props` ์ธ์ˆ˜๋Š” ๊ฐ์ฒด ๋˜๋Š” `null`์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `null`์„ ์ „๋‹ฌํ•˜๋ฉด ๋นˆ ๊ฐ์ฒด์™€ ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. React๋Š” ์ „๋‹ฌํ•œ `props`์™€ ์ผ์น˜ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ „๋‹ฌํ•œ `props` ๊ฐ์ฒด์˜ `ref`์™€ `key`๋Š” ํŠน์ˆ˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑํ•œ `element`์—์„œ `element.props.ref` ์™€ `element.props.key`๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ *์—†๋‹ค*๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”. `element.ref` ๋˜๋Š” `element.key`๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **์„ ํƒ์‚ฌํ•ญ** `...children`: 0๊ฐœ ์ด์ƒ์˜ ์ž์‹ ๋…ธ๋“œ. React ์—˜๋ฆฌ๋จผํŠธ, ๋ฌธ์ž์—ด, ์ˆซ์ž, [ํฌํƒˆ](/reference/react-dom/createPortal), ๋นˆ ๋…ธ๋“œ(`null`, `undefined`, `true`, `false`) ๊ทธ๋ฆฌ๊ณ  React ๋…ธ๋“œ ๋ฐฐ์—ด์„ ํฌํ•จํ•œ ๋ชจ๋“  React ๋…ธ๋“œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/src/content/reference/react/createFactory.md b/src/content/reference/react/createFactory.md index 725611449..2d5f423af 100644 --- a/src/content/reference/react/createFactory.md +++ b/src/content/reference/react/createFactory.md @@ -34,7 +34,7 @@ import { createFactory } from 'react'; const button = createFactory('button'); ``` -์ดํ›„ JSX ์—†์ด React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด, ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ดํ›„ JSX ์—†์ด React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด, ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js export default function App() { @@ -54,7 +54,7 @@ export default function App() { #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} -ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์ž์‹ ์ธ์ˆ˜์˜ ๋ฆฌ์ŠคํŠธ์— ๋’ค์ด์–ด, ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ `props` ๊ฐ์ฒด๋ฅผ ๋ฐ›์œผ๋ฉฐ, ์ฃผ์–ด์ง„ `types`, `props` ๊ทธ๋ฆฌ๊ณ  `์ž์‹`์„ ๊ฐ€์ง„ React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์ž์‹ ์ธ์ˆ˜์˜ ๋ฆฌ์ŠคํŠธ์— ๋’ค์ด์–ด, ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ `props` ๊ฐ์ฒด๋ฅผ ๋ฐ›์œผ๋ฉฐ, ์ฃผ์–ด์ง„ `types`, `props` ๊ทธ๋ฆฌ๊ณ  `์ž์‹`์„ ๊ฐ€์ง„ React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. --- @@ -134,7 +134,7 @@ export function createFactory(type) { ### `createFactory`๋ฅผ `createElement`๋กœ ๋Œ€์ฒดํ•˜๊ธฐ {/*replacing-createfactory-with-createelement*/} -์ง์ ‘ ์˜ฎ๊ฒจ์™€๋„ ๋ฌด๋ฐฉํ•  ์ •๋„๋กœ `createFactory`๋ฅผ ๋ช‡ ๊ฐœ๋งŒ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๊ณ  JSX๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด, [`createElement`](/reference/react/createElement)๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ด ์ฝ”๋“œ๋Š”, +์ง์ ‘ ์˜ฎ๊ฒจ์™€๋„ ๋ฌด๋ฐฉํ•  ์ •๋„๋กœ `createFactory`๋ฅผ ๋ช‡ ๊ฐœ๋งŒ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๊ณ  JSX๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด, [`createElement`](/reference/react/createElement)๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ด ์ฝ”๋“œ๋Š”, ```js {1,3,6} diff --git a/src/content/reference/react/forwardRef.md b/src/content/reference/react/forwardRef.md index e849fca32..191125e5b 100644 --- a/src/content/reference/react/forwardRef.md +++ b/src/content/reference/react/forwardRef.md @@ -328,7 +328,7 @@ const FormField = forwardRef(function FormField({ label, isRequired }, ref) { ref={ref} label={label} value={value} - onChange={e => setValue(e.target.value)} + onChange={e => setValue(e.target.value)} /> {(isRequired && value === '') && <i>Required</i> diff --git a/src/content/reference/react/memo.md b/src/content/reference/react/memo.md index 687b766bd..e0437458a 100644 --- a/src/content/reference/react/memo.md +++ b/src/content/reference/react/memo.md @@ -34,7 +34,7 @@ const SomeComponent = memo(function SomeComponent(props) { #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} -* `Component`: memoize ํ•˜๋ ค๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. `memo`๋Š” ์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  ์ƒˆ๋กœ์šด memoized ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜์™€ [`forwardRef`](/reference/react/forwardRef) ์ปดํฌ๋„ŒํŠธ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ์œ ํšจํ•œ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. +* `Component`: memoize ํ•˜๋ ค๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. `memo`๋Š” ์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  ์ƒˆ๋กœ์šด memoized ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜์™€ [`forwardRef`](/reference/react/forwardRef) ์ปดํฌ๋„ŒํŠธ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ์œ ํšจํ•œ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค. * **optional** `arePropsEqual`: ์ปดํฌ๋„ŒํŠธ์˜ ์ด์ „ props์™€ ์ƒˆ๋กœ์šด props์˜ ๋‘ ๊ฐ€์ง€ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ด์ „ props์™€ ์ƒˆ๋กœ์šด props๊ฐ€ ๋™์ผํ•œ ๊ฒฝ์šฐ, ์ฆ‰ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ด์ „ props์™€ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ  ์ƒˆ๋กœ์šด props์—์„œ๋„ ์ด์ „ props์™€ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ `true`๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด `false`๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ด ํ•จ์ˆ˜๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. React๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ [`Object.is`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/is)๋กœ ๊ฐ props๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. @@ -221,7 +221,7 @@ export default function MyApp() { const [theme, setTheme] = useState('dark'); function handleClick() { - setTheme(theme === 'dark' ? 'light' : 'dark'); + setTheme(theme === 'dark' ? 'light' : 'dark'); } return ( diff --git a/src/content/reference/react/use.md b/src/content/reference/react/use.md index f3deb228a..901099326 100644 --- a/src/content/reference/react/use.md +++ b/src/content/reference/react/use.md @@ -74,7 +74,7 @@ import { use } from 'react'; function Button() { const theme = use(ThemeContext); - // ... + // ... ``` `use`๋Š” ์ „๋‹ฌํ•œ <CodeStep step={1}>context</CodeStep>์˜ <CodeStep step={2}>context ๊ฐ’</CodeStep>์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. context ๊ฐ’์„ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด React๋Š” ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  **์œ„์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด context provider**๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. diff --git a/src/content/reference/react/useActionState.md b/src/content/reference/react/useActionState.md index f24569478..0a91375f4 100644 --- a/src/content/reference/react/useActionState.md +++ b/src/content/reference/react/useActionState.md @@ -80,7 +80,7 @@ Server Action๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, `useActionState`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ hy #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} * React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง€์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ, `useActionState`๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ด์ „์—๋„ ํผ์„ ์ƒํ˜ธ์ž‘์šฉํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ ์ง€์—ญ state์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. -* `useActionState`์— ์ „๋‹ฌํ•œ ํ•จ์ˆ˜๋Š” ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ด์ „ ํ˜น์€ ์ดˆ๊ธฐ state๋ฅผ ์ถ”๊ฐ€๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด `useActionState`๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ง์ ‘ ํผ ์•ก์…˜์„ ์‚ฌ์šฉํ–ˆ์„ ๊ฒฝ์šฐ์™€๋Š” ๋‹ค๋ฅธ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +* `useActionState`์— ์ „๋‹ฌํ•œ ํ•จ์ˆ˜๋Š” ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ด์ „ ํ˜น์€ ์ดˆ๊ธฐ state๋ฅผ ์ถ”๊ฐ€๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด `useActionState`๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ง์ ‘ ํผ ์•ก์…˜์„ ์‚ฌ์šฉํ–ˆ์„ ๊ฒฝ์šฐ์™€๋Š” ๋‹ค๋ฅธ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. --- diff --git a/src/content/reference/react/useCallback.md b/src/content/reference/react/useCallback.md index 7445e7c80..74481136c 100644 --- a/src/content/reference/react/useCallback.md +++ b/src/content/reference/react/useCallback.md @@ -123,7 +123,7 @@ function ProductPage({ productId, referrer, theme }) { orderDetails, }); } - + return ( <div className={theme}> {/* ... ๊ทธ๋ž˜์„œ ShippingForm์˜ props๋Š” ๊ฐ™์€ ๊ฐ’์ด ์•„๋‹ˆ๋ฏ€๋กœ ๋งค๋ฒˆ ๋ฆฌ๋ Œ๋”๋ง ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.*/} @@ -158,7 +158,7 @@ function ProductPage({ productId, referrer, theme }) { <Note> -**`useCallback`์€ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ์šฉ๋„๋กœ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** ๋งŒ์•ฝ ์ฝ”๋“œ๊ฐ€ `useCallback` ์—†์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋จผ์ € ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๋ฅผ ์ฐพ์•„ ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋‹ค์Œ์— `useCallback`์„ ๋‹ค์‹œ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +**`useCallback`์€ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ์šฉ๋„๋กœ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** ๋งŒ์•ฝ ์ฝ”๋“œ๊ฐ€ `useCallback` ์—†์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋จผ์ € ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๋ฅผ ์ฐพ์•„ ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋‹ค์Œ์— `useCallback`์„ ๋‹ค์‹œ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Note> @@ -219,7 +219,7 @@ function useCallback(fn, dependencies) { `useCallback`์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์บ์‹ฑํ•˜๋Š” ๊ฒƒ์€ ๋ช‡ ๊ฐ€์ง€ ๊ฒฝ์šฐ์—๋งŒ ๊ฐ€์น˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- [`memo`](/reference/react/memo)๋กœ ๊ฐ์‹ธ์ง„ ์ปดํฌ๋„ŒํŠธ์— prop์œผ๋กœ ๋„˜๊น๋‹ˆ๋‹ค. ์ด ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. memoization์€ ์˜์กด์„ฑ์ด ๋ณ€ํ–ˆ์„ ๋•Œ๋งŒ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋งํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. +- [`memo`](/reference/react/memo)๋กœ ๊ฐ์‹ธ์ง„ ์ปดํฌ๋„ŒํŠธ์— prop์œผ๋กœ ๋„˜๊น๋‹ˆ๋‹ค. ์ด ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. memoization์€ ์˜์กด์„ฑ์ด ๋ณ€ํ–ˆ์„ ๋•Œ๋งŒ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋งํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. - ๋„˜๊ธด ํ•จ์ˆ˜๊ฐ€ ๋‚˜์ค‘์— ์–ด๋–ค Hook์˜ ์˜์กด์„ฑ์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `useCallback`์œผ๋กœ ๊ฐ์‹ธ์ง„ ๋‹ค๋ฅธ ํ•จ์ˆ˜๊ฐ€ ์ด ํ•จ์ˆ˜์— ์˜์กดํ•˜๊ฑฐ๋‚˜, [`useEffect`](/reference/react/useEffect)์—์„œ ์ด ํ•จ์ˆ˜์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—์„œ `useCallback`์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ๋Š” ๊ฒƒ์€ ์•„๋ฌด๋Ÿฐ ์ด์ต์ด ์—†์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ํฐ ๋ถˆ์ด์ต์„ ๊ฐ€์ ธ์˜ค์ง€๋„ ์•Š์œผ๋ฏ€๋กœ ์ผ๋ถ€ ํŒ€์€ ๊ฐœ๋ณ„์ ์ธ ๊ฒฝ์šฐ๋ฅผ ๋”ฐ๋กœ ์ƒ๊ฐํ•˜์ง€ ์•Š๊ณ , ๊ฐ€๋Šฅํ•œ ํ•œ ๋งŽ์ด memoizationํ•˜๋Š” ๋ฐฉ์‹์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ ์€ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ, ๋ชจ๋“  memoization์ด ํšจ๊ณผ์ ์ธ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. "ํ•ญ์ƒ ์ƒˆ๋กœ์šด" ํ•˜๋‚˜์˜ ๊ฐ’์ด ์žˆ๋‹ค๋ฉด ์ „์ฒด ์ปดํฌ๋„ŒํŠธ์˜ memoization์„ ๊นจ๊ธฐ์— ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. @@ -316,7 +316,7 @@ const ShippingForm = memo(function ShippingForm({ onSubmit }) { } function handleSubmit(e) { - e.preventDefault(); + e.preventDefault(); const formData = new FormData(e.target); const orderDetails = { ...Object.fromEntries(formData), @@ -386,7 +386,7 @@ button[type="button"] { ์ด ์˜ˆ์‹œ์—์„œ `ShippingForm` ์ปดํฌ๋„ŒํŠธ ๋˜ํ•œ **์ธ์œ„์ ์œผ๋กœ ๋А๋ฆฌ๊ฒŒ ๋งŒ๋“ค์—ˆ๊ธฐ ๋•Œ๋ฌธ์—** ๋ Œ๋”๋งํ•˜๋Š” React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‹ค์ œ๋กœ ๋А๋ฆด ๋•Œ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š” ์ง€ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์นด์šดํ„ฐ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๊ณ  ํ…Œ๋งˆ๋ฅผ ํ† ๊ธ€ ํ•ด๋ณด์„ธ์š”. -์ด์ „ ์˜ˆ์‹œ์™€ ๋‹ค๋ฅด๊ฒŒ ์ง€๊ธˆ์€ ํ…Œ๋งˆ๋ฅผ ํ† ๊ธ€ ํ•˜๋Š” ๊ฒƒ๋„ ๋А๋ฆฝ๋‹ˆ๋‹ค! **์ด ๋ฒ„์ „์—์„œ๋Š” `useCallback`์„ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ธฐ** ๋•Œ๋ฌธ์— `handleSubmit`์€ ํ•ญ์ƒ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜์ด๊ณ , ๋А๋ ค์ง„ `ShippingForm` ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +์ด์ „ ์˜ˆ์‹œ์™€ ๋‹ค๋ฅด๊ฒŒ ์ง€๊ธˆ์€ ํ…Œ๋งˆ๋ฅผ ํ† ๊ธ€ ํ•˜๋Š” ๊ฒƒ๋„ ๋А๋ฆฝ๋‹ˆ๋‹ค! **์ด ๋ฒ„์ „์—์„œ๋Š” `useCallback`์„ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ธฐ** ๋•Œ๋ฌธ์— `handleSubmit`์€ ํ•ญ์ƒ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜์ด๊ณ , ๋А๋ ค์ง„ `ShippingForm` ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. <Sandpack> @@ -663,7 +663,7 @@ button[type="button"] { ๋•Œ๋•Œ๋กœ memoized ์ฝœ๋ฐฑ์—์„œ ์ด์ „ ์ƒํƒœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -`handleAddTodo` ํ•จ์ˆ˜๋Š” `todos`๋กœ๋ถ€ํ„ฐ ๋‹ค์Œ ํ•  ์ผ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์˜์กด์„ฑ์œผ๋กœ ๋ช…์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. +`handleAddTodo` ํ•จ์ˆ˜๋Š” `todos`๋กœ๋ถ€ํ„ฐ ๋‹ค์Œ ํ•  ์ผ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์˜์กด์„ฑ์œผ๋กœ ๋ช…์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ```js {6,7} function TodoList() { diff --git a/src/content/reference/react/useContext.md b/src/content/reference/react/useContext.md index 1182a1b9a..f930e223d 100644 --- a/src/content/reference/react/useContext.md +++ b/src/content/reference/react/useContext.md @@ -43,7 +43,7 @@ function MyComponent() { #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} * ์ปดํฌ๋„ŒํŠธ ๋‚ด์˜ `useContext()` ํ˜ธ์ถœ์€ **๋™์ผํ•œ** ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ˜ํ™˜๋œ provider์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•ด๋‹นํ•˜๋Š” `<Context.Provider>` ๋Š” `useContext()` ํ˜ธ์ถœ์„ ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ***์œ„์—* ๋ฐฐ์น˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** -* React๋Š” ๋‹ค๋ฅธ `value`์„ ๋ฐ›๋Š” provider๋กœ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ํŠน์ • context๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์ž์‹๋“ค์„ **์ž๋™์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง**ํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๊ฐ’๊ณผ ๋‹ค์Œ ๊ฐ’์€ [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) ๋น„๊ต๋ฅผ ํ†ตํ•ด ๋น„๊ต๋ฉ๋‹ˆ๋‹ค. [`memo`](/reference/react/memo)๋กœ ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ฐ์–ด๋„ ์ž์‹๋“ค์ด ์ƒˆ๋กœ์šด context ๊ฐ’์„ ๋ฐ›๋Š” ๊ฒƒ์„ ๋ง‰์ง€๋Š” ๋ชปํ•ฉ๋‹ˆ๋‹ค. +* React๋Š” ๋‹ค๋ฅธ `value`์„ ๋ฐ›๋Š” provider๋กœ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ํŠน์ • context๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์ž์‹๋“ค์„ **์ž๋™์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง**ํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๊ฐ’๊ณผ ๋‹ค์Œ ๊ฐ’์€ [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) ๋น„๊ต๋ฅผ ํ†ตํ•ด ๋น„๊ต๋ฉ๋‹ˆ๋‹ค. [`memo`](/reference/react/memo)๋กœ ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ฐ์–ด๋„ ์ž์‹๋“ค์ด ์ƒˆ๋กœ์šด context ๊ฐ’์„ ๋ฐ›๋Š” ๊ฒƒ์„ ๋ง‰์ง€๋Š” ๋ชปํ•ฉ๋‹ˆ๋‹ค. * ๋นŒ๋“œ ์‹œ์Šคํ…œ์ด ๊ฒฐ๊ณผ๋ฌผ์— ์ค‘๋ณต ๋ชจ๋“ˆ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ(์‹ฌ๋ณผ๋ฆญ ๋งํฌ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ) context๊ฐ€ ์†์ƒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. context๋ฅผ ํ†ตํ•ด ๋ฌด์–ธ๊ฐ€๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ `===` ๋น„๊ต์— ์˜ํ•ด ๊ฒฐ์ •๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” `SomeContext`์™€ context๋ฅผ ์ฝ๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” `SomeContext`๊ฐ€ ***์ •ํ™•ํ•˜๊ฒŒ* ๋™์ผํ•œ ๊ฐ์ฒด**์ธ ๊ฒฝ์šฐ์—๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. --- @@ -60,7 +60,7 @@ import { useContext } from 'react'; function Button() { const theme = useContext(ThemeContext); - // ... + // ... ``` `useContext`๋Š” ์ „๋‹ฌํ•œ <CodeStep step={1}>context</CodeStep> ์— ๋Œ€ํ•œ <CodeStep step={2}>context value </CodeStep>๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. context ๊ฐ’์„ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด React๋Š” ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ํŠน์ • context์— ๋Œ€ํ•ด **์ƒ์œ„์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด context provider**๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. @@ -85,7 +85,7 @@ provider์™€ `Button`์‚ฌ์ด์— ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์ปดํฌ๋„ŒํŠธ ๋ ˆ์ด์–ด๊ฐ€ ์žˆ๋Š” <Pitfall> -`useContext()` ๋Š” ํ•ญ์ƒ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ *์ƒ์œ„*์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด provider๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ์œ„์ชฝ์œผ๋กœ ์ฐพ๊ณ  `useContext()`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์•ˆ์˜ provider๋Š” **๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** +`useContext()` ๋Š” ํ•ญ์ƒ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ *์ƒ์œ„*์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด provider๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ์œ„์ชฝ์œผ๋กœ ์ฐพ๊ณ  `useContext()`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์•ˆ์˜ provider๋Š” **๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** </Pitfall> @@ -845,7 +845,7 @@ export default function AddTask() { type: 'added', id: nextId++, text: text, - }); + }); }}>Add</button> </> ); @@ -1292,7 +1292,7 @@ export const LevelContext = createContext(0); context๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด์™€ ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ๊ฐ’์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -```js [[2, 10, "{ currentUser, login }"]] +```js [[2, 10, "{ currentUser, login }"]] function MyApp() { const [currentUser, setCurrentUser] = useState(null); diff --git a/src/content/reference/react/useDeferredValue.md b/src/content/reference/react/useDeferredValue.md index 4b192b5ce..777351f63 100644 --- a/src/content/reference/react/useDeferredValue.md +++ b/src/content/reference/react/useDeferredValue.md @@ -189,7 +189,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -403,7 +403,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } @@ -632,7 +632,7 @@ function use(promise) { reason => { promise.status = 'rejected'; promise.reason = reason; - }, + }, ); throw promise; } diff --git a/src/content/reference/react/useEffect.md b/src/content/reference/react/useEffect.md index ce2ffb7d9..807251bb6 100644 --- a/src/content/reference/react/useEffect.md +++ b/src/content/reference/react/useEffect.md @@ -45,7 +45,7 @@ function ChatRoom({ roomId }) { #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} + `setup(์„ค์ •)`: Effect์˜ ๋กœ์ง์ด ํฌํ•จ๋œ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์„ค์ • ํ•จ์ˆ˜๋Š” ์„ ํƒ์ ์œผ๋กœ *clean up(์ •๋ฆฌ)* ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ DOM์— ์ถ”๊ฐ€๋œ ์ดํ›„์— ์„ค์ • ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ์˜ ๋ณ€ํ™”์— ๋”ฐ๋ผ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง์ด ๋˜์—ˆ์„ ๊ฒฝ์šฐ, (์„ค์ • ํ•จ์ˆ˜์— ์ •๋ฆฌ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ–ˆ์—ˆ๋‹ค๋ฉด) React๋Š” ์ด์ „ ๋ Œ๋”๋ง์— ์‚ฌ์šฉ๋œ ๊ฐ’์œผ๋กœ ์ •๋ฆฌ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ ํ›„ ์ƒˆ๋กœ์šด ๊ฐ’์œผ๋กœ ์„ค์ • ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ DOM์—์„œ ์ œ๊ฑฐ๋œ ๊ฒฝ์šฐ์—๋„ ์ •๋ฆฌ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. - + + `dependencies` **์„ ํƒ์‚ฌํ•ญ** : `์„ค์ •` ํ•จ์ˆ˜์˜ ์ฝ”๋“œ ๋‚ด๋ถ€์—์„œ ์ฐธ์กฐ๋˜๋Š” ๋ชจ๋“  ๋ฐ˜์‘ํ˜• ๊ฐ’๋“ค์ด ํฌํ•จ๋œ ๋ฐฐ์—ด๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜์‘ํ˜• ๊ฐ’์—๋Š” props์™€ state, ๋ชจ๋“  ๋ณ€์ˆ˜ ๋ฐ ์ปดํฌ๋„ŒํŠธ body์— ์ง์ ‘์ ์œผ๋กœ ์„ ์–ธ๋œ ํ•จ์ˆ˜๋“ค์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๋ฆฐํ„ฐ๊ฐ€ [React ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์„ค์ •๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ](/learn/editor-setup#linting), ๋ฆฐํ„ฐ๋Š” ๋ชจ๋“  ๋ฐ˜์‘ํ˜• ๊ฐ’๋“ค์ด ์˜์กด์„ฑ์— ์ œ๋Œ€๋กœ ๋ช…์‹œ๋˜์–ด ์žˆ๋Š”์ง€ ๊ฒ€์ฆํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜์กด์„ฑ ๋ฐฐ์—ด์€ ํ•ญ์ƒ ์ผ์ •ํ•œ ์ˆ˜์˜ ํ•ญ๋ชฉ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•˜๋ฉฐ `[dep1, dep2, dep3]`๊ณผ ๊ฐ™์ด ์ž‘์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. React๋Š” ๊ฐ๊ฐ์˜ ์˜์กด์„ฑ๋“ค์„ [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) ๋น„๊ต๋ฒ•์„ ํ†ตํ•ด ์ด์ „ ๊ฐ’๊ณผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ์„ ์ƒ๋žตํ•  ๊ฒฝ์šฐ, Effect๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง๋  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. [์ธ์ˆ˜์— ์˜์กด์„ฑ ๋ฐฐ์—ด์„ ์ถ”๊ฐ€ํ–ˆ์„ ๋•Œ, ๋นˆ ๋ฐฐ์—ด์„ ์ถ”๊ฐ€ํ–ˆ์„ ๋•Œ, ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์•˜์„ ๋•Œ์˜ ์ฐจ์ด๋ฅผ ํ™•์ธํ•ด ๋ณด์„ธ์š”.](#examples-dependencies) #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} @@ -114,7 +114,7 @@ function ChatRoom({ roomId }) { **์œ„์˜ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ˆœ์„œ๋ฅผ ์„ค๋ช…ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.** -์œ„์˜ `ChatRoom` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์— ์ถ”๊ฐ€๋˜๋ฉด ์ดˆ๊ธฐ `serverUrl`๊ณผ `roomId`๋ฅผ ์ด์šฉํ•ด ์ฑ„ํŒ…๋ฐฉ๊ณผ ์—ฐ๊ฒฐ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฆฌ๋ Œ๋”๋ง์— ์˜ํ•ด `serverUrl` ๋˜๋Š” `roomId`๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด (์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ๋“œ๋กญ๋‹ค์šด ๋ฉ”๋‰ด๋ฅผ ์ด์šฉํ•ด ๋‹ค๋ฅธ ์ฑ„ํŒ…๋ฐฉ์„ ์„ ํƒํ•  ๊ฒฝ์šฐ) *Effect๋Š” ์ด์ „ ์ฑ„ํŒ…๋ฐฉ๊ณผ์˜ ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•˜๊ณ  ๋‹ค์Œ ์ฑ„ํŒ…๋ฐฉ๊ณผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.* `ChatRoom` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์—์„œ ์ œ๊ฑฐ๋œ๋‹ค๋ฉด Effect๋Š” ๋งˆ์ง€๋ง‰ ์ฑ„ํŒ…๋ฐฉ๊ณผ ์ด๋ค„์ง„ ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์œ„์˜ `ChatRoom` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์— ์ถ”๊ฐ€๋˜๋ฉด ์ดˆ๊ธฐ `serverUrl`๊ณผ `roomId`๋ฅผ ์ด์šฉํ•ด ์ฑ„ํŒ…๋ฐฉ๊ณผ ์—ฐ๊ฒฐ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฆฌ๋ Œ๋”๋ง์— ์˜ํ•ด `serverUrl` ๋˜๋Š” `roomId`๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด (์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ๋“œ๋กญ๋‹ค์šด ๋ฉ”๋‰ด๋ฅผ ์ด์šฉํ•ด ๋‹ค๋ฅธ ์ฑ„ํŒ…๋ฐฉ์„ ์„ ํƒํ•  ๊ฒฝ์šฐ) *Effect๋Š” ์ด์ „ ์ฑ„ํŒ…๋ฐฉ๊ณผ์˜ ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•˜๊ณ  ๋‹ค์Œ ์ฑ„ํŒ…๋ฐฉ๊ณผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.* `ChatRoom` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์—์„œ ์ œ๊ฑฐ๋œ๋‹ค๋ฉด Effect๋Š” ๋งˆ์ง€๋ง‰ ์ฑ„ํŒ…๋ฐฉ๊ณผ ์ด๋ค„์ง„ ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. React๋Š” **[๋ฒ„๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ธฐ ์œ„ํ•ด](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed) ๊ฐœ๋ฐœ๋ชจ๋“œ์—์„œ <CodeStep step={1}>์„ค์ •</CodeStep>์ด ์‹คํ–‰๋˜๊ธฐ ์ „์— <CodeStep step={1}>์„ค์ •</CodeStep>๊ณผ <CodeStep step={2}>์ •๋ฆฌ</CodeStep>๋ฅผ ํ•œ ๋ฒˆ ๋” ์‹คํ–‰์‹œํ‚ต๋‹ˆ๋‹ค.** ์ด๋Š” ์ŠคํŠธ๋ ˆ์Šค ํ…Œ์ŠคํŠธ์˜ ํ•˜๋‚˜๋กœ์จ Effect์˜ ๋กœ์ง์ด ์ •ํ™•ํ•˜๊ฒŒ ์ˆ˜ํ–‰๋˜๊ณ  ์žˆ๋Š”์ง€๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๊ฐ€์‹œ์ ์ธ ์ด์Šˆ๊ฐ€ ๋ณด์ธ๋‹ค๋ฉด ์ •๋ฆฌ ํ•จ์ˆ˜์˜ ๋กœ์ง์— ๋†“์นœ ๋ถ€๋ถ„์ด ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ •๋ฆฌ ํ•จ์ˆ˜๋Š” ์„ค์ • ํ•จ์ˆ˜์˜ ์–ด๋– ํ•œ ๋™์ž‘์ด๋ผ๋„ ์ค‘์ง€ํ•˜๊ฑฐ๋‚˜ ์‹คํ–‰ ์ทจ์†Œ๋ฅผ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž๋Š” *์„ค์ •* ํ•จ์ˆ˜๊ฐ€ ํ•œ ๋ฒˆ ํ˜ธ์ถœ๋  ๋•Œ์™€ *์„ค์ •* โ†’ *์ •๋ฆฌ* โ†’ *์„ค์ •* ์ˆœ์„œ๋กœ ํ˜ธ์ถœ๋  ๋•Œ์˜ ์ฐจ์ด๋ฅผ ๋А๋‚„ ์ˆ˜ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. @@ -137,7 +137,7 @@ An Effect lets you [keep your component synchronized](/learn/synchronizing-with- #### ์ฑ„ํŒ… ์„œ๋ฒ„์™€ ์—ฐ๊ฒฐ {/*connecting-to-a-chat-server*/} -์ด ์˜ˆ์‹œ์—์„œ๋Š” `ChatRoom` ์ปดํฌ๋„ŒํŠธ์˜ Effect๋ฅผ ํ†ตํ•ด `chat.js`๋กœ ์ •์˜๋œ ์™ธ๋ถ€ ์‹œ์Šคํ…œ๊ณผ ์—ฐ๊ฒฐ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. "Open chat"์„ ๋ˆ„๋ฅด๋ฉด `ChatRoom` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ์ด ์ƒŒ๋“œ๋ฐ•์Šค๋Š” ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ ๋™์ž‘ํ•˜๋ฏ€๋กœ [์ถ”๊ฐ€์ ์ธ ์—ฐ๊ฒฐ-์—ฐ๊ฒฐํ•ด์ œ ์‚ฌ์ดํด](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed)์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋“œ๋กญ๋‹ค์šด ๋ฉ”๋‰ด๋‚˜ input์„ ์ด์šฉํ•ด `roomId` ๋˜๋Š” `serverUrl`๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์–ด๋–ป๊ฒŒ Effect๊ฐ€ chat์„ ์žฌ์—ฐ๊ฒฐํ•˜๋Š”์ง€ ํ™•์ธํ•ด ๋ณด์„ธ์š”. "Close chat"์„ ๋ˆŒ๋Ÿฌ Effect๊ฐ€ ๋งˆ์ง€๋ง‰์— ์—ฐ๊ฒฐ๋˜์—ˆ๋˜ chat์„ ์—ฐ๊ฒฐ ํ•ด์ œํ•˜๋Š” ๊ฒƒ๋„ ํ™•์ธํ•ด ๋ณด์„ธ์š”. +์ด ์˜ˆ์‹œ์—์„œ๋Š” `ChatRoom` ์ปดํฌ๋„ŒํŠธ์˜ Effect๋ฅผ ํ†ตํ•ด `chat.js`๋กœ ์ •์˜๋œ ์™ธ๋ถ€ ์‹œ์Šคํ…œ๊ณผ ์—ฐ๊ฒฐ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. "Open chat"์„ ๋ˆ„๋ฅด๋ฉด `ChatRoom` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ์ด ์ƒŒ๋“œ๋ฐ•์Šค๋Š” ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ ๋™์ž‘ํ•˜๋ฏ€๋กœ [์ถ”๊ฐ€์ ์ธ ์—ฐ๊ฒฐ-์—ฐ๊ฒฐํ•ด์ œ ์‚ฌ์ดํด](/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed)์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋“œ๋กญ๋‹ค์šด ๋ฉ”๋‰ด๋‚˜ input์„ ์ด์šฉํ•ด `roomId` ๋˜๋Š” `serverUrl`๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์–ด๋–ป๊ฒŒ Effect๊ฐ€ chat์„ ์žฌ์—ฐ๊ฒฐํ•˜๋Š”์ง€ ํ™•์ธํ•ด ๋ณด์„ธ์š”. "Close chat"์„ ๋ˆŒ๋Ÿฌ Effect๊ฐ€ ๋งˆ์ง€๋ง‰์— ์—ฐ๊ฒฐ๋˜์—ˆ๋˜ chat์„ ์—ฐ๊ฒฐ ํ•ด์ œํ•˜๋Š” ๊ฒƒ๋„ ํ™•์ธํ•ด ๋ณด์„ธ์š”. <Sandpack> @@ -1083,7 +1083,7 @@ function ChatRoom({ roomId }) { // ์ด๊ฒƒ์€ ๋ฐ˜์‘ํ˜• ๊ฐ’์ž…๋‹ˆ๋‹ค ```js {8} function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); - + useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); diff --git a/src/content/reference/react/useImperativeHandle.md b/src/content/reference/react/useImperativeHandle.md index f6dc7a9ee..63a24436f 100644 --- a/src/content/reference/react/useImperativeHandle.md +++ b/src/content/reference/react/useImperativeHandle.md @@ -4,7 +4,7 @@ title: useImperativeHandle <Intro> -`useImperativeHandle`์€ [ref](/learn/manipulating-the-dom-with-refs)๋กœ ๋…ธ์ถœ๋˜๋Š” ํ•ธ๋“ค์„ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” React ํ›…์ž…๋‹ˆ๋‹ค. +`useImperativeHandle`์€ [ref](/learn/manipulating-the-dom-with-refs)๋กœ ๋…ธ์ถœ๋˜๋Š” ํ•ธ๋“ค์„ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” React ํ›…์ž…๋‹ˆ๋‹ค. ```js useImperativeHandle(ref, createHandle, dependencies?) diff --git a/src/content/reference/react/useInsertionEffect.md b/src/content/reference/react/useInsertionEffect.md index 55558328d..f1bd6a3e8 100644 --- a/src/content/reference/react/useInsertionEffect.md +++ b/src/content/reference/react/useInsertionEffect.md @@ -45,7 +45,7 @@ function useCSS(rule) { #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} * `setup`: Effects ์˜ ๋กœ์ง์ด ํฌํ•จ๋œ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. setup ํ•จ์ˆ˜๋Š” ์„ ํƒ์ ์œผ๋กœ *cleanup* ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ DOM์— ์ถ”๊ฐ€๋˜๊ธฐ ์ „์—, layout Effects ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์—, React๋Š” setup ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. `dependencies`๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค, React๋Š” ๋จผ์ € ์ด์ „ ๊ฐ’์œผ๋กœ cleanup ํ•จ์ˆ˜(์ œ๊ณตํ•œ ๊ฒฝ์šฐ)๋ฅผ ์‹คํ–‰ํ•œ ๋‹ค์Œ ์ƒˆ ๊ฐ’์œผ๋กœ setup ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ DOM์—์„œ ์ œ๊ฑฐ๋˜๊ธฐ ์ „์— React๋Š” cleanup ํ•จ์ˆ˜๋ฅผ ํ•œ ๋ฒˆ ๋” ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. - + * **์„ ํƒ์‚ฌํ•ญ** `dependencies`: `setup` ์ฝ”๋“œ ๋‚ด์—์„œ ์ฐธ์กฐ๋œ ๋ชจ๋“  ๋ฐ˜์‘ํ˜• ๊ฐ’์˜ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ๋ฐ˜์‘ํ˜• ๊ฐ’์—๋Š” props, state, ๊ทธ๋ฆฌ๊ณ  ์ปดํฌ๋„ŒํŠธ ๋ณธ๋ฌธ์— ์ง์ ‘ ์„ ์–ธ๋œ ๋ชจ๋“  ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. linter๊ฐ€ [React์šฉ์œผ๋กœ ์„ค์ •๋œ](/learn/editor-setup#linting) ๊ฒฝ์šฐ, ๋ชจ๋“  ๋ฐ˜์‘ํ˜• ๊ฐ’์ด ์˜์กด์„ฑ์œผ๋กœ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ง€์ •๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ ๋ชฉ๋ก์—๋Š” ์ผ์ •ํ•œ ์ˆ˜์˜ ํ•ญ๋ชฉ์ด ์žˆ์–ด์•ผ ํ•˜๋ฉฐ `[dep1, dep2, dep3]`์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. React๋Š” [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) ๋น„๊ต ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ์˜์กด์„ฑ์„ ์ด์ „ ๊ฐ’๊ณผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ์„ ์ „ํ˜€ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค Effect๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} diff --git a/src/content/reference/react/useLayoutEffect.md b/src/content/reference/react/useLayoutEffect.md index d0cdc7a42..971a97225 100644 --- a/src/content/reference/react/useLayoutEffect.md +++ b/src/content/reference/react/useLayoutEffect.md @@ -48,8 +48,8 @@ function Tooltip() { #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} -* `setup`: Effect์˜ ๋กœ์ง์ด ํฌํ•จ๋œ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. setup ํ•จ์ˆ˜๋Š” ์„ ํƒ์ ์œผ๋กœ *cleanup* ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ DOM์— ์ถ”๊ฐ€๋˜๊ธฐ ์ „์— React๋Š” setup ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. `dependencies`๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด ๋‹ค์‹œ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค, React๋Š” (cleanup ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ–ˆ๋‹ค๋ฉด) ๋จผ์ € ์ด์ „ ๊ฐ’์œผ๋กœ cleanup ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ ๋‹ค์Œ, ์ƒˆ๋กœ์šด ๊ฐ’์œผ๋กœ setup ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ DOM์—์„œ ์ œ๊ฑฐ๋˜๊ธฐ ์ „์— React๋Š” cleanup ํ•จ์ˆ˜๋ฅผ ํ•œ ๋ฒˆ ๋” ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. - +* `setup`: Effect์˜ ๋กœ์ง์ด ํฌํ•จ๋œ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. setup ํ•จ์ˆ˜๋Š” ์„ ํƒ์ ์œผ๋กœ *cleanup* ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ DOM์— ์ถ”๊ฐ€๋˜๊ธฐ ์ „์— React๋Š” setup ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. `dependencies`๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด ๋‹ค์‹œ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค, React๋Š” (cleanup ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ–ˆ๋‹ค๋ฉด) ๋จผ์ € ์ด์ „ ๊ฐ’์œผ๋กœ cleanup ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ ๋‹ค์Œ, ์ƒˆ๋กœ์šด ๊ฐ’์œผ๋กœ setup ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ DOM์—์„œ ์ œ๊ฑฐ๋˜๊ธฐ ์ „์— React๋Š” cleanup ํ•จ์ˆ˜๋ฅผ ํ•œ ๋ฒˆ ๋” ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. + * **์„ ํƒ์‚ฌํ•ญ** `dependencies`: `setup`์ฝ”๋“œ ๋‚ด์—์„œ ์ฐธ์กฐ๋œ ๋ชจ๋“  ๋ฐ˜์‘ํ˜• ๊ฐ’์˜ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ๋ฐ˜์‘ํ˜• ๊ฐ’์—๋Š” props, state, ๊ทธ๋ฆฌ๊ณ  ์ปดํฌ๋„ŒํŠธ ๋ณธ๋ฌธ์— ์ง์ ‘ ์„ ์–ธ๋œ ๋ชจ๋“  ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. linter๊ฐ€ [React์šฉ์œผ๋กœ ์„ค์ •๋œ](/learn/editor-setup#linting) ๊ฒฝ์šฐ, ๋ชจ๋“  ๋ฐ˜์‘ํ˜• ๊ฐ’์ด ์˜์กด์„ฑ์œผ๋กœ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ง€์ •๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ ๋ชฉ๋ก์—๋Š” ์ผ์ •ํ•œ ์ˆ˜์˜ ํ•ญ๋ชฉ์ด ์žˆ์–ด์•ผ ํ•˜๋ฉฐ `[dep1, dep2, dep3]`์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. React๋Š” [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) ๋น„๊ต ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ์˜์กด์„ฑ์„ ์ด์ „ ๊ฐ’๊ณผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ์˜์กด์„ฑ์„ ์ „ํ˜€ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค Effect๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} @@ -59,7 +59,7 @@ function Tooltip() { #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} * `useLayoutEffect`๋Š” Hook์ด๋ฏ€๋กœ, **์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ** ๋˜๋Š” ์ปค์Šคํ…€ Hook์—์„œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ณต๋ฌธ์ด๋‚˜ ์กฐ๊ฑด๋ฌธ ๋‚ด์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ•ด์„œ Effect๋ฅผ ์ƒˆ ์ปดํฌ๋„ŒํŠธ๋กœ ์˜ฎ๊ธฐ์„ธ์š”. - + * Strict Mode๊ฐ€ ์ผœ์ ธ ์žˆ์œผ๋ฉด, React๋Š” ์‹ค์ œ ์ฒซ ๋ฒˆ์งธ setup ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ด์ „์— **๊ฐœ๋ฐœ ๋ชจ๋“œ์—๋งŒ ํ•œ์ •ํ•˜์—ฌ ํ•œ ๋ฒˆ์˜ ์ถ”๊ฐ€์ ์ธ setup + cleanup ์‚ฌ์ดํด์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.** ์ด๋Š” cleanup ๋กœ์ง์ด setup ๋กœ์ง์„ ์™„๋ฒฝํžˆ "๋ฐ˜์˜"ํ•˜๊ณ , setup ๋กœ์ง์ด ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์„ ์ค‘๋‹จํ•˜๊ฑฐ๋‚˜ ๋˜๋Œ๋ฆฌ๋Š” ์ง€๋ฅผ ํ™•์ธํ•˜๋Š” ์ŠคํŠธ๋ ˆ์Šค ํ…Œ์ŠคํŠธ์ž…๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด [cleanup ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜์„ธ์š”.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development) * ์˜์กด์„ฑ ์ค‘์— ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ์ •์˜๋œ ๊ฐ์ฒด๋‚˜ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, **Effect ๊ฐ€ ํ•„์š” ์ด์ƒ์œผ๋กœ ๋‹ค์‹œ ์‹คํ–‰๋  ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.** ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๋ถˆํ•„์š”ํ•œ [๊ฐ์ฒด ์˜์กด์„ฑ](/reference/react/useEffect#removing-unnecessary-object-dependencies)์ด๋‚˜ [ํ•จ์ˆ˜ ์˜์กด์„ฑ](/reference/react/useEffect#removing-unnecessary-function-dependencies)์„ ์ œ๊ฑฐํ•˜์„ธ์š”. [State ์—…๋ฐ์ดํŠธ](/reference/react/useEffect#updating-state-based-on-previous-state-from-an-effect)๋‚˜ [๋น„ ๋ฐ˜์‘ํ˜• ๋กœ์ง](/reference/react/useEffect#reading-the-latest-props-and-state-from-an-effect)์„ effect ๋ฐ–์œผ๋กœ ๋นผ๋‚ผ ์ˆ˜ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -720,7 +720,7 @@ export default function TooltipContainer({ children, x, y, contentRef }) { `useLayoutEffect`์˜ ๋ชฉ์ ์€ [๋ ˆ์ด์•„์›ƒ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•ด์„œ](#measuring-layout-before-the-browser-repaints-the-screen) ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. 1. ์ดˆ๊ธฐ ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. -2. *๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ™”๋ฉด์„ ๋‹ค์‹œ ๊ทธ๋ฆฌ๊ธฐ ์ „์—* ๋ ˆ์ด์•„์›ƒ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. +2. *๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ™”๋ฉด์„ ๋‹ค์‹œ ๊ทธ๋ฆฌ๊ธฐ ์ „์—* ๋ ˆ์ด์•„์›ƒ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. 3. ์ฝ์€ ๋ ˆ์ด์•„์›ƒ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ตœ์ข… ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. [์„œ๋ฒ„ ๋ Œ๋”๋ง](/reference/react-dom/server)์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด, React ์•ฑ์€ ์„œ๋ฒ„์—์„œ ์ดˆ๊ธฐ ๋ Œ๋”๋ง์„ ํ•ด์„œ HTML์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด JavaScript ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์— ์ดˆ๊ธฐ HTML์„ ๋ณด์—ฌ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. @@ -737,6 +737,6 @@ export default function TooltipContainer({ children, x, y, contentRef }) { - ๋˜๋Š” [ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ „์šฉ์œผ๋กœ ๋งŒ๋“œ์„ธ์š”.](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content) React๊ฐ€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด [`<Suspense>`](/reference/react/Suspense) ๊ฒฝ๊ณ„ ์•ˆ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์„œ๋ฒ„๋ Œ๋”๋ง ๋™์•ˆ (์Šคํ”ผ๋„ˆ๋‚˜ ๊ธ€๋ฆฌ๋จธ๊ฐ™์€) loading fallbck์œผ๋กœ ๋Œ€์ฒด ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. -- ๋˜๋Š” `useLayoutEffect`๊ฐ€ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ hydration ์ดํ›„์—๋งŒ ๋ Œ๋”๋งํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถˆ๋ฆฌ์–ธ ํƒ€์ž…์ธ `isMounted` state๋ฅผ ์ดˆ๊นƒ๊ฐ’์ธ `false`๋กœ ์œ ์ง€ํ•˜๋‹ค๊ฐ€, `useEffect` ํ˜ธ์ถœ๋˜๋ฉด ๊ฑฐ๊ธฐ์„œ `true`๋กœ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์„ธ์š”. ๊ทธ๋Ÿฌ๋ฉด ๋ Œ๋”๋ง ๋กœ์ง์€ `return isMounted ? <RealContent /> : <FallbackContent />` ์ฒ˜๋Ÿผ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๋Š” ์ค‘์ด๊ฑฐ๋‚˜ hydration ๋™์•ˆ ์‚ฌ์šฉ์ž๋Š” `FallbackContent`๋ฅผ ๋ณผ ๊ฒƒ์ด๊ณ  `FallbackContent`๋Š” `useLayoutEffect`๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„์— React๊ฐ€ `FallbackContent`๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ „์šฉ์ด๋ฉด์„œ `useLayoutEffect`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” `RealContent`๋กœ ๋ณ€๊ฒฝํ•  ๊ฒ๋‹ˆ๋‹ค. +- ๋˜๋Š” `useLayoutEffect`๊ฐ€ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ hydration ์ดํ›„์—๋งŒ ๋ Œ๋”๋งํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถˆ๋ฆฌ์–ธ ํƒ€์ž…์ธ `isMounted` state๋ฅผ ์ดˆ๊นƒ๊ฐ’์ธ `false`๋กœ ์œ ์ง€ํ•˜๋‹ค๊ฐ€, `useEffect` ํ˜ธ์ถœ๋˜๋ฉด ๊ฑฐ๊ธฐ์„œ `true`๋กœ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์„ธ์š”. ๊ทธ๋Ÿฌ๋ฉด ๋ Œ๋”๋ง ๋กœ์ง์€ `return isMounted ? <RealContent /> : <FallbackContent />` ์ฒ˜๋Ÿผ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๋Š” ์ค‘์ด๊ฑฐ๋‚˜ hydration ๋™์•ˆ ์‚ฌ์šฉ์ž๋Š” `FallbackContent`๋ฅผ ๋ณผ ๊ฒƒ์ด๊ณ  `FallbackContent`๋Š” `useLayoutEffect`๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„์— React๊ฐ€ `FallbackContent`๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ „์šฉ์ด๋ฉด์„œ `useLayoutEffect`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” `RealContent`๋กœ ๋ณ€๊ฒฝํ•  ๊ฒ๋‹ˆ๋‹ค. - ์ปดํฌ๋„ŒํŠธ๋ฅผ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ์™€ ๋™๊ธฐํ™”ํ•˜๊ณ , ๋ ˆ์ด์•„์›ƒ ๊ณ„์‚ฐ ์™ธ์— ๋‹ค๋ฅธ ์ด์œ ๋กœ `useLayoutEffect`์— ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด, ๋Œ€์‹  [`useSyncExternalStore`](/reference/react/useSyncExternalStore)๋ฅผ ๊ณ ๋ คํ•ด ๋ณด์„ธ์š”. ์ด Hook์€ [์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.](/reference/react/useSyncExternalStore#adding-support-for-server-rendering) diff --git a/src/content/reference/react/useMemo.md b/src/content/reference/react/useMemo.md index 9b4be3e84..bfedc1a59 100644 --- a/src/content/reference/react/useMemo.md +++ b/src/content/reference/react/useMemo.md @@ -143,13 +143,13 @@ console.timeEnd('filter array'); #### ๋ชจ๋“  ๊ณณ์— useMemo๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋‚˜์š”? {/*should-you-add-usememo-everywhere*/} -์ด ์‚ฌ์ดํŠธ์™€ ๊ฐ™์ด ๋Œ€๋ถ€๋ถ„์˜ ์ƒํ˜ธ ์ž‘์šฉ์ด ๊ฑฐ์นœ ๊ฒฝ์šฐ(ํŽ˜์ด์ง€ ๋˜๋Š” ์ „์ฒด ์„น์…˜์ด ๊ต์ฒด๋˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด) ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, ์•ฑ์ด ๊ทธ๋ฆผ ํŽธ์ง‘๊ธฐ์™€ ๋น„์Šทํ•˜๊ณ  ๋Œ€๋ถ€๋ถ„์˜ ์ƒํ˜ธ ์ž‘์šฉ์ด ์„ธ๋ถ„ํ™”๋œ ๊ฒฝ์šฐ(๋„ํ˜• ์ด๋™๊ณผ ๊ฐ™์€) ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ๋งค์šฐ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด ์‚ฌ์ดํŠธ์™€ ๊ฐ™์ด ๋Œ€๋ถ€๋ถ„์˜ ์ƒํ˜ธ ์ž‘์šฉ์ด ๊ฑฐ์นœ ๊ฒฝ์šฐ(ํŽ˜์ด์ง€ ๋˜๋Š” ์ „์ฒด ์„น์…˜์ด ๊ต์ฒด๋˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด) ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, ์•ฑ์ด ๊ทธ๋ฆผ ํŽธ์ง‘๊ธฐ์™€ ๋น„์Šทํ•˜๊ณ  ๋Œ€๋ถ€๋ถ„์˜ ์ƒํ˜ธ ์ž‘์šฉ์ด ์„ธ๋ถ„ํ™”๋œ ๊ฒฝ์šฐ(๋„ํ˜• ์ด๋™๊ณผ ๊ฐ™์€) ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ๋งค์šฐ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `useMemo`๋กœ ์ตœ์ ํ™”ํ•˜๋Š” ๊ฒƒ์€ ๋ช‡๋ช‡ ๊ฒฝ์šฐ์—๋งŒ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. - `useMemo`์— ์ž…๋ ฅํ•˜๋Š” ๊ณ„์‚ฐ์ด ๋ˆˆ์— ๋„๊ฒŒ ๋А๋ฆฌ๊ณ  ์ข…์†์„ฑ์ด ๊ฑฐ์˜ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ. - [`memo`](/reference/react/memo)๋กœ ๊ฐ์‹ธ์ง„ ์ปดํฌ๋„ŒํŠธ์— prop๋กœ ์ „๋‹ฌํ•  ๊ฒฝ์šฐ. ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ์˜์กด์„ฑ์ด ๋™์ผํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋งŒ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- ์ „๋‹ฌํ•œ ๊ฐ’์„ ๋‚˜์ค‘์— ์ผ๋ถ€ Hook์˜ ์ข…์†์„ฑ์œผ๋กœ ์ด์šฉํ•  ๊ฒฝ์šฐ. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค๋ฅธ `useMemo`์˜ ๊ณ„์‚ฐ ๊ฐ’์ด ์—ฌ๊ธฐ์— ์ข…์†๋˜์–ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” [`useEffect`](/reference/react/useEffect)์˜ ๊ฐ’์— ์ข…์†๋˜์–ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- ์ „๋‹ฌํ•œ ๊ฐ’์„ ๋‚˜์ค‘์— ์ผ๋ถ€ Hook์˜ ์ข…์†์„ฑ์œผ๋กœ ์ด์šฉํ•  ๊ฒฝ์šฐ. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค๋ฅธ `useMemo`์˜ ๊ณ„์‚ฐ ๊ฐ’์ด ์—ฌ๊ธฐ์— ์ข…์†๋˜์–ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” [`useEffect`](/reference/react/useEffect)์˜ ๊ฐ’์— ์ข…์†๋˜์–ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์™ธ๋Š” ๊ณ„์‚ฐ์„ `useMemo`๋กœ ๊ฐ์‹ธ๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ์ด๋“์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋ ‡๊ฒŒ ํ•œ๋‹ค๊ณ  ํ•ด์„œ ํฌ๊ฒŒ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๊ฒƒ๋„ ์•„๋‹ˆ๋ฏ€๋กœ ์ผ๋ถ€ ํŒ€์—์„œ๋Š” ๊ฐœ๋ณ„ ์‚ฌ๋ก€์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜์ง€ ์•Š๊ณ  ๊ฐ€๋Šฅํ•œ ํ•œ ๋งŽ์ด ๋ฉ”๋ชจํ•˜๋Š” ๋ฐฉ์‹์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ ๋ฐฉ์‹์˜ ๋‹จ์ ์€ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง„๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ, ๋ชจ๋“  ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ํšจ๊ณผ์ ์ธ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. "ํ•ญ์ƒ ์ƒˆ๋กœ์šด" ๋‹จ์ผ ๊ฐ’๋งŒ์œผ๋กœ๋„ ์ „์ฒด ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ๋ฉ”๋ชจํ™”๊ฐ€ ๊นจ์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. @@ -173,7 +173,7 @@ console.timeEnd('filter array'); ํƒญ์„ ์ „ํ™˜ํ•˜๋ฉด ๋А๋ ค์ง„ `filterTodos`๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋˜๋ฏ€๋กœ ๋А๋ฆฌ๊ฒŒ ๋А๊ปด์ง‘๋‹ˆ๋‹ค. ์ด๋Š” `tab`์ด ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋ฏ€๋กœ ์ „์ฒด ๊ณ„์‚ฐ์ด *ํ•„์ˆ˜์ ์œผ๋กœ* ๋‹ค์‹œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜ํƒ€๋‚˜๋Š” ํ˜„์ƒ์ž…๋‹ˆ๋‹ค. (์™œ ๋‘ ๋ฒˆ ์‹คํ–‰๋˜๋Š”์ง€ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด [์—ฌ๊ธฐ](#my-calculation-runs-twice-on-every-re-render)๋ฅผ ํด๋ฆญํ•ด์„œ ์„ค๋ช…์„ ํ™•์ธํ•˜์„ธ์š”.) -ํ…Œ๋งˆ๋ฅผ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. **์ธ์œ„์ ์ธ ์†๋„ ์ €ํ•˜์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋น ๋ฅธ ์ด์œ ๋Š” `useMemo` ๋•๋ถ„์ž…๋‹ˆ๋‹ค!** ๋А๋ฆฐ ์†๋„์˜ `filterTodos`๋Š” ๋งˆ์ง€๋ง‰ ๋ Œ๋”๋ง ์ดํ›„ (`useMemo`์— ์ข…์†์„ฑ์œผ๋กœ ์ „๋‹ฌํ•œ)`todos`์™€ `tab`์ด ๋ชจ๋‘ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ํ˜ธ์ถœ์„ ๊ฑด๋„ˆ๋›ฐ์—ˆ์Šต๋‹ˆ๋‹ค. +ํ…Œ๋งˆ๋ฅผ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. **์ธ์œ„์ ์ธ ์†๋„ ์ €ํ•˜์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋น ๋ฅธ ์ด์œ ๋Š” `useMemo` ๋•๋ถ„์ž…๋‹ˆ๋‹ค!** ๋А๋ฆฐ ์†๋„์˜ `filterTodos`๋Š” ๋งˆ์ง€๋ง‰ ๋ Œ๋”๋ง ์ดํ›„ (`useMemo`์— ์ข…์†์„ฑ์œผ๋กœ ์ „๋‹ฌํ•œ)`todos`์™€ `tab`์ด ๋ชจ๋‘ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ํ˜ธ์ถœ์„ ๊ฑด๋„ˆ๋›ฐ์—ˆ์Šต๋‹ˆ๋‹ค. <Sandpack> @@ -609,7 +609,7 @@ export default function TodoList({ todos, tab, theme }) { ``` -**`visibleTodos`์—ฐ์‚ฐ์„ `useMemo`๋กœ ๊ฐ์‹ธ๋ฉด ๋‹ค์‹œ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค *๊ฐ™์€* ๊ฐ’์„ ๊ฐ–๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค** (์ข…์†์„ฑ์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ์ „๊นŒ์ง€). *ํŠน๋ณ„ํ•œ ์ด์œ ๊ฐ€ ์—†๋Š” ํ•œ* ์—ฐ์‚ฐ์„ `useMemo`๋กœ ๊ฐ์‹ธ์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ์—์„œ๋Š” [`memo`](/reference/react/memo)๋กœ ๊ฐ์‹ธ์ง„ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•˜๋ฉด ์žฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ํŽ˜์ด์ง€์—์„œ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋Š” `useMemo`๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +**`visibleTodos`์—ฐ์‚ฐ์„ `useMemo`๋กœ ๊ฐ์‹ธ๋ฉด ๋‹ค์‹œ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค *๊ฐ™์€* ๊ฐ’์„ ๊ฐ–๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค** (์ข…์†์„ฑ์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ์ „๊นŒ์ง€). *ํŠน๋ณ„ํ•œ ์ด์œ ๊ฐ€ ์—†๋Š” ํ•œ* ์—ฐ์‚ฐ์„ `useMemo`๋กœ ๊ฐ์‹ธ์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ์—์„œ๋Š” [`memo`](/reference/react/memo)๋กœ ๊ฐ์‹ธ์ง„ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•˜๋ฉด ์žฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ํŽ˜์ด์ง€์—์„œ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋Š” `useMemo`๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. <DeepDive> @@ -1122,7 +1122,7 @@ function ChatRoom({ roomId }) { serverUrl: 'https://localhost:1234', roomId: roomId } - + const connection = createConnection(options); connection.connect(); return () => connection.disconnect(); @@ -1278,7 +1278,7 @@ React๊ฐ€ ํ•จ์ˆ˜๋ฅผ ๋‘ ๋ฒˆ ํ˜ธ์ถœํ•˜๋ฏ€๋กœ todo๊ฐ€ ๋‘ ๋ฒˆ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ๊ณ„ ์ˆœ์ˆ˜์„ฑ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด [์ปดํฌ๋„ŒํŠธ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ](/learn/keeping-components-pure)๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”. -๋˜ํ•œ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์—†๋Š” [๊ฐ์ฒด ์—…๋ฐ์ดํŠธ](/learn/updating-objects-in-state) ๋ฐ [๋ฐฐ์—ด ์—…๋ฐ์ดํŠธ](/learn/updating-arrays-in-state)์— ๋Œ€ํ•œ ๊ฐ€์ด๋“œ๋„ ํ™•์ธํ•ด๋ณด์„ธ์š”. +๋˜ํ•œ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์—†๋Š” [๊ฐ์ฒด ์—…๋ฐ์ดํŠธ](/learn/updating-objects-in-state) ๋ฐ [๋ฐฐ์—ด ์—…๋ฐ์ดํŠธ](/learn/updating-arrays-in-state)์— ๋Œ€ํ•œ ๊ฐ€์ด๋“œ๋„ ํ™•์ธํ•ด๋ณด์„ธ์š”. --- @@ -1363,7 +1363,7 @@ Object.is(temp1[2], temp2[2]); // ... ๊ทธ๋ฆฌ๊ณ  ๊ธฐํƒ€ ๋ชจ๋“  ์ข…์†์„ฑ๋“ค์ด ### ๋ฐ˜๋ณต๋ฌธ์—์„œ ๊ฐ ๋ชฉ๋ก ํ•ญ๋ชฉ์— ๋Œ€ํ•ด `useMemo`๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š”๋ฐ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. {/*i-need-to-call-usememo-for-each-list-item-in-a-loop-but-its-not-allowed*/} -`Chart` ์ปดํฌ๋„ŒํŠธ๊ฐ€ [`memo`](/reference/react/memo)๋กœ ๊ฐ์‹ธ์ ธ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. `ReportList` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋  ๋•Œ ๋ชฉ๋ก์˜ ๋ชจ๋“  `Chart`๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์„ ์ƒ๋žตํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฐ˜๋ณต๋ฌธ์—์„œ `useMemo`๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +`Chart` ์ปดํฌ๋„ŒํŠธ๊ฐ€ [`memo`](/reference/react/memo)๋กœ ๊ฐ์‹ธ์ ธ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. `ReportList` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋  ๋•Œ ๋ชฉ๋ก์˜ ๋ชจ๋“  `Chart`๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์„ ์ƒ๋žตํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฐ˜๋ณต๋ฌธ์—์„œ `useMemo`๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ```js {5-11} function ReportList({ items }) { diff --git a/src/content/reference/react/useReducer.md b/src/content/reference/react/useReducer.md index 9b45391f2..c055819fd 100644 --- a/src/content/reference/react/useReducer.md +++ b/src/content/reference/react/useReducer.md @@ -69,7 +69,7 @@ function handleClick() { // ... ``` -React๋Š” ํ˜„์žฌ `state`์™€ `dispatch`๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋œ action์„ ์ œ๊ณต๋ฐ›์•„ ํ˜ธ์ถœ๋œ `reducer`์˜ ๋ฐ˜ํ™˜๊ฐ’์„ ํ†ตํ•ด ๋‹ค์Œ state๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. +React๋Š” ํ˜„์žฌ `state`์™€ `dispatch`๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋œ action์„ ์ œ๊ณต๋ฐ›์•„ ํ˜ธ์ถœ๋œ `reducer`์˜ ๋ฐ˜ํ™˜๊ฐ’์„ ํ†ตํ•ด ๋‹ค์Œ state๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*dispatch-parameters*/} @@ -199,7 +199,7 @@ Actions์€ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ปจ๋ฒค์…˜์— ๋”ฐ ```js {5,9-12} function Form() { const [state, dispatch] = useReducer(reducer, { name: 'Taylor', age: 42 }); - + function handleButtonClick() { dispatch({ type: 'incremented_age' }); } @@ -292,7 +292,7 @@ export default function Form() { dispatch({ type: 'changed_name', nextName: e.target.value - }); + }); } return ( @@ -761,7 +761,7 @@ function TodoList({ username }) { #### ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜ ์ „๋‹ฌ {/*passing-the-initializer-function*/} -์ด ์˜ˆ์‹œ์—์„œ๋Š” ์ดˆ๊ธฐํ™” ๋‹จ๊ณ„์—์„œ๋งŒ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜์ธ `createInitialState`๋ฅผ ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์ธํ’‹์— ์ž…๋ ฅ ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ฆฌ๋ Œ๋”๋ง ์ƒํ™ฉ ๋“ฑ์—์„œ๋Š” ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +์ด ์˜ˆ์‹œ์—์„œ๋Š” ์ดˆ๊ธฐํ™” ๋‹จ๊ณ„์—์„œ๋งŒ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜์ธ `createInitialState`๋ฅผ ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์ธํ’‹์— ์ž…๋ ฅ ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ฆฌ๋ Œ๋”๋ง ์ƒํ™ฉ ๋“ฑ์—์„œ๋Š” ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. <Sandpack> diff --git a/src/content/reference/react/useState.md b/src/content/reference/react/useState.md index e19db6860..52d32168d 100644 --- a/src/content/reference/react/useState.md +++ b/src/content/reference/react/useState.md @@ -20,7 +20,7 @@ const [state, setState] = useState(initialState) ### `useState(initialState)` {/*usestate*/} -์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ `useState`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ [state ๋ณ€์ˆ˜](/learn/state-a-components-memory)๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. +์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ `useState`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ [state ๋ณ€์ˆ˜](/learn/state-a-components-memory)๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. ```js import { useState } from 'react'; @@ -79,7 +79,7 @@ function handleClick() { #### ์ฃผ์˜ ์‚ฌํ•ญ {/*setstate-caveats*/} -* `set` ํ•จ์ˆ˜๋Š” ***๋‹ค์Œ* ๋ Œ๋”๋ง์— ๋Œ€ํ•œ state ๋ณ€์ˆ˜๋งŒ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.** `set` ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ํ›„์—๋„ state ๋ณ€์ˆ˜์—๋Š” ์—ฌ์ „ํžˆ ํ˜ธ์ถœ ์ „ ํ™”๋ฉด์— ์žˆ๋˜ [์ด์ „ ๊ฐ’์ด ๋‹ด๊ฒจ ์žˆ์Šต๋‹ˆ๋‹ค.](#ive-updated-the-state-but-logging-gives-me-the-old-value) +* `set` ํ•จ์ˆ˜๋Š” ***๋‹ค์Œ* ๋ Œ๋”๋ง์— ๋Œ€ํ•œ state ๋ณ€์ˆ˜๋งŒ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.** `set` ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ํ›„์—๋„ state ๋ณ€์ˆ˜์—๋Š” ์—ฌ์ „ํžˆ ํ˜ธ์ถœ ์ „ ํ™”๋ฉด์— ์žˆ๋˜ [์ด์ „ ๊ฐ’์ด ๋‹ด๊ฒจ ์žˆ์Šต๋‹ˆ๋‹ค.](#ive-updated-the-state-but-logging-gives-me-the-old-value) * ์‚ฌ์šฉ์ž๊ฐ€ ์ œ๊ณตํ•œ ์ƒˆ๋กœ์šด ๊ฐ’์ด [`Object.is`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/is)์— ์˜ํ•ด ํ˜„์žฌ `state`์™€ ๋™์ผํ•˜๋‹ค๊ณ  ํŒ์ •๋˜๋ฉด, React๋Š” **์ปดํฌ๋„ŒํŠธ์™€ ๊ทธ ์ž์‹๋“ค์„ ๋ฆฌ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** ์ด๊ฒƒ์ด ๋ฐ”๋กœ ์ตœ์ ํ™”์ž…๋‹ˆ๋‹ค. ๊ฒฝ์šฐ์— ๋”ฐ๋ผ React๊ฐ€ ์ž์‹์„ ๊ฑด๋„ˆ๋›ฐ๊ธฐ ์ „์— ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์ฝ”๋“œ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. @@ -607,8 +607,8 @@ export default function Form() { <br /> (located in {person.artwork.city}) </p> - <img - src={person.artwork.image} + <img + src={person.artwork.image} alt={person.artwork.title} /> </> @@ -1157,7 +1157,7 @@ function handleClick() { console.log(count); // 0 setCount(count + 1); // 1๋กœ ๋ฆฌ๋ Œ๋”๋ง ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. - console.log(count); // ์•„์ง 0์ž…๋‹ˆ๋‹ค! + console.log(count); // ์•„์ง 0์ž…๋‹ˆ๋‹ค! setTimeout(() => { console.log(count); // ์—ฌ๊ธฐ๋„ 0์ด๊ณ ์š”! @@ -1225,16 +1225,16 @@ return <button onClick={(e) => handleClick(e)}>Click me</button> ```js {2,5-6,11-12} function TodoList() { - // ํ•ด๋‹น ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋Š” ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. + // ํ•ด๋‹น ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋Š” ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. const [todos, setTodos] = useState(() => { - // ํ•ด๋‹น ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜๋Š” ์ดˆ๊ธฐํ™” ๋™์•ˆ ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. + // ํ•ด๋‹น ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜๋Š” ์ดˆ๊ธฐํ™” ๋™์•ˆ ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. return createTodos(); }); function handleClick() { setTodos(prevTodos => { - // ํ•ด๋‹น ์—…๋ฐ์ดํ„ฐ ํ•จ์ˆ˜๋Š” ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. + // ํ•ด๋‹น ์—…๋ฐ์ดํ„ฐ ํ•จ์ˆ˜๋Š” ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. return [...prevTodos, createTodo()]; }); } diff --git a/src/content/reference/react/useSyncExternalStore.md b/src/content/reference/react/useSyncExternalStore.md index dd383c137..ef0b3692c 100644 --- a/src/content/reference/react/useSyncExternalStore.md +++ b/src/content/reference/react/useSyncExternalStore.md @@ -407,8 +407,8 @@ subscribe ํ•จ์ˆ˜๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ์ •์˜๋˜๋ฏ€๋กœ ๋ฆฌ๋ Œ๋”๋งํ•  ๋•Œ ```js {4-7} function ChatIndicator() { const isOnline = useSyncExternalStore(subscribe, getSnapshot); - - // ๐Ÿšฉํ•ญ์ƒ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ React๋Š” ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค ๋‹ค์‹œ ๊ตฌ๋…ํ•ฉ๋‹ˆ๋‹ค. + + // ๐Ÿšฉํ•ญ์ƒ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ React๋Š” ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค ๋‹ค์‹œ ๊ตฌ๋…ํ•ฉ๋‹ˆ๋‹ค. function subscribe() { // ... } diff --git a/src/content/reference/rsc/server-actions.md b/src/content/reference/rsc/server-actions.md index cffaa1b6d..b8914e705 100644 --- a/src/content/reference/rsc/server-actions.md +++ b/src/content/reference/rsc/server-actions.md @@ -37,7 +37,7 @@ function EmptyNote () { async function createNoteAction() { // Server Action 'use server'; - + await db.notes.create(); } @@ -50,8 +50,8 @@ React๊ฐ€ `EmptyNote` ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ, `createNoteAction` ```js {5} "use client"; -export default function Button({onClick}) { - console.log(onClick); +export default function Button({onClick}) { + console.log(onClick); // {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'} return <button onClick={() => onClick()}>Create Empty Note</button> } @@ -123,7 +123,7 @@ function UpdateName() { } }) } - + return ( <form action={submitAction}> <input type="text" name="name" disabled={isPending}/> diff --git a/src/content/reference/rsc/server-components.md b/src/content/reference/rsc/server-components.md index 96676a2d1..04db179bf 100644 --- a/src/content/reference/rsc/server-components.md +++ b/src/content/reference/rsc/server-components.md @@ -40,7 +40,7 @@ function Page({page}) { setContent(data.content); }); }, [page]); - + return <div>{sanitizeHtml(marked(content))}</div>; } ``` @@ -64,7 +64,7 @@ import sanitizeHtml from 'sanitize-html'; // Not included in bundle async function Page({page}) { // NOTE: loads *during* render, when the app is built. const content = await file.readFile(`${page}.md`); - + return <div>{sanitizeHtml(marked(content))}</div>; } ``` @@ -108,7 +108,7 @@ function Note({id}) { setNote(data.note); }); }, [id]); - + return ( <div> <Author id={note.authorId} /> @@ -248,7 +248,7 @@ export default function Expandable({children}) { <p>this is the second note</p> </Expandable> <!--...--> - </div> + </div> </body> ``` @@ -265,8 +265,8 @@ import db from './database'; async function Page({id}) { // Will suspend the Server Component. const note = await db.notes.get(id); - - // NOTE: not awaited, will start here and await on the client. + + // NOTE: not awaited, will start here and await on the client. const commentsPromise = db.comments.get(note.id); return ( <div> diff --git a/src/content/reference/rsc/use-server.md b/src/content/reference/rsc/use-server.md index aae8cbf39..786ba40af 100644 --- a/src/content/reference/rsc/use-server.md +++ b/src/content/reference/rsc/use-server.md @@ -6,7 +6,7 @@ canary: true <Canary> -`'use server'`๋Š” [React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉ](/learn/start-a-new-react-project#bleeding-edge-react-frameworks)ํ•˜๊ฑฐ๋‚˜ ๊ทธ์™€ ํ˜ธํ™˜๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค ๋•Œ๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. +`'use server'`๋Š” [React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉ](/learn/start-a-new-react-project#bleeding-edge-react-frameworks)ํ•˜๊ฑฐ๋‚˜ ๊ทธ์™€ ํ˜ธํ™˜๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค ๋•Œ๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. </Canary> diff --git a/src/content/reference/rules/react-calls-components-and-hooks.md b/src/content/reference/rules/react-calls-components-and-hooks.md index 133d54662..708cd91f8 100644 --- a/src/content/reference/rules/react-calls-components-and-hooks.md +++ b/src/content/reference/rules/react-calls-components-and-hooks.md @@ -43,7 +43,7 @@ React๊ฐ€ ๋ Œ๋”๋ง์„ ์กฐ์ •ํ•˜๋„๋ก ํ•˜๋ฉด ์—ฌ๋Ÿฌ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. Hook์€ ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook ๋‚ด๋ถ€์—์„œ๋งŒ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Hook์„ ์ผ๋ฐ˜ ๊ฐ’์ฒ˜๋Ÿผ ์ „๋‹ฌํ•˜์ง€ ๋งˆ์„ธ์š”. -Hook์€ ์ปดํฌ๋„ŒํŠธ์— React ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. Hook์€ ํ•ญ์ƒ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•˜๋ฉฐ ์ผ๋ฐ˜ ๊ฐ’์ฒ˜๋Ÿผ ์ „๋‹ฌํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. Hook์„ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœํ•ด์•ผ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” _๋กœ์ปฌ ์ถ”๋ก _ ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. +Hook์€ ์ปดํฌ๋„ŒํŠธ์— React ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. Hook์€ ํ•ญ์ƒ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•˜๋ฉฐ ์ผ๋ฐ˜ ๊ฐ’์ฒ˜๋Ÿผ ์ „๋‹ฌํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. Hook์„ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœํ•ด์•ผ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” _๋กœ์ปฌ ์ถ”๋ก _ ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ทœ์น™์„ ์–ด๊ธฐ๋ฉด React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx index 6849df35d..c03cba2a8 100644 --- a/src/pages/_document.tsx +++ b/src/pages/_document.tsx @@ -141,7 +141,7 @@ const MyDocument = () => { // An example of such content can be the keyboard shortcut displayed in the search bar document.documentElement.classList.add( window.navigator.platform.includes('Mac') - ? "platform-mac" + ? "platform-mac" : "platform-win" ); })(); diff --git a/src/utils/forwardRefWithAs.tsx b/src/utils/forwardRefWithAs.tsx index a0e73370d..354544a66 100644 --- a/src/utils/forwardRefWithAs.tsx +++ b/src/utils/forwardRefWithAs.tsx @@ -103,7 +103,7 @@ export function forwardRefWithAs<Props, ComponentType extends As>( } /* -Test components to make sure our dynamic As prop components work as intended +Test components to make sure our dynamic As prop components work as intended type PopupProps = { lol: string; children?: React.ReactNode | ((value?: number) => JSX.Element); From e894cee378285d5d10ac935987386ca313f8fd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 14:51:35 +0900 Subject: [PATCH 0326/1059] chore: create `.gitattributes` for consistent EOL handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `LF`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ผ๊ด€์ ์ธ EOL ํ•ธ๋“ค๋ง์„ ์œ„ํ•˜์—ฌ, `.gitattributes` ์ถ”๊ฐ€. --- .gitattributes | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..8a5a53391 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +# https://git-scm.com/docs/gitattributes + +# Ensure consistent EOL(LF) for all files that Git considers text files. +* text=auto eol=lf From 68e4587245ce0ddbf102780ced9dbac141ff067b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 14:57:41 +0900 Subject: [PATCH 0327/1059] chore: create `.vscode/extensions.json` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vscode ์‚ฌ์šฉ์ž๋“ค์„ ์œ„ํ•ด ๊ถŒ์žฅ ์„ค์น˜์‚ฌํ•ญ ๋ชฉ๋ก ์ถ”๊ฐ€. --- .vscode/extensions.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .vscode/extensions.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..034db5d67 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "editorconfig.editorconfig" + ] +} From 95fcd9b7c7fa81d3538ae37d0f6cbe977eabb2f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 15:04:42 +0900 Subject: [PATCH 0328/1059] chore: create `VScode.code-workspace` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— `.code-workspace` ํŒŒ์ผ์„ ํฌํ•จํ•˜๋ฉด ํŒ€ ์ž‘์—…์—์„œ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ์„ค์ •์„ ๊ฐ„์†Œํ™”ํ•˜๋ฉฐ, ์ƒ์‚ฐ์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. --- VScode.code-workspace | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 VScode.code-workspace diff --git a/VScode.code-workspace b/VScode.code-workspace new file mode 100644 index 000000000..c7223d8ef --- /dev/null +++ b/VScode.code-workspace @@ -0,0 +1,7 @@ +{ + "folders": [ + { + "path": "." + } + ] +} From cb2e7f514fed6a7d9e5ac70e1db9f81f873b362b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 15:38:31 +0900 Subject: [PATCH 0329/1059] chore: install `textlint-rule-allowed-uris` package as deps-dev for consistent markdown handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `https://ko.react.dev` ๋ฐ `http://ko.react.dev`๋กœ ์‹œ์ž‘ํ•˜๋Š” uri๋ฅผ ๋งˆํฌ๋‹ค์šด ๋ฌธ์„œ์—์„œ ์‚ฌ์šฉ ๊ธˆ์ง€ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ ๊ด€๋ จ ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜. --- .textlintrc | 5 - .textlintrc.js | 20 +++ package.json | 1 + src/content/learn/react-compiler.md | 6 +- src/content/reference/react/use.md | 6 +- src/content/reference/rules/index.md | 2 +- yarn.lock | 215 ++++++++++++++++++++++++++- 7 files changed, 241 insertions(+), 14 deletions(-) delete mode 100644 .textlintrc create mode 100644 .textlintrc.js diff --git a/.textlintrc b/.textlintrc deleted file mode 100644 index 474876784..000000000 --- a/.textlintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "filters": { - "comments": true - } -} diff --git a/.textlintrc.js b/.textlintrc.js new file mode 100644 index 000000000..fc2a0b9a5 --- /dev/null +++ b/.textlintrc.js @@ -0,0 +1,20 @@ +module.exports = { + rules: { + 'allowed-uris': { + disallowed: { + /** + * Disallow URIs starting with the following strings: + * - https://ko.react.dev + * - http://ko.react.dev + * + * For example, + * `https://ko.react.dev/reference/rules` can be replaced with `/reference/rules`. + */ + links: [/https?:\/\/ko\.react\.dev/g], + }, + }, + }, + filters: { + comments: true, + }, +}; diff --git a/package.json b/package.json index 3e6a27bfe..2ac0fbf2b 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "tailwindcss": "^3.4.1", "textlint": "^14.0.4", "textlint-filter-rule-comments": "^1.2.2", + "textlint-rule-allowed-uris": "^1.0.7", "textlint-tester": "^14.0.4", "typescript": "^4.0.2", "unist-util-visit": "^2.0.3", diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 588b2f071..6e0d3fc81 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -93,7 +93,7 @@ function TableContainer({ items }) { - React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React ์ปดํฌ๋„ŒํŠธ์™€ Hooks๋งŒ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜๋ฉฐ, ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. - React ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋‚˜ Hooks ์‚ฌ์ด์—์„œ ๊ณต์œ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -๋”ฐ๋ผ์„œ `expensivelyProcessAReallyLargeArrayOfObjects`๊ฐ€ ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค๋ฉด ๋™์ผํ•œ ์•„์ดํ…œ์ด ์ „๋‹ฌ๋˜๋”๋ผ๋„ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ณ„์‚ฐ์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๋” ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์ „์— ๋จผ์ € [ํ”„๋กœํŒŒ์ผ๋ง](https://ko.react.dev/reference/react/useMemo#how-to-tell-if-a-calculation-is-expensive)์„ ํ†ตํ•ด ํ•ด๋‹น ๊ณ„์‚ฐ์ด ์‹ค์ œ๋กœ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. +๋”ฐ๋ผ์„œ `expensivelyProcessAReallyLargeArrayOfObjects`๊ฐ€ ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค๋ฉด ๋™์ผํ•œ ์•„์ดํ…œ์ด ์ „๋‹ฌ๋˜๋”๋ผ๋„ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ณ„์‚ฐ์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๋” ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์ „์— ๋จผ์ € [ํ”„๋กœํŒŒ์ผ๋ง](/reference/react/useMemo#how-to-tell-if-a-calculation-is-expensive)์„ ํ†ตํ•ด ํ•ด๋‹น ๊ณ„์‚ฐ์ด ์‹ค์ œ๋กœ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. </DeepDive> ### ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฌด์—‡์„ ๊ฐ€์ •ํ•˜๋‚˜์š”? {/*what-does-the-compiler-assume*/} @@ -102,7 +102,7 @@ React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. 1. ์˜ฌ๋ฐ”๋ฅด๊ณ  ์˜๋ฏธ ์žˆ๋Š” JavaScript ์ฝ”๋“œ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 2. nullable/optional ๊ฐ’๊ณผ ์†์„ฑ์— ์ ‘๊ทผํ•˜๊ธฐ ์ „์— ๊ทธ ๊ฐ’์ด ์ •์˜๋˜์–ด ์žˆ๋Š”์ง€ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค. TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ [`strictNullChecks`](https://www.typescriptlang.org/ko/tsconfig/#strictNullChecks)์„ ํ™œ์„ฑํ™”ํ•˜์—ฌ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `if (object.nullableProperty) { object.nullableProperty.foo }`์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜, ์˜ต์…”๋„ ์ฒด์ด๋‹์„ ์‚ฌ์šฉํ•˜์—ฌ `object.nullableProperty?.foo`์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. -3. [React์˜ ๊ทœ์น™](https://ko.react.dev/reference/rules)์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. +3. [React์˜ ๊ทœ์น™](/reference/rules)์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React์˜ ๋งŽ์€ ๊ทœ์น™์„ ์ •์ ์œผ๋กœ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์—๋Ÿฌ๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ์•ˆ์ „ํ•˜๊ฒŒ ์ปดํŒŒ์ผ์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด [`eslint-plugin-react-compiler`](https://www.npmjs.com/package/eslint-plugin-react-compiler)์˜ ์„ค์น˜๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. @@ -396,7 +396,7 @@ React ์ปดํŒŒ์ผ๋Ÿฌ ์›Œํ‚น ๊ทธ๋ฃน์—์„œ๋„ ํšŒ์›์œผ๋กœ ์‹ ์ฒญํ•˜์—ฌ ํ”ผ๋“œ๋ฐฑ์„ ### `(0 , _c) is not a function` ์—๋Ÿฌ {/*0--_c-is-not-a-function-error*/} -์ด ์—๋Ÿฌ๋Š” React 19 RC ์ด์ƒ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๋จผ์ € [React 19 RC๋กœ ์•ฑ์„ ์—…๊ทธ๋ ˆ์ด๋“œ](https://ko.react.dev/blog/2024/04/25/react-19-upgrade-guide)ํ•˜์„ธ์š”. +์ด ์—๋Ÿฌ๋Š” React 19 RC ์ด์ƒ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๋จผ์ € [React 19 RC๋กœ ์•ฑ์„ ์—…๊ทธ๋ ˆ์ด๋“œ](/blog/2024/04/25/react-19-upgrade-guide)ํ•˜์„ธ์š”. React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ, [์›Œํ‚น ๊ทธ๋ฃน](https://github.com/reactwg/react-compiler/discussions/6)์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ์บ์‹œ ํ•จ์ˆ˜ ๊ตฌํ˜„์„ ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ€๋Šฅํ•˜๋ฉด React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. diff --git a/src/content/reference/react/use.md b/src/content/reference/react/use.md index 901099326..3861f0fc6 100644 --- a/src/content/reference/react/use.md +++ b/src/content/reference/react/use.md @@ -67,7 +67,7 @@ Promise์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋  ๋•Œ `use` Hook์€ [`Suspense`](/reference/react/Susp ### `use`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ context ์ฐธ์กฐํ•˜๊ธฐ {/*reading-context-with-use*/} -[context](/learn/passing-data-deeply-with-context)๊ฐ€ `use`์— ์ „๋‹ฌ๋˜๋ฉด [`useContext`](https://ko.react.dev/reference/react/useContext)์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. `useContext`๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ ํ˜ธ์ถœํ•ด์•ผ ํ•˜์ง€๋งŒ, `use`๋Š” `if`์™€ ๊ฐ™์€ ์กฐ๊ฑด๋ฌธ์ด๋‚˜ `for`์™€ ๊ฐ™์€ ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `use`๋Š” ์œ ์—ฐํ•˜๋ฏ€๋กœ `useContext`๋ณด๋‹ค ์„ ํ˜ธ๋ฉ๋‹ˆ๋‹ค. +[context](/learn/passing-data-deeply-with-context)๊ฐ€ `use`์— ์ „๋‹ฌ๋˜๋ฉด [`useContext`](/reference/react/useContext)์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. `useContext`๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ ํ˜ธ์ถœํ•ด์•ผ ํ•˜์ง€๋งŒ, `use`๋Š” `if`์™€ ๊ฐ™์€ ์กฐ๊ฑด๋ฌธ์ด๋‚˜ `for`์™€ ๊ฐ™์€ ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `use`๋Š” ์œ ์—ฐํ•˜๋ฏ€๋กœ `useContext`๋ณด๋‹ค ์„ ํ˜ธ๋ฉ๋‹ˆ๋‹ค. ```js [[2, 4, "theme"], [1, 4, "ThemeContext"]] import { use } from 'react'; @@ -97,7 +97,7 @@ function Form() { provider์™€ `Button` ์‚ฌ์ด์— ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋Š”์ง€๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `Form` ๋‚ด๋ถ€์˜ *์–ด๋А ๊ณณ์ด๋“ * `Button`์ด `use(ThemeContext)`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด `"dark"`๋ฅผ ๊ฐ’์œผ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. -[`useContext`](https://ko.react.dev/reference/react/useContext)์™€ ๋‹ฌ๋ฆฌ, <CodeStep step={2}>`use`</CodeStep>๋Š” <CodeStep step={1}>`if`</CodeStep>์™€ ๊ฐ™์€ ์กฐ๊ฑด๋ฌธ๊ณผ ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +[`useContext`](/reference/react/useContext)์™€ ๋‹ฌ๋ฆฌ, <CodeStep step={2}>`use`</CodeStep>๋Š” <CodeStep step={1}>`if`</CodeStep>์™€ ๊ฐ™์€ ์กฐ๊ฑด๋ฌธ๊ณผ ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js [[1, 2, "if"], [2, 3, "use"]] @@ -346,7 +346,7 @@ export default async function App() { } ``` -ํ•˜์ง€๋งŒ [์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ](https://ko.react.dev/reference/react/use-server)์—์„œ `await`์„ ์‚ฌ์šฉํ•˜๋ฉด `await` ๋ฌธ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋ Œ๋”๋ง์ด ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ Promise๋ฅผ prop์œผ๋กœ ์ „๋‹ฌํ•˜๋ฉด Promise๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์„ ์ฐจ๋‹จํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ [์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ](/reference/react/use-server)์—์„œ `await`์„ ์‚ฌ์šฉํ•˜๋ฉด `await` ๋ฌธ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋ Œ๋”๋ง์ด ์ฐจ๋‹จ๋ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ Promise๋ฅผ prop์œผ๋กœ ์ „๋‹ฌํ•˜๋ฉด Promise๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์„ ์ฐจ๋‹จํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </DeepDive> diff --git a/src/content/reference/rules/index.md b/src/content/reference/rules/index.md index ceecaa7c0..586abda2b 100644 --- a/src/content/reference/rules/index.md +++ b/src/content/reference/rules/index.md @@ -28,7 +28,7 @@ React๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋” ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด [ * [์ปดํฌ๋„ŒํŠธ๋Š” ๋ฉฑ๋“ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent) โ€“ React ์ปดํฌ๋„ŒํŠธ๋Š” ํ•ญ์ƒ ์ž…๋ ฅ ๊ฐ’(props, state, context)์— ๋”ฐ๋ผ ๋™์ผํ•œ ์ถœ๋ ฅ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. * [์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” ๋ Œ๋”๋ง ์™ธ๋ถ€์—์„œ ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) โ€“ [์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ](/learn/keeping-components-pure#side-effects-unintended-consequences)๋Š” React๊ฐ€ ์ตœ์ƒ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ Œ๋”๋ง ์ค‘์— ์‹คํ–‰๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. -* [Props์™€ state๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#props-and-state-are-immutable) โ€“ ์ปดํฌ๋„ŒํŠธ์˜ props์™€ state๋Š” ๋‹จ์ผ ๋ Œ๋”๋ง์— ๋Œ€ํ•ด ๋ถˆ๋ณ€์˜ [์Šค๋ƒ…์ƒท](https://ko.react.dev/learn/state-as-a-snapshot)์ž…๋‹ˆ๋‹ค. ์ ˆ๋Œ€ ์ด๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. +* [Props์™€ state๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#props-and-state-are-immutable) โ€“ ์ปดํฌ๋„ŒํŠธ์˜ props์™€ state๋Š” ๋‹จ์ผ ๋ Œ๋”๋ง์— ๋Œ€ํ•ด ๋ถˆ๋ณ€์˜ [์Šค๋ƒ…์ƒท](/learn/state-as-a-snapshot)์ž…๋‹ˆ๋‹ค. ์ ˆ๋Œ€ ์ด๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. * [Hook์˜ ๋ฐ˜ํ™˜๊ฐ’๊ณผ ์ธ์ˆ˜๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#return-values-and-arguments-to-hooks-are-immutable) โ€“ ๊ฐ’์ด Hook์— ์ „๋‹ฌ๋˜๋ฉด ์ด๋ฅผ ์ˆ˜์ •ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. JSX์˜ props์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Hook์— ์ „๋‹ฌ๋œ ๊ฐ’๋„ ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค. * [JSX๋กœ ์ „๋‹ฌ๋œ ๊ฐ’์€ ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#values-are-immutable-after-being-passed-to-jsx) โ€“ JSX์— ์‚ฌ์šฉ๋œ ํ›„์—๋Š” ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. JSX๊ฐ€ ์ƒ์„ฑ๋˜๊ธฐ ์ „์— ๋ณ€๊ฒฝ์„ ์ˆ˜ํ–‰ํ•˜์„ธ์š”. diff --git a/yarn.lock b/yarn.lock index 6be6095b5..355c72f6e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1934,6 +1934,11 @@ astring@^1.8.0: resolved "https://registry.npmjs.org/astring/-/astring-1.8.3.tgz" integrity sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + asyncro@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/asyncro/-/asyncro-3.0.0.tgz" @@ -1981,6 +1986,15 @@ axe-core@^4.3.5: resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz" integrity sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA== +axios@^1.7.4: + version "1.7.9" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.9.tgz#d7d071380c132a24accda1b2cfc1535b79ec650a" + integrity sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz" @@ -2053,6 +2067,11 @@ body-scroll-lock@^3.1.3: resolved "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz" integrity sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg== +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + boundary@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/boundary/-/boundary-2.0.0.tgz#169c8b1f0d44cf2c25938967a328f37e0a4e5efc" @@ -2247,6 +2266,35 @@ charenc@0.0.2: resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" + integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== + dependencies: + boolbase "^1.0.0" + css-select "^5.1.0" + css-what "^6.1.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + +cheerio@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0.tgz#1ede4895a82f26e8af71009f961a9b8cb60d6a81" + integrity sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww== + dependencies: + cheerio-select "^2.1.0" + dom-serializer "^2.0.0" + domhandler "^5.0.3" + domutils "^3.1.0" + encoding-sniffer "^0.2.0" + htmlparser2 "^9.1.0" + parse5 "^7.1.2" + parse5-htmlparser2-tree-adapter "^7.0.0" + parse5-parser-stream "^7.1.2" + undici "^6.19.5" + whatwg-mimetype "^4.0.0" + chokidar@^3.4.0, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" @@ -2358,6 +2406,13 @@ colorette@^2.0.16: resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + comma-separated-tokens@^1.0.0: version "1.0.8" resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz" @@ -2484,6 +2539,22 @@ css-prefers-color-scheme@^3.1.1: dependencies: postcss "^7.0.5" +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + cssdb@^4.4.0: version "4.4.0" resolved "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz" @@ -2639,6 +2710,11 @@ define-properties@^1.2.0, define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + depd@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" @@ -2700,6 +2776,36 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1, domutils@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.1.tgz#b39f4c390a1ae6f6a2c56a5f5a16d6438b6bce28" + integrity sha512-xWXmuRnN9OMP6ptPd2+H0cCbcYBULa5YDTbMm/2lvkWvNA3O4wcW+GvzooqBuNM8yy6pl3VIAeJTUUWUbfI5Fw== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + dotenv@^16.0.3: version "16.0.3" resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz" @@ -2750,6 +2856,14 @@ encodeurl@~1.0.2: resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +encoding-sniffer@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz#799569d66d443babe82af18c9f403498365ef1d5" + integrity sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg== + dependencies: + iconv-lite "^0.6.3" + whatwg-encoding "^3.1.1" + enquirer@^2.3.5: version "2.3.6" resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" @@ -2757,6 +2871,11 @@ enquirer@^2.3.5: dependencies: ansi-colors "^4.1.1" +entities@^4.2.0, entities@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" @@ -3459,6 +3578,11 @@ flatten@^1.0.2: resolved "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz" integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -3466,6 +3590,15 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +form-data@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + format@^0.2.0: version "0.2.2" resolved "https://registry.npmjs.org/format/-/format-0.2.2.tgz" @@ -3897,6 +4030,16 @@ html-void-elements@^1.0.0: resolved "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz" integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== +htmlparser2@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-9.1.0.tgz#cdb498d8a75a51f739b61d3f718136c369bc8c23" + integrity sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.1.0" + entities "^4.5.0" + http-errors@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" @@ -3925,6 +4068,13 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@0.6.3, iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" @@ -5487,7 +5637,7 @@ mime-types@2.1.13: dependencies: mime-db "~1.25.0" -mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.35, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -5728,6 +5878,13 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz" @@ -5998,6 +6155,28 @@ parse-numeric-range@^1.2.0: resolved "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz" integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ== +parse5-htmlparser2-tree-adapter@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz#b5a806548ed893a43e24ccb42fbb78069311e81b" + integrity sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g== + dependencies: + domhandler "^5.0.3" + parse5 "^7.0.0" + +parse5-parser-stream@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz#d7c20eadc37968d272e2c02660fff92dd27e60e1" + integrity sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow== + dependencies: + parse5 "^7.0.0" + +parse5@^7.0.0, parse5@^7.1.2: + version "7.2.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.2.1.tgz#8928f55915e6125f430cc44309765bf17556a33a" + integrity sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ== + dependencies: + entities "^4.5.0" + parseurl@~1.3.3: version "1.3.3" resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" @@ -6570,6 +6749,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + punycode@^2.1.0: version "2.1.1" resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" @@ -7118,7 +7302,7 @@ safe-regex-test@^1.0.3: es-errors "^1.3.0" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -7682,6 +7866,16 @@ textlint-filter-rule-comments@^1.2.2: resolved "https://registry.yarnpkg.com/textlint-filter-rule-comments/-/textlint-filter-rule-comments-1.2.2.tgz#3a72c494994e068e0e4aaad0f24ea7cfe338503a" integrity sha512-AtyxreCPb3Hq/bd6Qd6szY1OGgnW34LOjQXAHzE8NoXbTUudQqALPdRe+hvRsf81rnmGLxBiCUXZbnbpIseFyw== +textlint-rule-allowed-uris@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/textlint-rule-allowed-uris/-/textlint-rule-allowed-uris-1.0.7.tgz#199edcc038817e771256c541aa975a077fa64472" + integrity sha512-cLFOc80dn3kMYlnsGjwoDEppxUaIw7A3fo35afEr1o7JDc1bSHcsymS3tVxJDDHfKBZk0AYE7hNrGDA8g+r6FQ== + dependencies: + ansi-colors "^4.1.3" + axios "^1.7.4" + cheerio "^1.0.0" + mime-types "^2.1.35" + textlint-tester@^14.0.4: version "14.0.4" resolved "https://registry.yarnpkg.com/textlint-tester/-/textlint-tester-14.0.4.tgz#ed1b4c65bbd2fe5f8f78bb02ebc6400bef393a7a" @@ -7974,6 +8168,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +undici@^6.19.5: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.21.0.tgz#4b3d3afaef984e07b48e7620c34ed8a285ed4cd4" + integrity sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw== + unherit@^1.0.4: version "1.1.3" resolved "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz" @@ -8306,6 +8505,18 @@ webpack-bundle-analyzer@^4.5.0: sirv "^1.0.7" ws "^7.3.1" +whatwg-encoding@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz#d0f4ef769905d426e1688f3e34381a99b60b76e5" + integrity sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ== + dependencies: + iconv-lite "0.6.3" + +whatwg-mimetype@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz#bc1bf94a985dc50388d54a9258ac405c3ca2fc0a" + integrity sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg== + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" From db2c0df023fcd822ac58e9bcc47cd81a3a2a519e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 15:52:15 +0900 Subject: [PATCH 0330/1059] ci: update ci workflows to follow the latest react.dev source code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ์ตœ์‹  ์—…๋ฐ์ดํŠธ๋œ react.dev์˜ ์›Œํฌํ”Œ๋กœ ๋ฐ˜์˜. --- .github/workflows/analyze.yml | 18 +++++++++++++----- .github/workflows/site_lint.yml | 16 ++++++++++++---- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.github/workflows/analyze.yml b/.github/workflows/analyze.yml index 8330e30d2..555efe26b 100644 --- a/.github/workflows/analyze.yml +++ b/.github/workflows/analyze.yml @@ -11,18 +11,26 @@ jobs: analyze: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '20.x' + cache: yarn + cache-dependency-path: yarn.lock - - name: Install dependencies - uses: bahmutov/npm-install@v1.7.10 + - name: Restore cached node_modules + uses: actions/cache@v4 + with: + path: '**/node_modules' + key: node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }} + + - name: Install deps + run: yarn install --frozen-lockfile - name: Restore next build - uses: actions/cache@v3 + uses: actions/cache@v4 id: restore-build-cache env: cache-name: cache-next-build diff --git a/.github/workflows/site_lint.yml b/.github/workflows/site_lint.yml index 34ca6d7b8..2b01231eb 100644 --- a/.github/workflows/site_lint.yml +++ b/.github/workflows/site_lint.yml @@ -14,14 +14,22 @@ jobs: name: Lint on node 20.x and ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 20.x + cache: yarn + cache-dependency-path: yarn.lock - - name: Install deps and build (with cache) - uses: bahmutov/npm-install@v1.8.32 + - name: Restore cached node_modules + uses: actions/cache@v4 + with: + path: '**/node_modules' + key: node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }} + + - name: Install deps + run: yarn install --frozen-lockfile - name: Lint codebase run: yarn ci-check From 4bc1d1f887e2069378796f66f883fa5aad690405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 15:55:46 +0900 Subject: [PATCH 0331/1059] chore: bump lint-staged from 12.3.1 to 15.3.0 --- package.json | 2 +- yarn.lock | 471 +++++++++++++++++++++++++++------------------------ 2 files changed, 248 insertions(+), 225 deletions(-) diff --git a/package.json b/package.json index 2ac0fbf2b..dcaf8e055 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "gray-matter": "^4.0.2", "husky": "^7.0.4", "is-ci": "^3.0.1", - "lint-staged": ">=10", + "lint-staged": "^15.3.0", "mdast-util-to-string": "^1.1.0", "metro-cache": "0.72.2", "mocha": "^10.6.0", diff --git a/yarn.lock b/yarn.lock index 355c72f6e..50e3ad3b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1708,14 +1708,6 @@ acorn@^8.0.4: resolved "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" @@ -1772,12 +1764,12 @@ ansi-colors@^4.1.3: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== +ansi-escapes@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-7.0.0.tgz#00fc19f491bbb18e1d481b97868204f92109bfe7" + integrity sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw== dependencies: - type-fest "^0.21.3" + environment "^1.0.0" ansi-regex@^5.0.1: version "5.0.1" @@ -1808,6 +1800,11 @@ ansi-styles@^6.0.0: resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz" integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== +ansi-styles@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + any-promise@^1.0.0: version "1.3.0" resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz" @@ -2099,6 +2096,13 @@ braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + browser-stdout@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -2221,6 +2225,11 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: 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== + 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" @@ -2330,33 +2339,20 @@ clean-set@^1.1.2: resolved "https://registry.npmjs.org/clean-set/-/clean-set-1.1.2.tgz" integrity sha512-cA8uCj0qSoG9e0kevyOWXwPaELRPVg5Pxp6WskLMwerx257Zfnh8Nl0JBH59d7wQzij2CK7qEfJQK3RjuKKIug== -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== +cli-cursor@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-5.0.0.tgz#24a4831ecf5a6b01ddeb32fb71a4b2088b0dce38" + integrity sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw== dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" + restore-cursor "^5.0.0" -cli-truncate@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz" - integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== +cli-truncate@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-4.0.0.tgz#6cc28a2924fee9e25ce91e973db56c7066e6172a" + integrity sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA== dependencies: slice-ansi "^5.0.0" - string-width "^5.0.0" + string-width "^7.0.0" client-only@0.0.1: version "0.0.1" @@ -2401,10 +2397,10 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -colorette@^2.0.16: - version "2.0.16" - resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz" - integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== +colorette@^2.0.20: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== combined-stream@^1.0.8: version "1.0.8" @@ -2438,10 +2434,10 @@ commander@^7.2.0: resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== -commander@^8.3.0: - version "8.3.0" - resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +commander@~12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" + integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== concat-map@0.0.1: version "0.0.1" @@ -2646,7 +2642,7 @@ debug@^4.0.0, debug@^4.3.4: dependencies: ms "2.1.2" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3: +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.3" resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== @@ -2660,6 +2656,13 @@ debug@^4.3.5: dependencies: ms "2.1.2" +debug@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" + decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" @@ -2816,11 +2819,6 @@ duplexer@^0.1.2: resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - editorconfig-checker@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/editorconfig-checker/-/editorconfig-checker-6.0.0.tgz#f9bdcbd13411aab9a208030f88051add97bff2f6" @@ -2841,6 +2839,11 @@ electron-to-chromium@^1.4.202: resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.241.tgz" integrity sha512-e7Wsh4ilaioBZ5bMm6+F4V5c11dh56/5Jwz7Hl5Tu1J7cnB+Pqx5qIF2iC7HPpfyQMqGSvvLP5bBAIDd2gAtGw== +emoji-regex@^10.3.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.4.0.tgz#03553afea80b3975749cfcb36f776ca268e413d4" + integrity sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" @@ -2876,6 +2879,11 @@ entities@^4.2.0, entities@^4.5.0: resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== +environment@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/environment/-/environment-1.1.0.tgz#8e86c66b180f363c7ab311787e0259665f45a9f1" + integrity sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q== + error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" @@ -3351,20 +3359,25 @@ etag@~1.8.1: resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== -execa@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + +execa@~8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" + integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== dependencies: cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" + get-stream "^8.0.1" + human-signals "^5.0.0" + is-stream "^3.0.0" merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^4.1.0" + strip-final-newline "^3.0.0" express@^4.17.1: version "4.18.1" @@ -3506,6 +3519,13 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + finalhandler@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" @@ -3688,6 +3708,11 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-east-asian-width@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz#21b4071ee58ed04ee0db653371b55b4299875389" + integrity sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" @@ -3718,10 +3743,10 @@ get-stdin@^5.0.1: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" integrity sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA== -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-stream@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" + integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== get-symbol-description@^1.0.0: version "1.0.0" @@ -4051,10 +4076,10 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +human-signals@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" + integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== husky@^7.0.4: version "7.0.4" @@ -4103,11 +4128,6 @@ imurmurhash@^0.1.4: resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - indexes-of@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz" @@ -4334,6 +4354,13 @@ is-fullwidth-code-point@^4.0.0: resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz" integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== +is-fullwidth-code-point@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz#9609efced7c2f97da7b60145ef481c787c7ba704" + integrity sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA== + dependencies: + get-east-asian-width "^1.0.0" + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" @@ -4410,10 +4437,10 @@ is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: dependencies: call-bind "^1.0.7" -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" @@ -4613,53 +4640,48 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -lilconfig@2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz" - integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA== - lilconfig@^2.0.5, lilconfig@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz" integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== +lilconfig@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" + integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw== + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -lint-staged@>=10: - version "12.3.1" - resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.1.tgz" - integrity sha512-Ocht/eT+4/siWOZDJpNUKcKX2UeWW/pDbohJ4gRsrafAjBi79JK8kiNVk2ciIVNKdw0Q4ABptl2nr6uQAlRImw== - dependencies: - cli-truncate "^3.1.0" - colorette "^2.0.16" - commander "^8.3.0" - debug "^4.3.3" - execa "^5.1.1" - lilconfig "2.0.4" - listr2 "^4.0.1" - micromatch "^4.0.4" - normalize-path "^3.0.0" - object-inspect "^1.12.0" - string-argv "^0.3.1" - supports-color "^9.2.1" - yaml "^1.10.2" - -listr2@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/listr2/-/listr2-4.0.1.tgz" - integrity sha512-D65Nl+zyYHL2jQBGmxtH/pU8koPZo5C8iCNE8EoB04RwPgQG1wuaKwVbeZv9LJpiH4Nxs0FCp+nNcG8OqpniiA== - dependencies: - cli-truncate "^2.1.0" - colorette "^2.0.16" - log-update "^4.0.0" - p-map "^4.0.0" - rfdc "^1.3.0" - rxjs "^7.5.2" - through "^2.3.8" - wrap-ansi "^7.0.0" +lint-staged@^15.3.0: + version "15.3.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-15.3.0.tgz#32a0b3f2f2b8825950bd3b9fb093e045353bdfa3" + integrity sha512-vHFahytLoF2enJklgtOtCtIjZrKD/LoxlaUusd5nh7dWv/dkKQJY74ndFSzxCdv7g0ueGg1ORgTSt4Y9LPZn9A== + dependencies: + chalk "~5.4.1" + commander "~12.1.0" + debug "~4.4.0" + execa "~8.0.1" + lilconfig "~3.1.3" + listr2 "~8.2.5" + micromatch "~4.0.8" + pidtree "~0.6.0" + string-argv "~0.3.2" + yaml "~2.6.1" + +listr2@~8.2.5: + version "8.2.5" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-8.2.5.tgz#5c9db996e1afeb05db0448196d3d5f64fec2593d" + integrity sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ== + dependencies: + cli-truncate "^4.0.0" + colorette "^2.0.20" + eventemitter3 "^5.0.1" + log-update "^6.1.0" + rfdc "^1.4.1" + wrap-ansi "^9.0.0" load-json-file@^1.0.0: version "1.1.0" @@ -4725,15 +4747,16 @@ log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log-update@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" - integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== +log-update@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-6.1.0.tgz#1a04ff38166f94647ae1af562f4bd6a15b1b7cd4" + integrity sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w== dependencies: - ansi-escapes "^4.3.0" - cli-cursor "^3.1.0" - slice-ansi "^4.0.0" - wrap-ansi "^6.2.0" + ansi-escapes "^7.0.0" + cli-cursor "^5.0.0" + slice-ansi "^7.1.0" + strip-ansi "^7.1.0" + wrap-ansi "^9.0.0" longest-streak@^2.0.0, longest-streak@^2.0.1: version "2.0.4" @@ -5620,6 +5643,14 @@ micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" +micromatch@~4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + mime-db@1.52.0, mime-db@^1.52.0: version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" @@ -5649,10 +5680,15 @@ mime@1.6.0: resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +mimic-function@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mimic-function/-/mimic-function-5.0.1.tgz#acbe2b3349f99b9deaca7fb70e48b83e94e67076" + integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA== minimatch@^3.0.4: version "3.0.4" @@ -5871,12 +5907,12 @@ npm-run-all@^4.1.5: shell-quote "^1.6.1" string.prototype.padend "^3.0.0" -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== +npm-run-path@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" + integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ== dependencies: - path-key "^3.0.0" + path-key "^4.0.0" nth-check@^2.0.1: version "2.1.1" @@ -5900,7 +5936,7 @@ object-hash@^3.0.0: resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== -object-inspect@^1.11.0, object-inspect@^1.12.0, object-inspect@^1.9.0: +object-inspect@^1.11.0, object-inspect@^1.9.0: version "1.12.0" resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== @@ -5994,12 +6030,19 @@ once@^1.3.0: dependencies: wrappy "1" -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== dependencies: - mimic-fn "^2.1.0" + mimic-fn "^4.0.0" + +onetime@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-7.0.0.tgz#9f16c92d8c9ef5120e3acd9dd9957cceecc1ab60" + integrity sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ== + dependencies: + mimic-function "^5.0.0" open@^7.4.2: version "7.4.2" @@ -6081,13 +6124,6 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - p-try@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" @@ -6221,11 +6257,16 @@ path-key@^2.0.1: resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-key@^3.0.0, path-key@^3.1.0: +path-key@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.6, path-parse@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" @@ -6290,6 +6331,11 @@ pidtree@^0.3.0: resolved "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz" integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== +pidtree@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" + integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== + pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" @@ -7173,13 +7219,13 @@ resolve@^2.0.0-next.3: is-core-module "^2.2.0" path-parse "^1.0.6" -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== +restore-cursor@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-5.1.0.tgz#0766d95699efacb14150993f55baf0953ea1ebe7" + integrity sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA== dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" + onetime "^7.0.0" + signal-exit "^4.1.0" retext-latin@^2.0.0: version "2.0.4" @@ -7218,10 +7264,10 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== +rfdc@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" + integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== rimraf@2.6.3: version "2.6.3" @@ -7259,13 +7305,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^7.5.2: - version "7.5.2" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.5.2.tgz" - integrity sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w== - dependencies: - tslib "^2.1.0" - sade@^1.7.3: version "1.8.1" resolved "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz" @@ -7447,10 +7486,10 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.6" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz" - integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== sirv@^1.0.7: version "1.0.19" @@ -7471,15 +7510,6 @@ slash@^3.0.0: resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" - integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" @@ -7497,6 +7527,14 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" +slice-ansi@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-7.1.0.tgz#cd6b4655e298a8d1bdeb04250a433094b347b9a9" + integrity sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg== + dependencies: + ansi-styles "^6.2.1" + is-fullwidth-code-point "^5.0.0" + source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" @@ -7588,10 +7626,10 @@ strict-event-emitter@^0.4.3: resolved "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.4.6.tgz" integrity sha512-12KWeb+wixJohmnwNFerbyiBrAlq5qJLwIt38etRtKtmmHyDSoGlIqFE9wx+4IwG0aDjI7GV8tc8ZccjWZZtTg== -string-argv@^0.3.1: - version "0.3.1" - resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" - integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== +string-argv@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" + integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" @@ -7602,14 +7640,14 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.0.tgz" - integrity sha512-7x54QnN21P+XL/v8SuNKvfgsUre6PXpN7mc77N3HlZv+f1SBRGmjxtOud2Z6FZ8DmdkD/IdjCaf9XXbnqmTZGQ== +string-width@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc" + integrity sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ== dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" + emoji-regex "^10.3.0" + get-east-asian-width "^1.0.0" + strip-ansi "^7.1.0" string.prototype.matchall@^4.0.6: version "4.0.6" @@ -7702,10 +7740,10 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== +strip-ansi@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: ansi-regex "^6.0.1" @@ -7726,10 +7764,10 @@ strip-bom@^3.0.0: resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" @@ -7796,11 +7834,6 @@ supports-color@^8.1.1: dependencies: has-flag "^4.0.0" -supports-color@^9.2.1: - version "9.2.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-9.2.1.tgz" - integrity sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ== - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" @@ -7932,11 +7965,6 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" -through@^2.3.8: - version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - tiny-warning@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz" @@ -8064,11 +8092,6 @@ type-fest@^0.20.2: resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - type-is@~1.6.18: version "1.6.18" resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" @@ -8568,15 +8591,6 @@ workerpool@^6.5.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" @@ -8586,6 +8600,15 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-9.0.0.tgz#1a3dc8b70d85eeb8398ddfb1e4a02cd186e58b3e" + integrity sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q== + dependencies: + ansi-styles "^6.2.1" + string-width "^7.0.0" + strip-ansi "^7.1.0" + wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" @@ -8623,16 +8646,16 @@ yallist@^4.0.0: resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.2: - version "1.10.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - yaml@^2.1.1: version "2.3.1" resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz" integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== +yaml@~2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.1.tgz#42f2b1ba89203f374609572d5349fb8686500773" + integrity sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg== + yargs-parser@^20.2.2, yargs-parser@^20.2.9: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" From 02d5a920b154d912bd8470f4522fb3724e26f871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 20:37:48 +0900 Subject: [PATCH 0332/1059] docs: resolve conflicts in `sync-84f29eb2` --- src/content/community/acknowledgements.md | 6 +----- src/content/reference/react/useReducer.md | 12 +++--------- .../rules/components-and-hooks-must-be-pure.md | 6 +----- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/content/community/acknowledgements.md b/src/content/community/acknowledgements.md index 02eced6a1..5726771b3 100644 --- a/src/content/community/acknowledgements.md +++ b/src/content/community/acknowledgements.md @@ -4,11 +4,7 @@ title: ๊ฐ์‚ฌ์˜ ๋ง <Intro> -<<<<<<< HEAD -React๋Š” ์›๋ž˜ [Jordan Walke](https://github.com/jordwalke)์— ์˜ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜๋‚  React์—๋Š” [์ž‘์—…์„ ์ „๋‹ดํ•˜๋Š” ์ „์ž„ ํŒ€](/community/team)๊ณผ ์ฒœ์—ฌ ๋ช…์ด ๋„˜๋Š” [์˜คํ”ˆ ์†Œ์Šค ๊ธฐ์—ฌ์ž๋“ค](https://github.com/facebook/react/blob/main/AUTHORS)์ด ์žˆ์Šต๋‹ˆ๋‹ค. -======= -React was originally created by [Jordan Walke.](https://github.com/jordwalke) Today, React has a [dedicated full-time team working on it](/community/team), as well as over a thousand [open source contributors.](https://github.com/facebook/react/graphs/contributors) ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 +React๋Š” ์›๋ž˜ [Jordan Walke](https://github.com/jordwalke)์— ์˜ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜๋‚  React์—๋Š” [์ž‘์—…์„ ์ „๋‹ดํ•˜๋Š” ์ „์ž„ ํŒ€](/community/team)๊ณผ ์ฒœ์—ฌ ๋ช…์ด ๋„˜๋Š” [์˜คํ”ˆ ์†Œ์Šค ๊ธฐ์—ฌ์ž๋“ค](https://github.com/facebook/react/graphs/contributors)์ด ์žˆ์Šต๋‹ˆ๋‹ค. </Intro> diff --git a/src/content/reference/react/useReducer.md b/src/content/reference/react/useReducer.md index f3e62351f..5e169c23e 100644 --- a/src/content/reference/react/useReducer.md +++ b/src/content/reference/react/useReducer.md @@ -51,15 +51,9 @@ function MyComponent() { #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} -<<<<<<< HEAD -* `useReducer`๋Š” Hook์ด๋ฏ€๋กœ **์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„** ๋˜๋Š” ์ปค์Šคํ…€ Hook์—์„œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ณต๋ฌธ์ด๋‚˜ ์กฐ๊ฑด๋ฌธ์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”์ถœํ•˜๊ณ  ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋กœ state๋ฅผ ์˜ฎ๊ฒจ์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -* 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) -* Strict Mode์—์„œ๋Š” [์šฐ์—ฐํ•œ ๋น„์ˆœ์ˆ˜์„ฑ](#my-reducer-or-initializer-function-runs-twice)์„ ์ฐพ์•„๋‚ด๊ธฐ ์œ„ํ•ด reducer์™€ init ํ•จ์ˆ˜๋ฅผ ๋‘๋ฒˆ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋งŒ ํ•œ์ •๋œ ๋™์ž‘์ด๋ฉฐ, ๋ฐฐํฌ ๋ชจ๋“œ์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. reducer์™€ init ํ•จ์ˆ˜๊ฐ€ ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋ผ๋ฉด(๊ทธ๋ž˜์•ผ๋งŒ ํ•˜๋“ฏ์ด) ๋กœ์ง์— ์–ด๋– ํ•œ ์˜ํ–ฅ๋„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜ธ์ถœ ์ค‘ ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ๋Š” ๋ฌด์‹œํ•ฉ๋‹ˆ๋‹ค. -======= -* `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) -* 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. ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 +* `useReducer`๋Š” Hook์ด๋ฏ€๋กœ **์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„** ๋˜๋Š” ์ปค์Šคํ…€ Hook์—์„œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ณต๋ฌธ์ด๋‚˜ ์กฐ๊ฑด๋ฌธ์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”์ถœํ•˜๊ณ  ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋กœ State๋ฅผ ์˜ฎ๊ฒจ์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* 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) +* Strict Mode์—์„œ๋Š” [์šฐ์—ฐํ•œ ๋น„์ˆœ์ˆ˜์„ฑ](#my-reducer-or-initializer-function-runs-twice)์„ ์ฐพ์•„๋‚ด๊ธฐ ์œ„ํ•ด Reducer์™€ `init` ํ•จ์ˆ˜๋ฅผ ๋‘๋ฒˆ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋งŒ ํ•œ์ •๋œ ๋™์ž‘์ด๋ฉฐ, ๋ฐฐํฌ<sup>Production</sup> ํ™˜๊ฒฝ์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Reducer์™€ `init` ํ•จ์ˆ˜๊ฐ€ ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋ผ๋ฉด(๊ทธ๋ž˜์•ผ๋งŒ ํ•˜๋“ฏ์ด) ๋กœ์ง์— ์–ด๋– ํ•œ ์˜ํ–ฅ๋„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜ธ์ถœ ์ค‘ ํ•˜๋‚˜์˜ ๊ฒฐ๊ณผ๋Š” ๋ฌด์‹œํ•ฉ๋‹ˆ๋‹ค. --- 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 072bfb6b6..cc1bf4fe7 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,11 +194,7 @@ function ProductDetailPage({ product }) { } ``` -<<<<<<< HEAD -`window.title`์„ ๋ Œ๋”๋ง ์™ธ๋ถ€์—์„œ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ [์ปดํฌ๋„ŒํŠธ๋ฅผ `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). ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 +์›ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ๋ Œ๋”๋ง ์™ธ๋ถ€์—์„œ `document.title`์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ [์ปดํฌ๋„ŒํŠธ๋ฅผ `document`์™€ ๋™๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ](/learn/synchronizing-with-effects)์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•ด๋„ ์•ˆ์ „ํ•˜๊ณ  ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š” ํ•œ, React๋Š” ์—„๊ฒฉํ•œ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์˜๋ฏธ์—์„œ 100% ์ˆœ์ˆ˜ํ•˜์ง€ ์•Š์•„๋„ ์ƒ๊ด€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋” ์ค‘์š”ํ•œ ๊ฒƒ์€ [์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ˜๋“œ์‹œ ๋ฉฑ๋“ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ](/reference/rules/components-and-hooks-must-be-pure)์ž…๋‹ˆ๋‹ค. From cbafdc4b1ca79f2afe62e625a9c4d0cecb0069d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 20:47:26 +0900 Subject: [PATCH 0333/1059] =?UTF-8?q?docs:=20rename=20`react=20=ED=95=99?= =?UTF-8?q?=EC=8A=B5`=20to=20`react=20=ED=95=99=EC=8A=B5=ED=95=98=EA=B8=B0?= =?UTF-8?q?`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTRIBUTING.md | 4 ++-- src/components/Layout/HomeContent.js | 2 +- src/sidebarLearn.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 327466732..8b45bbd42 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,9 +16,9 @@ React ๋ฌธ์„œ ๊ธฐ์—ฌ์— ๊ด€์‹ฌ์„ ๊ฐ€์ ธ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ด ๋ฌธ์„œ๋Š” ๋‹ค์–‘ํ•œ ํ•™์Šต ์Šคํƒ€์ผ๊ณผ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋ถ„ํ• ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณธ๋ฌธ์„ ์ˆ˜์ •ํ•  ๋•Œ๋Š” ์ฃผ๋ณ€ ๊ธ€์˜ ํ†ค<sup>Tone</sup>๊ณผ ์Šคํƒ€์ผ<sup>Style</sup>์— ๋งž๊ฒŒ ์ž‘์„ฑํ•˜๋„๋ก ์ฃผ์˜ํ•˜์„ธ์š”. ์ƒˆ๋กœ์šด ๊ธ€์„ ์ž‘์„ฑํ•  ๋•Œ๋Š” ๊ฐ™์€ ์„น์…˜์— ์žˆ๋Š” ๋‹ค๋ฅธ ๊ธ€๋“ค๊ณผ ํ†ค์„ ๋งž์ถ”๋„๋ก ํ•˜์„ธ์š”. ๊ฐ ์„น์…˜์˜ ์˜๋„์™€ ๋™๊ธฐ๋Š” ์•„๋ž˜์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -**[React ํ•™์Šต](https://ko.react.dev/learn)** ์„น์…˜์€ ๊ธฐ์ดˆ ๊ฐœ๋…์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ œ๊ณต๋˜๋Š” ๊ธ€๋“ค์€ ์ด์ „์— ์„ค๋ช…๋œ ์ง€์‹์„ ๋ฐ”ํƒ•์œผ๋กœ ํ•˜๋ฏ€๋กœ, ๊ธ€ ๊ฐ„ ์•ž๋’ค ๊ฐœ๋…์ด ์ค‘๋ณต๋˜๊ฑฐ๋‚˜ ๊ผฌ์ด์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์„ธ์š”. ๋…์ž๋Š” ์ฒซ ๋ฒˆ์งธ ๊ธ€๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ๊ธ€๊นŒ์ง€ ์ˆœ์„œ๋Œ€๋กœ ์ฝ์œผ๋ฉฐ ๊ฐœ๋…์„ ์ตํž ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ, ์ถ”๊ฐ€ ์„ค๋ช…์„ ์œ„ํ•ด ๋ฏธ๋ฆฌ ์•ž์„  ๊ฐœ๋…๋“ค์„ ์‚ดํŽด๋ณด์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด์œ ๋กœ ์ƒํƒœ<sup>State</sup>๋Š” ์ด๋ฒคํŠธ<sup>Event</sup>๋ณด๋‹ค ๋จผ์ € ์„ค๋ช…๋˜๊ณ , 'React๋กœ ์‚ฌ๊ณ ํ•˜๊ธฐ' ํŒŒํŠธ์—์„œ `ref`๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋“ฑ ํŠน์ • ์ˆœ์„œ๊ฐ€ ์ •ํ•ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์‹œ์— 'React ํ•™์Šต'์€ React ๊ฐœ๋…์— ๋Œ€ํ•œ ์ฐธ๊ณ  ์ž๋ฃŒ ์—ญํ• ์„ ํ•˜๋ฏ€๋กœ, ๊ฐœ๋…๋“ค์— ๋Œ€ํ•œ ์ •์˜์™€ ์ƒํ˜ธ ๊ด€๊ณ„๋ฅผ ์—„๊ฒฉํ•˜๊ฒŒ ๋‹ค๋ฃจ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +**[React ํ•™์Šตํ•˜๊ธฐ](https://ko.react.dev/learn)** ์„น์…˜์€ ๊ธฐ์ดˆ ๊ฐœ๋…์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ œ๊ณต๋˜๋Š” ๊ธ€๋“ค์€ ์ด์ „์— ์„ค๋ช…๋œ ์ง€์‹์„ ๋ฐ”ํƒ•์œผ๋กœ ํ•˜๋ฏ€๋กœ, ๊ธ€ ๊ฐ„ ์•ž๋’ค ๊ฐœ๋…์ด ์ค‘๋ณต๋˜๊ฑฐ๋‚˜ ๊ผฌ์ด์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์„ธ์š”. ๋…์ž๋Š” ์ฒซ ๋ฒˆ์งธ ๊ธ€๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ๊ธ€๊นŒ์ง€ ์ˆœ์„œ๋Œ€๋กœ ์ฝ์œผ๋ฉฐ ๊ฐœ๋…์„ ์ตํž ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ, ์ถ”๊ฐ€ ์„ค๋ช…์„ ์œ„ํ•ด ๋ฏธ๋ฆฌ ์•ž์„  ๊ฐœ๋…๋“ค์„ ์‚ดํŽด๋ณด์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด์œ ๋กœ ์ƒํƒœ<sup>State</sup>๋Š” ์ด๋ฒคํŠธ<sup>Event</sup>๋ณด๋‹ค ๋จผ์ € ์„ค๋ช…๋˜๊ณ , 'React๋กœ ์‚ฌ๊ณ ํ•˜๊ธฐ' ํŒŒํŠธ์—์„œ `ref`๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋“ฑ ํŠน์ • ์ˆœ์„œ๊ฐ€ ์ •ํ•ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์‹œ์— 'React ํ•™์Šตํ•˜๊ธฐ'๋Š” React ๊ฐœ๋…์— ๋Œ€ํ•œ ์ฐธ๊ณ  ์ž๋ฃŒ ์—ญํ• ์„ ํ•˜๋ฏ€๋กœ, ๊ฐœ๋…๋“ค์— ๋Œ€ํ•œ ์ •์˜์™€ ์ƒํ˜ธ ๊ด€๊ณ„๋ฅผ ์—„๊ฒฉํ•˜๊ฒŒ ๋‹ค๋ฃจ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -**[API ๋ ˆํผ๋Ÿฐ์Šค](https://ko.react.dev/reference/react)** ์„น์…˜์€ ๊ฐœ๋…์ด ์•„๋‹Œ API๋ณ„๋กœ ์ •๋ฆฌ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๊ฐ€๋Šฅํ•œ ํ•œ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. 'React ํ•™์Šต'์—์„œ ๊ฐ„๋‹จํžˆ ๋‹ค๋ค˜๊ฑฐ๋‚˜ ์ƒ๋žตํ•œ ์˜ˆ์™ธ ์‚ฌํ•ญ<sup>Edge Cases</sup> ํ˜น์€ ๊ถŒ์žฅ ์‚ฌํ•ญ<sup>Recommendations</sup>์€ ํ•ด๋‹น API์˜ ๋ ˆํผ๋Ÿฐ์Šค ๋ฌธ์„œ์— ์ถ”๊ฐ€๋กœ ์–ธ๊ธ‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +**[API ๋ ˆํผ๋Ÿฐ์Šค](https://ko.react.dev/reference/react)** ์„น์…˜์€ ๊ฐœ๋…์ด ์•„๋‹Œ API๋ณ„๋กœ ์ •๋ฆฌ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๊ฐ€๋Šฅํ•œ ํ•œ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. 'React ํ•™์Šตํ•˜๊ธฐ'์—์„œ ๊ฐ„๋‹จํžˆ ๋‹ค๋ค˜๊ฑฐ๋‚˜ ์ƒ๋žตํ•œ ์˜ˆ์™ธ ์‚ฌํ•ญ<sup>Edge Cases</sup> ํ˜น์€ ๊ถŒ์žฅ ์‚ฌํ•ญ<sup>Recommendations</sup>์€ ํ•ด๋‹น API์˜ ๋ ˆํผ๋Ÿฐ์Šค ๋ฌธ์„œ์— ์ถ”๊ฐ€๋กœ ์–ธ๊ธ‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. **์Šค์Šค๋กœ ์ž‘์„ฑํ•œ ์ง€์นจ<sup>Instructions</sup>์„ ์‹ค์ฒœํ•ด ๋ณด์„ธ์š”.** diff --git a/src/components/Layout/HomeContent.js b/src/components/Layout/HomeContent.js index 6a7f46a70..5a5097321 100644 --- a/src/components/Layout/HomeContent.js +++ b/src/components/Layout/HomeContent.js @@ -174,7 +174,7 @@ export function HomeContent() { <Br /> ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ๋งŒ๋“ค๊ธฐ </Header> <Para> - React๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ์กฐ๊ฐ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž + React๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๋ผ ๋ถˆ๋ฆฌ๋Š” ์กฐ๊ฐ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <Code>Thumbnail</Code>,{' '} <Code>LikeButton</Code>, ๊ทธ๋ฆฌ๊ณ  <Code>Video</Code> ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ „์ฒด ํ™”๋ฉด, ํŽ˜์ด์ง€ ๋ฐ ์•ฑ์—์„œ ์ด๋“ค์„ diff --git a/src/sidebarLearn.json b/src/sidebarLearn.json index b1eaecf61..f318d9ab2 100644 --- a/src/sidebarLearn.json +++ b/src/sidebarLearn.json @@ -1,5 +1,5 @@ { - "title": "React ํ•™์Šต", + "title": "React ํ•™์Šตํ•˜๊ธฐ", "path": "/learn", "routes": [ { @@ -53,7 +53,7 @@ }, { "hasSectionHeader": true, - "sectionHeader": "React ํ•™์Šต" + "sectionHeader": "React ํ•™์Šตํ•˜๊ธฐ" }, { "title": "UI ํ‘œํ˜„ํ•˜๊ธฐ", From e0f46187cd6e12e29cc34edfcb3df936604e5b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 21:40:53 +0900 Subject: [PATCH 0334/1059] docs: update Korean terminology for API reference and installation sections --- CONTRIBUTING.md | 2 +- src/components/Layout/Footer.tsx | 6 +- src/components/Layout/HomeContent.js | 95 ++++++++++--------- src/components/Layout/TopNav/TopNav.tsx | 2 +- .../blog/2023/03/16/introducing-react-dev.md | 8 +- src/content/learn/index.md | 2 +- src/content/learn/tutorial-tic-tac-toe.md | 2 +- src/sidebarHome.json | 2 +- src/sidebarLearn.json | 2 +- src/sidebarReference.json | 2 +- 10 files changed, 64 insertions(+), 59 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8b45bbd42..96229a467 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ React ๋ฌธ์„œ ๊ธฐ์—ฌ์— ๊ด€์‹ฌ์„ ๊ฐ€์ ธ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! **[React ํ•™์Šตํ•˜๊ธฐ](https://ko.react.dev/learn)** ์„น์…˜์€ ๊ธฐ์ดˆ ๊ฐœ๋…์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ œ๊ณต๋˜๋Š” ๊ธ€๋“ค์€ ์ด์ „์— ์„ค๋ช…๋œ ์ง€์‹์„ ๋ฐ”ํƒ•์œผ๋กœ ํ•˜๋ฏ€๋กœ, ๊ธ€ ๊ฐ„ ์•ž๋’ค ๊ฐœ๋…์ด ์ค‘๋ณต๋˜๊ฑฐ๋‚˜ ๊ผฌ์ด์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์„ธ์š”. ๋…์ž๋Š” ์ฒซ ๋ฒˆ์งธ ๊ธ€๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ๊ธ€๊นŒ์ง€ ์ˆœ์„œ๋Œ€๋กœ ์ฝ์œผ๋ฉฐ ๊ฐœ๋…์„ ์ตํž ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ, ์ถ”๊ฐ€ ์„ค๋ช…์„ ์œ„ํ•ด ๋ฏธ๋ฆฌ ์•ž์„  ๊ฐœ๋…๋“ค์„ ์‚ดํŽด๋ณด์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด์œ ๋กœ ์ƒํƒœ<sup>State</sup>๋Š” ์ด๋ฒคํŠธ<sup>Event</sup>๋ณด๋‹ค ๋จผ์ € ์„ค๋ช…๋˜๊ณ , 'React๋กœ ์‚ฌ๊ณ ํ•˜๊ธฐ' ํŒŒํŠธ์—์„œ `ref`๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋“ฑ ํŠน์ • ์ˆœ์„œ๊ฐ€ ์ •ํ•ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์‹œ์— 'React ํ•™์Šตํ•˜๊ธฐ'๋Š” React ๊ฐœ๋…์— ๋Œ€ํ•œ ์ฐธ๊ณ  ์ž๋ฃŒ ์—ญํ• ์„ ํ•˜๋ฏ€๋กœ, ๊ฐœ๋…๋“ค์— ๋Œ€ํ•œ ์ •์˜์™€ ์ƒํ˜ธ ๊ด€๊ณ„๋ฅผ ์—„๊ฒฉํ•˜๊ฒŒ ๋‹ค๋ฃจ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -**[API ๋ ˆํผ๋Ÿฐ์Šค](https://ko.react.dev/reference/react)** ์„น์…˜์€ ๊ฐœ๋…์ด ์•„๋‹Œ API๋ณ„๋กœ ์ •๋ฆฌ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๊ฐ€๋Šฅํ•œ ํ•œ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. 'React ํ•™์Šตํ•˜๊ธฐ'์—์„œ ๊ฐ„๋‹จํžˆ ๋‹ค๋ค˜๊ฑฐ๋‚˜ ์ƒ๋žตํ•œ ์˜ˆ์™ธ ์‚ฌํ•ญ<sup>Edge Cases</sup> ํ˜น์€ ๊ถŒ์žฅ ์‚ฌํ•ญ<sup>Recommendations</sup>์€ ํ•ด๋‹น API์˜ ๋ ˆํผ๋Ÿฐ์Šค ๋ฌธ์„œ์— ์ถ”๊ฐ€๋กœ ์–ธ๊ธ‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +**[API ์ฐธ๊ณ ์„œ](https://ko.react.dev/reference/react)** ์„น์…˜์€ ๊ฐœ๋…์ด ์•„๋‹Œ API๋ณ„๋กœ ์ •๋ฆฌ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๊ฐ€๋Šฅํ•œ ํ•œ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. 'React ํ•™์Šตํ•˜๊ธฐ'์—์„œ ๊ฐ„๋‹จํžˆ ๋‹ค๋ค˜๊ฑฐ๋‚˜ ์ƒ๋žตํ•œ ์˜ˆ์™ธ ์‚ฌํ•ญ<sup>Edge Cases</sup> ํ˜น์€ ๊ถŒ์žฅ ์‚ฌํ•ญ<sup>Recommendations</sup>์€ ํ•ด๋‹น API์˜ ๋ ˆํผ๋Ÿฐ์Šค ๋ฌธ์„œ์— ์ถ”๊ฐ€๋กœ ์–ธ๊ธ‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. **์Šค์Šค๋กœ ์ž‘์„ฑํ•œ ์ง€์นจ<sup>Instructions</sup>์„ ์‹ค์ฒœํ•ด ๋ณด์„ธ์š”.** diff --git a/src/components/Layout/Footer.tsx b/src/components/Layout/Footer.tsx index f912ba2ae..4b2dedd48 100644 --- a/src/components/Layout/Footer.tsx +++ b/src/components/Layout/Footer.tsx @@ -336,7 +336,7 @@ export function Footer() { ์ปค๋ฎค๋‹ˆํ‹ฐ </FooterLink> <FooterLink href="https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md"> - Code of Conduct + ํ–‰๋™ ๊ฐ•๋ น </FooterLink> <FooterLink href="/community/team">ํŒ€ ์†Œ๊ฐœ</FooterLink> <FooterLink href="/community/docs-contributors"> @@ -347,7 +347,9 @@ export function Footer() { <div className="flex flex-col"> <FooterLink isHeader={true}>๋” ๋ณด๊ธฐ</FooterLink> <FooterLink href="/blog">๋ธ”๋กœ๊ทธ</FooterLink> - <FooterLink href="https://reactnative.dev/">React Native</FooterLink> + <FooterLink href="https://reactnative.dev/"> + React ๋„ค์ดํ‹ฐ๋ธŒ + </FooterLink> <FooterLink href="https://opensource.facebook.com/legal/privacy"> ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ </FooterLink> diff --git a/src/components/Layout/HomeContent.js b/src/components/Layout/HomeContent.js index 5a5097321..7c7aa4c3f 100644 --- a/src/components/Layout/HomeContent.js +++ b/src/components/Layout/HomeContent.js @@ -162,7 +162,7 @@ export function HomeContent() { size="lg" className="w-full sm:w-auto justify-center" label="API Reference"> - API ๋ ˆํผ๋Ÿฐ์Šค + API ์ฐธ๊ณ ์„œ </ButtonLink> </div> </div> @@ -177,8 +177,8 @@ export function HomeContent() { React๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๋ผ ๋ถˆ๋ฆฌ๋Š” ์กฐ๊ฐ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <Code>Thumbnail</Code>,{' '} <Code>LikeButton</Code>, ๊ทธ๋ฆฌ๊ณ  <Code>Video</Code> ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ - ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ „์ฒด ํ™”๋ฉด, ํŽ˜์ด์ง€ ๋ฐ ์•ฑ์—์„œ ์ด๋“ค์„ - ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + ๋งŒ๋“ค์–ด ๋ณด์„ธ์š”. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ „์ฒด ํ™”๋ฉด, ํŽ˜์ด์ง€ ๋ฐ ์•ฑ์—์„œ ์ด๋“ค์„ ๊ฒฐํ•ฉํ•  + ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Para> </Center> <FullBleed> @@ -200,10 +200,10 @@ export function HomeContent() { <Br /> ์ปดํฌ๋„ŒํŠธ ์ž‘์„ฑํ•˜๊ธฐ </Header> <Para> - React ์ปดํฌ๋„ŒํŠธ๋Š” JavaScript ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์กฐ๊ฑด๋ถ€๋กœ ๋‚ด์šฉ์„ ํ‘œ์‹œํ•˜๋ ค๋ฉด{' '} - <Code>if</Code> ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชฉ๋ก์„ ํ‘œ์‹œํ•˜๋ ค๋ฉด ๋ฐฐ์—ด์—{' '} - <Code>map()</Code>์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React๋ฅผ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์€ - ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. + React ์ปดํฌ๋„ŒํŠธ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์กฐ๊ฑด๋ถ€๋กœ ๋‚ด์šฉ์„ + ํ‘œ์‹œํ•˜๋ ค๋ฉด <Code>if</Code> ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชฉ๋ก์„ + ํ‘œ์‹œํ•˜๋ ค๋ฉด ๋ฐฐ์—ด์— <Code>map()</Code>์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React๋ฅผ + ๋ฐฐ์šฐ๋Š” ๊ฒƒ์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. </Para> </Center> <FullBleed> @@ -211,9 +211,9 @@ export function HomeContent() { </FullBleed> <Center> <Para> - ์ด ๋งˆํฌ์—… ๊ตฌ๋ฌธ์„ JSX ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ React์— ์˜ํ•ด์„œ ๋Œ€์ค‘ํ™”๋œ - JavaScript ๊ตฌ๋ฌธ์˜ ํ™•์žฅ์ž…๋‹ˆ๋‹ค. JSX ๋งˆํฌ์—…์„ ๊ด€๋ จ๋œ ๋ Œ๋”๋ง ๋กœ์ง๊ณผ - ๊ฐ€๊นŒ์ด ๋‘๋ฉด, React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ณ  ์œ ์ง€ํ•˜๊ณ  ์‚ญ์ œํ•  ์ˆ˜ + ์ด ๋งˆํฌ์—… ๊ตฌ๋ฌธ์„ JSX๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ React์— ์˜ํ•ด์„œ ๋Œ€์ค‘ํ™”๋œ + ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ตฌ๋ฌธ์˜ ํ™•์žฅ์ž…๋‹ˆ๋‹ค. JSX ๋งˆํฌ์—…์„ ๊ด€๋ จ๋œ ๋ Œ๋”๋ง ๋กœ์ง๊ณผ + ๊ฐ€๊นŒ์ด ๋‘๋ฉด, React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ณ  ๊ด€๋ฆฌํ•˜๊ณ  ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Para> </Center> @@ -238,7 +238,7 @@ export function HomeContent() { <Center> <Para> ์ „์ฒด ํŽ˜์ด์ง€๋ฅผ React๋กœ ๋นŒ๋“œํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. React๋ฅผ ๊ธฐ์กด HTML - ํŽ˜์ด์ง€์— ์ถ”๊ฐ€ํ•˜๊ณ , ์–ด๋””์—์„œ๋‚˜ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ + ํŽ˜์ด์ง€์— ์ถ”๊ฐ€ํ•˜๊ณ , ํŽ˜์ด์ง€ ์–ด๋””์—์„œ๋‚˜ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Para> <div className="flex justify-start w-full lg:justify-center"> @@ -255,13 +255,14 @@ export function HomeContent() { <Section background="right-card"> <Center> <Header> - ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ†ตํ•ด์„œ + ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ†ตํ•ด <Br /> ํ’€์Šคํƒ์œผ๋กœ ๋งŒ๋“ค๊ธฐ </Header> <Para> - React๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•จ๊ป˜ ๋ฌถ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ผ์šฐํŒ…๊ณผ - ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ๊ทœ์ •ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. React๋กœ ์•ฑ์„ - ๋งŒ๋“ค๋ ค๋ฉด, <Link href="https://nextjs.org">Next.js</Link> ๋˜๋Š”{' '} + React๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ์กฐํ•ฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ์ง€๋งŒ, + ๋ผ์šฐํŒ…์ด๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ๊ทœ์ •ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. React๋กœ + ์™„์ „ํ•œ ์•ฑ์„ ๋งŒ๋“ค๋ ค๋ฉด,{' '} + <Link href="https://nextjs.org">Next.js</Link> ๋˜๋Š”{' '} <Link href="https://remix.run">Remix</Link> ๊ฐ™์€ ํ’€์Šคํƒ React ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. </Para> @@ -271,10 +272,11 @@ export function HomeContent() { </FullBleed> <Center> <Para> - React๋Š” ์•„ํ‚คํ…์ฒ˜์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด - ์„œ๋ฒ„์—์„œ ์‹คํ–‰๋˜๋Š” ๋น„๋™๊ธฐ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋˜๋Š” ๋นŒ๋“œ ๋„์ค‘์— ๋ฐ์ดํ„ฐ๋ฅผ - ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ์ด๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ , ์ด๋ฅผ - ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + React๋Š” ์•„ํ‚คํ…์ฒ˜์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์„œ๋ฒ„์—์„œ + ์‹คํ–‰๋˜๋Š” ๋น„๋™๊ธฐ ์ปดํฌ๋„ŒํŠธ ํ˜น์€ ๋นŒ๋“œ ์ค‘์— ์‹คํ–‰๋˜๋Š” ๋น„๋™๊ธฐ + ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ์ด๋‚˜ + ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ , ์ด๋ฅผ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์— + ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Para> <div className="flex justify-start w-full lg:justify-center"> <CTA @@ -293,7 +295,7 @@ export function HomeContent() { <Para> ์‚ฌ๋žŒ๋“ค์€ ๋‹ค์–‘ํ•œ ์ด์œ ๋กœ ์›น๊ณผ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. React๋Š” ๋™์ผํ•œ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ์›น ์•ฑ๊ณผ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์„ ๋ชจ๋‘ ๋งŒ๋“ค ์ˆ˜ - ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ํ”Œ๋žซํผ์— ๊ฐ•์ ์„ ํ™œ์šฉํ•˜์—ฌ ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ ์ ํ•ฉํ•œ + ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ํ”Œ๋žซํผ์˜ ์žฅ์ ์„ ํ™œ์šฉํ•˜์—ฌ ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ ์ ํ•ฉํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Para> </div> @@ -311,12 +313,12 @@ export function HomeContent() { ์›น์— ์ถฉ์‹คํ•˜๊ธฐ </h4> <p className="lg:text-xl leading-normal text-secondary"> - ์‚ฌ๋žŒ๋“ค์€ ์›น์ด ๋น ๋ฅด๊ฒŒ ๋กœ๋“œ๋˜๊ธธ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ + ์‚ฌ๋žŒ๋“ค์€ ์›น ์•ฑ์ด ๋น ๋ฅด๊ฒŒ ๋กœ๋“œ๋˜๊ธธ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ React๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋™์•ˆ HTML์„ - ์ŠคํŠธ๋ฆฌ๋ฐํ•˜์—ฌ JavaScript ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์— ๋‚จ์€ ๋‚ด์šฉ์„ - ์ ์ง„์ ์œผ๋กœ ์ฑ„์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ React๋Š” ํ‘œ์ค€ - web API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋ง ์ค‘์—๋„ UI๋ฅผ ๋ฐ˜์‘์ ์œผ๋กœ ์œ ์ง€ํ•  - ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + ์ŠคํŠธ๋ฆฌ๋ฐํ•˜์—ฌ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์— ๋‚จ์€ + ๋‚ด์šฉ์„ ์ ์ง„์ ์œผ๋กœ ์ฑ„์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ + React๋Š” ํ‘œ์ค€ ์›น API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋ง ์ค‘์—๋„ UI๋ฅผ + ๋ฐ˜์‘ํ•˜๋„๋ก ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </p> </div> </div> @@ -394,21 +396,22 @@ export function HomeContent() { </div> <div className="flex flex-col items-start justify-center pt-0 gap-3 px-2.5 lg:pt-8 lg:px-8"> <h4 className="leading-tight text-primary dark:text-primary-dark font-semibold text-3xl lg:text-4xl"> - ๋„ค์ดํ‹ฐ๋ธŒ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ + ์ง„์ •ํ•œ ๋„ค์ดํ‹ฐ๋ธŒ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ </h4> <p className="h-full lg:text-xl text-secondary dark:text-secondary-dark leading-normal"> - ์‚ฌ๋žŒ๋“ค์€ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์ด ํ”Œ๋žซํผ๊ณผ ๊ฐ™์€ ๋ชจ์–‘์ฒ˜๋Ÿผ - ๋А๊ปด์ง€๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค.{' '} + ์‚ฌ๋žŒ๋“ค์€ ๋„ค์ดํ‹ฐ๋ธŒ<sup>Native</sup> ์•ฑ์ด ํ•ด๋‹น ํ”Œ๋žซํผ์˜ + ๋ชจ์Šต๊ณผ ๋А๋‚Œ์„ ๊ฐ–๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.{' '} <Link href="https://reactnative.dev"> React Native </Link> ์™€{' '} <Link href="https://github.com/expo/expo">Expo</Link> - ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด React๋ฅผ ํ†ตํ•˜์—ฌ Android, iOS ๋“ฑ์„ ์œ„ํ•œ ์•ฑ์„ - ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UI๋“ค์ด native์ด๊ธฐ ๋•Œ๋ฌธ์— ์ง„์งœ - native์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ web view๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. React - ์ปดํฌ๋„ŒํŠธ๋“ค์€ ์‹ค์ œ Android, iOS ํ”Œ๋žซํผ์—์„œ ์ œ๊ณตํ•˜๋Š” - view๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. + ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด React๋ฅผ ํ†ตํ•ด Android, iOS ๋“ฑ์„ ์œ„ํ•œ ์•ฑ์„ + ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. UI๊ฐ€ ์ง„์ •ํ•œ ๋„ค์ดํ‹ฐ๋ธŒ์ด๊ธฐ ๋•Œ๋ฌธ์— + ๋„ค์ดํ‹ฐ๋ธŒ์ฒ˜๋Ÿผ ๋ณด์ด๊ณ  ๋А๊ปด์ง‘๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์›น ๋ทฐ + <sup>Web View</sup>๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. React ์ปดํฌ๋„ŒํŠธ๋“ค์€ + ์‹ค์ œ Android, iOS ํ”Œ๋žซํผ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ทฐ + <sup>View</sup>๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. </p> </div> </div> @@ -441,9 +444,9 @@ export function HomeContent() { <Br breakPointPrefix="xl" /> ์—…๊ทธ๋ ˆ์ด๋“œ ํ•˜๊ธฐ </Header> <Para> - React๋Š” ๋ณ€ํ™”์— ์‹ ์ค‘ํ•˜๊ฒŒ ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  React ์ปค๋ฐ‹์€ 10์–ต ๋ช… - ์ด์ƒ์˜ ์‚ฌ์šฉ์ž๊ฐ€ ์žˆ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค์— ํฌ๋ฆฌํ‹ฐ์ปฌํ•œ ์˜์—ญ์—์„œ ํ…Œ์ŠคํŠธ - ๋ฉ๋‹ˆ๋‹ค. Meta์—์„œ๋Š” 10๋งŒ ๊ฐœ ์ด์ƒ์˜ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ชจ๋“  + React๋Š” ๋ณ€ํ™”์— ์‹ ์ค‘ํ•˜๊ฒŒ ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  React ์ปค๋ฐ‹์€ 10์–ต๋ช… + ์ด์ƒ์˜ ์‚ฌ์šฉ์ž๊ฐ€ ์žˆ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค์˜ ํฌ๋ฆฌํ‹ฐ์ปฌํ•œ ์˜์—ญ์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ + ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. Meta์—์„œ๋Š” 10๋งŒ ๊ฐœ ์ด์ƒ์˜ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ชจ๋“  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ „๋žต์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. </Para> <div className="order-last pt-5"> @@ -495,9 +498,9 @@ export function HomeContent() { <Center> <Header>์ˆ˜๋ฐฑ๋งŒ ๋ช…์ด ์žˆ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ</Header> <Para> - ์—ฌ๋Ÿฌ๋ถ„์€ ํ˜ผ์ž๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. 200๋งŒ ๋ช…์ด ๋„˜๋Š” ๊ฐœ๋ฐœ์ž๋“ค์ด React - ๋ฌธ์„œ๋ฅผ ๋งค๋‹ฌ ๋ฐฉ๋ฌธํ•ฉ๋‹ˆ๋‹ค. React๋Š” ์‚ฌ๋žŒ๋“ค๊ณผ ํŒ€์ด ๋™์˜ํ•  ์ˆ˜ ์žˆ๋Š” - ๊ฒƒ์ž…๋‹ˆ๋‹ค. + ์—ฌ๋Ÿฌ๋ถ„์€ ํ˜ผ์ž๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ „์„ธ๊ณ„์˜ 200๋งŒ ๋ช…์ด ๋„˜๋Š” ๊ฐœ๋ฐœ์ž๋“ค์ด + React ๋ฌธ์„œ๋ฅผ ๋งค๋‹ฌ ๋ฐฉ๋ฌธํ•ฉ๋‹ˆ๋‹ค. React๋Š” ์‚ฌ๋žŒ๋“ค๊ณผ ํŒ€์ด ๋™์˜ํ•  ์ˆ˜ + ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. </Para> </Center> </div> @@ -505,12 +508,12 @@ export function HomeContent() { <div className="mx-auto flex flex-col max-w-4xl"> <Center> <Para> - ์ด๊ฒƒ์ด ๋ฐ”๋กœ React๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋„˜์–ด ์•„ํ‚คํ…์ฒ˜, ์‹ฌ์ง€์–ด - ์—์ฝ”์‹œ์Šคํ…œ ๊ทธ ์ด์ƒ์ธ ์ด์œ ์ž…๋‹ˆ๋‹ค. React๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ์ž…๋‹ˆ๋‹ค. - ๋„์›€์„ ์š”์ฒญํ•˜๊ณ , ๊ธฐํšŒ๋ฅผ ์ฐพ๊ณ , ์ƒˆ๋กœ์šด ์นœ๊ตฌ๋ฅผ ๋งŒ๋‚  ์ˆ˜ ์žˆ๋Š” - ๊ณณ์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž์™€ ๋””์ž์ด๋„ˆ, ์ดˆ๋ณด์ž์™€ ์ „๋ฌธ๊ฐ€, ์—ฐ๊ตฌ์›๊ณผ ์˜ˆ์ˆ ๊ฐ€, - ๊ต์‚ฌ์™€ ํ•™์ƒ์„ ๋งŒ๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘์˜ ๋ฐฐ๊ฒฝ์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์ง€๋งŒ, - React๋ฅผ ํ†ตํ•ด ํ•จ๊ป˜ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + ์ด๊ฒƒ์ด ๋ฐ”๋กœ React๊ฐ€ ๋‹จ์ˆœํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ์•„ํ‚คํ…์ฒ˜, ํ˜น์€ ์ƒํƒœ๊ณ„ + ๊ทธ ์ด์ƒ์ธ ์ด์œ ์ž…๋‹ˆ๋‹ค. React๋Š” ๋ฐ”๋กœ ์ปค๋ฎค๋‹ˆํ‹ฐ์ž…๋‹ˆ๋‹ค. ๋„์›€์„ + ์š”์ฒญํ•˜๊ณ , ๊ธฐํšŒ๋ฅผ ์ฐพ๊ณ , ์ƒˆ๋กœ์šด ์นœ๊ตฌ๋ฅผ ๋งŒ๋‚  ์ˆ˜ ์žˆ๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค. + ๊ฐœ๋ฐœ์ž์™€ ๋””์ž์ด๋„ˆ, ์ดˆ๋ณด์ž์™€ ์ „๋ฌธ๊ฐ€, ์—ฐ๊ตฌ์›๊ณผ ์˜ˆ์ˆ ๊ฐ€, ๊ต์‚ฌ์™€ + ํ•™์ƒ์„ ๋งŒ๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฐ๊ฒฝ์€ ๋ชจ๋‘ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์ง€๋งŒ, React๋ฅผ + ํ†ตํ•ด ํ•จ๊ป˜ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Para> </Center> </div> @@ -528,7 +531,7 @@ export function HomeContent() { <Logo className="uwu-hidden text-brand dark:text-brand-dark w-24 lg:w-28 mb-10 lg:mb-8 mt-12 h-auto mx-auto self-start" /> <Header> React ์ปค๋ฎค๋‹ˆํ‹ฐ์— - <Br /> ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. + <Br /> ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค </Header> <ButtonLink href={'/learn'} diff --git a/src/components/Layout/TopNav/TopNav.tsx b/src/components/Layout/TopNav/TopNav.tsx index dab8dcb37..3d6e4b689 100644 --- a/src/components/Layout/TopNav/TopNav.tsx +++ b/src/components/Layout/TopNav/TopNav.tsx @@ -326,7 +326,7 @@ export default function TopNav({ <NavItem isActive={section === 'reference'} url="/reference/react"> - ๋ ˆํผ๋Ÿฐ์Šค + API ์ฐธ๊ณ ์„œ </NavItem> <NavItem isActive={section === 'community'} url="/community"> ์ปค๋ฎค๋‹ˆํ‹ฐ diff --git a/src/content/blog/2023/03/16/introducing-react-dev.md b/src/content/blog/2023/03/16/introducing-react-dev.md index 15364878c..8b13cb55e 100644 --- a/src/content/blog/2023/03/16/introducing-react-dev.md +++ b/src/content/blog/2023/03/16/introducing-react-dev.md @@ -43,7 +43,7 @@ description: ์˜ค๋Š˜ React์™€ React ๋ฌธ์„œ์˜ ์ƒˆ๋กœ์šด ๋ณด๊ธˆ์ž๋ฆฌ์ธ react.dev **์ƒˆ๋กœ์šด ๋ฌธ์„œ๋Š” Hooks๋ฅผ ์‚ฌ์šฉํ•œ React๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค.** ๋ฌธ์„œ๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ์„น์…˜์œผ๋กœ ๋‚˜๋‰˜์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. * **[React ๋ฐฐ์šฐ๊ธฐ](/learn)** ๋Š” React๋ฅผ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ์Šค์Šค๋กœ ํ•™์Šตํ•  ์ˆ˜ ์žˆ๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. -* **[API ๋ ˆํผ๋Ÿฐ์Šค](/reference)** ๋Š” ๋ชจ๋“  React API์— ๋Œ€ํ•œ ์„ธ๋ถ€ ๋‚ด์šฉ๊ณผ ์‚ฌ์šฉ ์˜ˆ์‹œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +* **[API ์ฐธ๊ณ ์„œ](/reference)** ๋Š” ๋ชจ๋“  React API์— ๋Œ€ํ•œ ์„ธ๋ถ€ ๋‚ด์šฉ๊ณผ ์‚ฌ์šฉ ์˜ˆ์‹œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์„น์…˜์—์„œ ๋ฌด์Šจ ๋‚ด์šฉ์„ ์•Œ ์ˆ˜ ์žˆ๋Š”์ง€ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. @@ -456,9 +456,9 @@ export default function PackingList() { ๋ธŒ๋ผ์šฐ์ € ๊ณต๊ธ‰์—…์ฒด์—๊ฒŒ ์ด ํ‘œํ˜„์ด 100% ๊ณผํ•™์ ์œผ๋กœ ์ •ํ™•ํ•˜๋‹ค๋Š” ํ™•์ธ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. -## ์ƒˆ๋กœ์šด, ์ƒ์„ธํ•œ API ๋ ˆํผ๋Ÿฐ์Šค {/*a-new-detailed-api-reference*/} +## ์ƒˆ๋กœ์šด, ์ƒ์„ธํ•œ API ์ฐธ๊ณ ์„œ {/*a-new-detailed-api-reference*/} -[API ๋ ˆํผ๋Ÿฐ์Šค](/reference/react)์—์„œ, ์ด์ œ ๋ชจ๋“  React API๋Š” ์ „์šฉ ํŽ˜์ด์ง€๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๋ชจ๋“  ์ข…๋ฅ˜์˜ API๋“ค์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. +[API ์ฐธ๊ณ ์„œ](/reference/react)์—์„œ, ์ด์ œ ๋ชจ๋“  React API๋Š” ์ „์šฉ ํŽ˜์ด์ง€๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๋ชจ๋“  ์ข…๋ฅ˜์˜ API๋“ค์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. - [`useState`](/reference/react/useState) ๊ฐ™์€ ๋‚ด์žฅ Hooks - [`<Suspense>`](/reference/react/Suspense) ๊ฐ™์€ ๋‚ด์žฅ ์ปดํฌ๋„ŒํŠธ @@ -610,7 +610,7 @@ button { display: block; margin-top: 10px; } ๋˜ํ•œ ๋ช‡๋ช‡ API ํŽ˜์ด์ง€๋Š” (์ผ๋ฐ˜์ ์ธ ๋ฌธ์ œ์— ๋Œ€ํ•œ) [ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…](/reference/react/useEffect#troubleshooting)๊ณผ (๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” API์™€ ๊ด€๋ จ๋œ) [๋Œ€์•ˆ](/reference/react-dom/findDOMNode#alternatives)์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -์ด๋Ÿฌํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด API ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋‹จ์ˆœํžˆ ์ธ์ž๋ฅผ ์ฐพ๋Š” ์šฉ๋„๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๊ฐ API๊ฐ€ ์–ด๋–ค ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€, ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅธ API์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๊ฒŒ ๋  ๊ฒƒ์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. +์ด๋Ÿฌํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด API ์ฐธ๊ณ ์„œ๋ฅผ ๋‹จ์ˆœํžˆ ์ธ์ž๋ฅผ ์ฐพ๋Š” ์šฉ๋„๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๊ฐ API๊ฐ€ ์–ด๋–ค ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€, ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅธ API์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๊ฒŒ ๋  ๊ฒƒ์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ## ๋‹ค์Œ์€ ๋ฌด์—‡์ธ๊ฐ€์š”? {/*whats-next*/} diff --git a/src/content/learn/index.md b/src/content/learn/index.md index a28e615ad..dfe86ba5e 100644 --- a/src/content/learn/index.md +++ b/src/content/learn/index.md @@ -382,7 +382,7 @@ button { ## Hook ์‚ฌ์šฉํ•˜๊ธฐ {/*using-hooks*/} -`use`๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ *Hook*์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. `useState`๋Š” React์—์„œ ์ œ๊ณตํ•˜๋Š” ๋‚ด์žฅ Hook์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋‚ด์žฅ Hook์€ [API ๋ ˆํผ๋Ÿฐ์Šค](/reference/react)์—์„œ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ธฐ์กด์˜ ๊ฒƒ๋“ค์„ ์กฐํ•ฉํ•˜์—ฌ ์ž์‹ ๋งŒ์˜ Hook์„ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +`use`๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ *Hook*์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. `useState`๋Š” React์—์„œ ์ œ๊ณตํ•˜๋Š” ๋‚ด์žฅ Hook์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋‚ด์žฅ Hook์€ [API ์ฐธ๊ณ ์„œ](/reference/react)์—์„œ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ธฐ์กด์˜ ๊ฒƒ๋“ค์„ ์กฐํ•ฉํ•˜์—ฌ ์ž์‹ ๋งŒ์˜ Hook์„ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Hook์€ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ณด๋‹ค ๋” ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ(๋˜๋Š” ๋‹ค๋ฅธ Hook)์˜ *์ƒ๋‹จ*์—์„œ๋งŒ Hook์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์กฐ๊ฑด์ด๋‚˜ ๋ฐ˜๋ณต์—์„œ `useState`๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ƒˆ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”์ถœํ•˜์—ฌ ๊ทธ๊ณณ์— ๋„ฃ์œผ์„ธ์š”. diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index 7eec48733..516255153 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -1361,7 +1361,7 @@ const nextSquares = ['X', null, null, null, null, null, null, null, null]; ๋ถˆ๋ณ€์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์„ ํ›จ์”ฌ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด ์ž์Šต์„œ์˜ ๋’ท๋ถ€๋ถ„์—์„œ ๊ฒŒ์ž„์˜ ์ง„ํ–‰ ๊ณผ์ •์„ ๊ฒ€ํ† ํ•˜๊ณ  ๊ณผ๊ฑฐ ์›€์ง์ž„์œผ๋กœ "๋Œ์•„๊ฐ€๊ธฐ"๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” "์‹œ๊ฐ„ ์—ฌํ–‰" ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ํŠน์ • ์ž‘์—…์„ ์‹คํ–‰ ์ทจ์†Œํ•˜๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ์ด ๊ฒŒ์ž„์—๋งŒ ๊ตญํ•œ๋œ ๊ฒƒ์ด ์•„๋‹Œ ์•ฑ์˜ ์ผ๋ฐ˜์ ์ธ ์š”๊ตฌ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ์ง์ ‘์ ์ธ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ํ”ผํ•˜๋ฉด ์ด์ „ ๋ฒ„์ „์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜์—ฌ ๋‚˜์ค‘์— ์žฌ์‚ฌ์šฉ(๋˜๋Š” ์ดˆ๊ธฐํ™”)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋ถˆ๋ณ€์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์˜ ๋˜ ๋‹ค๋ฅธ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ state๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ๋ชจ๋“  ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์—†๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋„ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๋ฆฌ๋ Œ๋”๋ง ์ž์ฒด๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ์„ฑ๋Šฅ์ƒ์˜ ์ด์œ ๋กœ ํŠธ๋ฆฌ์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š” ๋ถ€๋ถ„์˜ ๋ฆฌ๋ Œ๋”๋ง์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ถˆ๋ณ€์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ ์—ฌ๋ถ€๋ฅผ ์ €๋ ดํ•œ ๋น„์šฉ์œผ๋กœ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [`memo` API ๋ ˆํผ๋Ÿฐ์Šค](/reference/react/memo)์—์„œ React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ์‹œ์ ์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ถˆ๋ณ€์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์˜ ๋˜ ๋‹ค๋ฅธ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ state๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ๋ชจ๋“  ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์—†๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋„ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ๋ฆฌ๋ Œ๋”๋ง ์ž์ฒด๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ์„ฑ๋Šฅ์ƒ์˜ ์ด์œ ๋กœ ํŠธ๋ฆฌ์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š” ๋ถ€๋ถ„์˜ ๋ฆฌ๋ Œ๋”๋ง์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ถˆ๋ณ€์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ ์—ฌ๋ถ€๋ฅผ ์ €๋ ดํ•œ ๋น„์šฉ์œผ๋กœ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [`memo` API ์ฐธ๊ณ ์„œ](/reference/react/memo)์—์„œ React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ์‹œ์ ์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ### ์ˆœ์„œ ์ •ํ•˜๊ธฐ {/*taking-turns*/} diff --git a/src/sidebarHome.json b/src/sidebarHome.json index 5fb212184..3b018bcc1 100644 --- a/src/sidebarHome.json +++ b/src/sidebarHome.json @@ -11,7 +11,7 @@ "path": "/learn" }, { - "title": "์„ค์น˜", + "title": "์„ค์น˜ํ•˜๊ธฐ", "path": "/learn/installation" }, { diff --git a/src/sidebarLearn.json b/src/sidebarLearn.json index f318d9ab2..c4dcbca8f 100644 --- a/src/sidebarLearn.json +++ b/src/sidebarLearn.json @@ -21,7 +21,7 @@ ] }, { - "title": "์„ค์น˜", + "title": "์„ค์น˜ํ•˜๊ธฐ", "path": "/learn/installation", "routes": [ { diff --git a/src/sidebarReference.json b/src/sidebarReference.json index 1b3dd82db..6b0542762 100644 --- a/src/sidebarReference.json +++ b/src/sidebarReference.json @@ -1,5 +1,5 @@ { - "title": "API ๋ ˆํผ๋Ÿฐ์Šค", + "title": "API ์ฐธ๊ณ ์„œ", "path": "/reference/react", "routes": [ { From 3c58b51897a02ea1005c11d273735c0f2ab4b325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 21:47:01 +0900 Subject: [PATCH 0335/1059] refactor: translate text `Learn`, `Reference` and more in `TopNav.tsx` --- src/components/Layout/TopNav/TopNav.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Layout/TopNav/TopNav.tsx b/src/components/Layout/TopNav/TopNav.tsx index 3d6e4b689..296155b93 100644 --- a/src/components/Layout/TopNav/TopNav.tsx +++ b/src/components/Layout/TopNav/TopNav.tsx @@ -408,20 +408,20 @@ export default function TopNav({ <Suspense fallback={null}> <div className="ps-3 xs:ps-5 xs:gap-0.5 xs:text-base overflow-x-auto flex flex-row lg:hidden text-base font-bold text-secondary dark:text-secondary-dark"> <NavItem isActive={section === 'learn'} url="/learn"> - Learn + ํ•™์Šตํ•˜๊ธฐ </NavItem> <NavItem isActive={section === 'reference'} url="/reference/react"> - Reference + API ์ฐธ๊ณ ์„œ </NavItem> <NavItem isActive={section === 'community'} url="/community"> - Community + ์ปค๋ฎค๋‹ˆํ‹ฐ </NavItem> <NavItem isActive={section === 'blog'} url="/blog"> - Blog + ๋ธ”๋กœ๊ทธ </NavItem> </div> <div From 815606db58dfe45562a50aec164a6885c2f1c771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 21:52:00 +0900 Subject: [PATCH 0336/1059] refactor: update `sidebarLearn.json` --- src/sidebarLearn.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sidebarLearn.json b/src/sidebarLearn.json index c4dcbca8f..43729ef11 100644 --- a/src/sidebarLearn.json +++ b/src/sidebarLearn.json @@ -65,7 +65,7 @@ "path": "/learn/your-first-component" }, { - "title": "์ปดํฌ๋„ŒํŠธ import ๋ฐ exportํ•˜๊ธฐ", + "title": "์ปดํฌ๋„ŒํŠธ Import ๋ฐ Exportํ•˜๊ธฐ", "path": "/learn/importing-and-exporting-components" }, { @@ -77,7 +77,7 @@ "path": "/learn/javascript-in-jsx-with-curly-braces" }, { - "title": "์ปดํฌ๋„ŒํŠธ์— props ์ „๋‹ฌํ•˜๊ธฐ", + "title": "์ปดํฌ๋„ŒํŠธ์— Props ์ „๋‹ฌํ•˜๊ธฐ", "path": "/learn/passing-props-to-a-component" }, { @@ -116,7 +116,7 @@ "path": "/learn/render-and-commit" }, { - "title": "์Šค๋ƒ…์ƒท์œผ๋กœ์„œ์˜ state", + "title": "์Šค๋ƒ…์ƒท์œผ๋กœ์„œ์˜ State", "path": "/learn/state-as-a-snapshot" }, { @@ -124,11 +124,11 @@ "path": "/learn/queueing-a-series-of-state-updates" }, { - "title": "๊ฐ์ฒด state ์—…๋ฐ์ดํŠธํ•˜๊ธฐ", + "title": "๊ฐ์ฒด State ์—…๋ฐ์ดํŠธํ•˜๊ธฐ", "path": "/learn/updating-objects-in-state" }, { - "title": "๋ฐฐ์—ด state ์—…๋ฐ์ดํŠธํ•˜๊ธฐ", + "title": "๋ฐฐ์—ด State ์—…๋ฐ์ดํŠธํ•˜๊ธฐ", "path": "/learn/updating-arrays-in-state" } ] From d3ff085e687a26b61bb495a30821219c4d27d360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 22:49:55 +0900 Subject: [PATCH 0337/1059] =?UTF-8?q?refactor:=20translate=20`Previous`=20?= =?UTF-8?q?and=20`Next`=20to=20`=EC=9D=B4=EC=A0=84`=20and=20`=EB=8B=A4?= =?UTF-8?q?=EC=9D=8C`=20in=20`DocsFooter.tsx`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๋ฌธ์„œ ํ•˜๋‹จ๋ถ€ Footer์—์„œ Previous ๋ฐ Next๋กœ ํ‘œํ˜„๋˜๋˜ ํ…์ŠคํŠธ ํ•œ๊ตญ์–ด๋กœ ์ˆ˜์ •. --- 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 5f2330e7e..68e9cf7ec 100644 --- a/src/components/DocsFooter.tsx +++ b/src/components/DocsFooter.tsx @@ -30,7 +30,7 @@ export const DocsPageFooter = memo<DocsPageFooterProps>( <div className="grid grid-cols-1 gap-4 py-4 mx-auto max-w-7xl md:grid-cols-2 md:py-12"> {prevRoute?.path ? ( <FooterLink - type="Previous" + type="์ด์ „" title={prevRoute.title} href={prevRoute.path} /> @@ -40,7 +40,7 @@ export const DocsPageFooter = memo<DocsPageFooterProps>( {nextRoute?.path ? ( <FooterLink - type="Next" + type="๋‹ค์Œ" title={nextRoute.title} href={nextRoute.path} /> @@ -63,7 +63,7 @@ function FooterLink({ }: { href: string; title: string; - type: 'Previous' | 'Next'; + type: '์ด์ „' | '๋‹ค์Œ'; }) { return ( <NextLink @@ -71,12 +71,12 @@ function FooterLink({ className={cn( 'flex gap-x-4 md:gap-x-6 items-center w-full md:min-w-80 md:w-fit md:max-w-md px-4 md:px-5 py-6 border-2 border-transparent text-base leading-base text-link dark:text-link-dark rounded-lg group focus:text-link dark:focus:text-link-dark focus:bg-highlight focus:border-link dark:focus:bg-highlight-dark dark:focus:border-link-dark focus:border-opacity-100 focus:border-2 focus:ring-1 focus:ring-offset-4 focus:ring-blue-40 active:ring-0 active:ring-offset-0 hover:bg-gray-5 dark:hover:bg-gray-80', { - 'flex-row-reverse justify-self-end text-end': type === 'Next', + 'flex-row-reverse justify-self-end text-end': type === '๋‹ค์Œ', } )}> <IconNavArrow className="inline text-tertiary dark:text-tertiary-dark group-focus:text-link dark:group-focus:text-link-dark" - displayDirection={type === 'Previous' ? 'start' : 'end'} + displayDirection={type === '์ด์ „' ? 'start' : 'end'} /> <div className="flex flex-col overflow-hidden"> <span className="text-sm font-bold tracking-wide no-underline uppercase text-secondary dark:text-secondary-dark group-focus:text-link dark:group-focus:text-link-dark group-focus:text-opacity-100"> From f92b23cb6bd90efb55c17696b3e13b3f7bad6b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 22:53:38 +0900 Subject: [PATCH 0338/1059] docs: update `installation.md` --- src/content/learn/installation.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/content/learn/installation.md b/src/content/learn/installation.md index 27a39d122..edec4eb31 100644 --- a/src/content/learn/installation.md +++ b/src/content/learn/installation.md @@ -4,7 +4,7 @@ title: ์„ค์น˜ํ•˜๊ธฐ <Intro> -React๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ ํ•„์š”ํ•œ ๋งŒํผ React๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React๋ฅผ ๋ง›๋ณด๊ธฐ๋กœ ์ ‘ํ•ด๋ณด๋ ค๊ฑฐ๋‚˜ ๊ฐ„๋‹จํ•œ HTML ํŽ˜์ด์ง€์— ์•ฝ๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณต์žกํ•œ React ๊ธฐ๋ฐ˜์˜ ์•ฑ์„ ์‹œ์ž‘ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ, ์ด ์„น์…˜์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. +React๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ ํ•„์š”ํ•œ ๋งŒํผ React๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React๋ฅผ ๋ง›๋ณด๊ธฐ๋กœ ์ ‘ํ•ด๋ณด๋ ค๊ฑฐ๋‚˜, ๊ฐ„๋‹จํ•œ HTML ํŽ˜์ด์ง€์— ์•ฝ๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ๋ณต์žกํ•œ React ๊ธฐ๋ฐ˜์˜ ์•ฑ์„ ์‹œ์ž‘ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ, ์ด ์„น์…˜์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. </Intro> @@ -37,7 +37,7 @@ export default function App() { ์ง์ ‘ ํŽธ์ง‘ํ•˜๊ฑฐ๋‚˜ ์˜ค๋ฅธ์ชฝ ์ƒ๋‹จ์˜ "Fork" ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ƒˆ ํƒญ์—์„œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -React ๋ฌธ์„œ์˜ ๋Œ€๋ถ€๋ถ„ ํŽ˜์ด์ง€์—๋Š” ์ด์™€ ๊ฐ™์€ ์ƒŒ๋“œ๋ฐ•์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. React ๋ฌธ์„œ ์™ธ์—๋„ [CodeSandbox](https://codesandbox.io/s/new), [StackBlitz](https://stackblitz.com/fork/react), [CodePen.](https://codepen.io/pen?template=QWYVwWN) ๋“ฑ์˜ ์˜จ๋ผ์ธ ์ƒŒ๋“œ๋ฐ•์Šค์—์„œ React๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. +React ๋ฌธ์„œ์˜ ๋Œ€๋ถ€๋ถ„ ํŽ˜์ด์ง€์—๋Š” ์ด์™€ ๊ฐ™์€ ์ƒŒ๋“œ๋ฐ•์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. React ๋ฌธ์„œ ์™ธ์—๋„ [CodeSandbox](https://codesandbox.io/s/new), [StackBlitz](https://stackblitz.com/fork/react), [CodePen](https://codepen.io/pen?template=QWYVwWN) ๋“ฑ์˜ ์˜จ๋ผ์ธ ์ƒŒ๋“œ๋ฐ•์Šค์—์„œ React๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ### ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ React ์‹œ๋„ํ•˜๊ธฐ {/*try-react-locally*/} @@ -49,9 +49,8 @@ React๋กœ ์™„์ „ํžˆ ์•ฑ์ด๋‚˜ ์›น์‚ฌ์ดํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, [์ƒˆ๋กœ์šด ## ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— React ์ถ”๊ฐ€ํ•˜๊ธฐ {/*add-react-to-an-existing-project*/} -๊ธฐ์กด ์•ฑ์ด๋‚˜ ์›น์‚ฌ์ดํŠธ์—์„œ React๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, [๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— React๋ฅผ ์ถ”๊ฐ€](/learn/add-react-to-an-existing-project)ํ•˜์„ธ์š”. +๊ธฐ์กด ์•ฑ์ด๋‚˜ ์›น์‚ฌ์ดํŠธ์— React๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, [๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— React๋ฅผ ์ถ”๊ฐ€](/learn/add-react-to-an-existing-project)ํ•˜์„ธ์š”. ## ๋‹ค์Œ ๋‹จ๊ณ„ {/*next-steps*/} -React ๊ฐœ๋… ์ค‘ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฐœ๋…๋“ค์„ ์‚ดํŽด๋ณด๊ธฐ ์œ„ํ•ด [๋น ๋ฅธ ์‹œ์ž‘ ๊ฐ€์ด๋“œ](/learn)๋กœ ์ด๋™ํ•˜์„ธ์š”. - +React์˜ ๊ฐœ๋… ์ค‘ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฐœ๋…๋“ค์„ ์‚ดํŽด๋ณด๊ธฐ ์œ„ํ•ด [๋น ๋ฅด๊ฒŒ ์‹œ์ž‘ํ•˜๊ธฐ](/learn)๋กœ ์ด๋™ํ•˜์„ธ์š”. From 822ab3093782ff092c6fc3e1b98e27b20aa0740a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 23:00:18 +0900 Subject: [PATCH 0339/1059] =?UTF-8?q?refactor:=20translate=20`deep=20dive`?= =?UTF-8?q?=20to=20`=EC=9E=90=EC=84=B8=ED=9E=88=20=EC=82=B4=ED=8E=B4?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/MDX/ExpandableExample.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MDX/ExpandableExample.tsx b/src/components/MDX/ExpandableExample.tsx index 29116c1b1..d643f98e7 100644 --- a/src/components/MDX/ExpandableExample.tsx +++ b/src/components/MDX/ExpandableExample.tsx @@ -71,7 +71,7 @@ function ExpandableExample({children, excerpt, type}: ExpandableExampleProps) { {isDeepDive && ( <> <IconDeepDive className="inline me-2 dark:text-purple-30 text-purple-40" /> - Deep Dive + ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ธฐ </> )} {isExample && ( From ff9f6987075f8573038b6e489467f891586fc532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Sun, 29 Dec 2024 23:43:04 +0900 Subject: [PATCH 0340/1059] docs: update `start-a-new-react-project.md` --- .../learn/start-a-new-react-project.md | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/content/learn/start-a-new-react-project.md b/src/content/learn/start-a-new-react-project.md index e6b4dca74..48956ab35 100644 --- a/src/content/learn/start-a-new-react-project.md +++ b/src/content/learn/start-a-new-react-project.md @@ -4,38 +4,39 @@ title: ์ƒˆ๋กœ์šด React ํ”„๋กœ์ ํŠธ ์‹œ์ž‘ํ•˜๊ธฐ <Intro> -React๋ฅผ ์ „์ฒด์ ์œผ๋กœ ์ ์šฉํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ์‚ฌ์ดํŠธ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ React ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. +React๋กœ ์ƒˆ๋กœ์šด ์•ฑ์ด๋‚˜ ์ƒˆ๋กœ์šด ์›น์‚ฌ์ดํŠธ๋ฅผ ์™„์ „ํžˆ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ React ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. </Intro> +ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด React๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋Œ€๋ถ€๋ถ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ์‚ฌ์ดํŠธ๋“ค์ด ๊ฒฐ๊ตญ์—๋Š” ์ฝ”๋“œ ๋ถ„ํ• <sup>Code-Splitting</sup>, ๋ผ์šฐํŒ…<sup>Routing</sup>, ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ<sup>Data Fetching</sup>, ๊ทธ๋ฆฌ๊ณ  HTML ์ƒ์„ฑ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์€ UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์˜ ๊ณตํ†ต์ ์ธ ๋ฌธ์ œ์ด๋ฉฐ React๋งŒ์˜ ๋ฌธ์ œ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. -ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด React๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋Œ€๋ถ€๋ถ„์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ์‚ฌ์ดํŠธ๋“ค์ด ๊ฒฐ๊ตญ์—๋Š” ์ฝ”๋“œ ๋ถ„ํ• , routing, ๋ฐ์ดํ„ฐ fetching, ๊ทธ๋ฆฌ๊ณ  HTML ์ƒ์„ฑ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ๊ณ  ์žˆ๋‹ค๋Š”๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์€ UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์˜ ๊ธฐ๋ณธ์ ์ธ ๋ฌธ์ œ์ด๋ฉฐ React ๋งŒ์˜ ๋ฌธ์ œ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. - -ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ์‹œ์ž‘ํ•˜๋ฉด React๋ฅผ ๋น ๋ฅด๊ฒŒ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๊ณ , ๋‚˜์ค‘์— ์ž์ฒด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ์‹œ์ž‘ํ•˜๋ฉด React๋ฅผ ๋น ๋ฅด๊ฒŒ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๊ณ , ๋‚˜์ค‘์— ์ž์ฒด์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <DeepDive> #### ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด React ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‚˜์š”? {/*can-i-use-react-without-a-framework*/} -๋ฌผ๋ก  React๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [๊ธฐ์กด ํŽ˜์ด์ง€์˜ ์ผ๋ถ€๋ถ„์— React ์‚ฌ์šฉํ•˜๊ธฐ](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page)๋ฅผ ํ™œ์šฉํ•ด ๋ณด์„ธ์š”. **ํ•˜์ง€๋งŒ, ์ƒˆ๋กœ์šด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ์‚ฌ์ดํŠธ ์ „์ฒด๋ฅผ React๋กœ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.** +๋ฌผ๋ก  React๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [๊ธฐ์กด ํŽ˜์ด์ง€์˜ ์ผ๋ถ€๋ถ„์— React ์‚ฌ์šฉํ•˜๊ธฐ](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page)๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”. **ํ•˜์ง€๋งŒ, ์ƒˆ๋กœ์šด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ์‚ฌ์ดํŠธ ์ „์ฒด๋ฅผ React๋กœ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.** -์ด์œ ๊ฐ€ ์—ฌ๊ธฐ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด์œ ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. -๋ผ์šฐํŒ…์ด๋‚˜ ๋ฐ์ดํ„ฐ ํŽ˜์นญ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด ์ฒ˜์Œ์—” ํ•„์š”ํ•˜์ง€ ์•Š๋”๋ผ๋„, ์ด๋ฅผ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์€ ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. JavaScript ๋ฒˆ๋“ค์€ ๋‚ ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์ด ๋”ํ•ด์ง€๊ณ , ๋ชจ๋“  ๊ฐ๊ฐ์˜ ๋ผ์šฐํŒ… ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ถ„ํ• ํ•ด์•ผ ํ• ์ง€ ๊ณ ๋ฏผํ•ด์•ผ ํ•˜๋Š” ์ˆœ๊ฐ„์ด ์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ํŽ˜์นญ์€ ๋‚ ๋กœ ๋ณต์žกํ•ด์ง€๊ณ , ์•„๋งˆ ์„œ๋ฒ„-ํด๋ผ์ด์–ธํŠธ ๋„คํŠธ์›Œํฌ์˜ ์›Œํ„ฐํด์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์†๋„๋ฅผ ๋А๋ฆฌ๊ฒŒ ๋งŒ๋“œ๋Š” ์ˆœ๊ฐ„๋„ ์ง๋ฉดํ•˜๊ฒŒ ๋  ๊ฒ๋‹ˆ๋‹ค. ์„ฑ๋Šฅ์ด ์ข‹์ง€ ์•Š์€ ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ์ด๋‚˜ ์ €์‚ฌ์–‘์˜ ๋‹จ๋ง๊ธฐ๋ฅผ ์ด์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๋“ค์ด ๋Š˜์–ด๋‚จ์— ๋”ฐ๋ผ ์„œ๋ฒ„ ํ˜น์€ ๋นŒ๋“œ ์‹œ๊ฐ„์— ์ปดํฌ๋„ŒํŠธ์—์„œ HTML์„ ์ผ์ฐ ์ƒ์„ฑํ•˜์—ฌ ๋‚ด์šฉ์„ ๋จผ์ € ํ‘œ์‹œํ•  ํ•„์š”๊ฐ€ ์ƒ๊ธธ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ์ฝ”๋“œ์˜ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์„œ๋ฒ„์—์„œ ํ˜น์€ ๋นŒ๋“œ๋˜๋Š” ๋™์•ˆ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ฒƒ์€ ๋งค์šฐ ๊นŒ๋‹ค๋กœ์šด ์ž‘์—…์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ผ์šฐํŒ…<sup>Routing</sup>์ด๋‚˜ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ<sup>Data Fetching</sup>์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด ์ฒ˜์Œ์—” ํ•„์š”ํ•˜์ง€ ์•Š๋”๋ผ๋„, ์ด๋ฅผ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์€ ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ<sup>JavaScript</sup> ๋ฒˆ๋“ค์€ ๋‚ ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์ด ๋”ํ•ด์ง€๊ณ , ๊ฐ๊ฐ์˜ ๋ผ์šฐํŒ… ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ถ„ํ• ํ•ด์•ผ ํ• ์ง€ ๊ณ ๋ฏผํ•ด์•ผ ํ•˜๋Š” ์ˆœ๊ฐ„์ด ์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ<sup>Data Fetching</sup>๋Š” ๋‚ ๋กœ ๋ณต์žกํ•ด์ง€๊ณ , ์•„๋งˆ ์„œ๋ฒ„-ํด๋ผ์ด์–ธํŠธ ๋„คํŠธ์›Œํฌ์˜ ์›Œํ„ฐํด<sup>Waterfall</sup>์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์†๋„๋ฅผ ๋А๋ฆฌ๊ฒŒ ํ•˜๋Š” ์ˆœ๊ฐ„๋„ ์ง๋ฉดํ•˜๊ฒŒ ๋  ๊ฒ๋‹ˆ๋‹ค. ์„ฑ๋Šฅ์ด ์ข‹์ง€ ์•Š์€ ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ์ด๋‚˜ ์ €์‚ฌ์–‘์˜ ๋‹จ๋ง๊ธฐ๋ฅผ ์ด์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๋“ค์ด ๋Š˜์–ด๋‚จ์— ๋”ฐ๋ผ, ์„œ๋ฒ„์—์„œ ํ˜น์€ ๋นŒ๋“œ ์‹œ๊ฐ„์— ์ปดํฌ๋„ŒํŠธ์—์„œ HTML์„ ์ƒ์„ฑํ•˜์—ฌ ๋‚ด์šฉ<sup>Content</sup>์„ ๋น ๋ฅด๊ฒŒ ํ‘œ์‹œํ•ด์•ผํ•  ํ•„์š”๊ฐ€ ์ƒ๊ธธ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ์ฝ”๋“œ์˜ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์„œ๋ฒ„์—์„œ ํ˜น์€ ๋นŒ๋“œ๋˜๋Š” ๋™์•ˆ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ฒƒ์€ ๋งค์šฐ ๊นŒ๋‹ค๋กœ์šด ์ž‘์—…์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -**์ด ๋ฌธ์ œ๋Š” React์— ๊ตญํ•œ๋œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ Svelte์—๋Š” SvelteKit๊ฐ€ ์žˆ๊ณ , Vue์—๋Š” Nuxt๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.** ์ž์ฒด ์„œ๋น„์Šค์—์„œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ผ์šฐํ„ฐ์™€ ๋ฐ์ดํ„ฐ ํŽ˜์นญ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ฒˆ๋“ค๋Ÿฌ์™€ ํ†ตํ•ฉํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ์„ธํŒ…์„ ๊ตฌ๋™ํ•˜๋Š” ๊ฑด ๊ทธ๋‹ค์ง€ ์–ด๋ ต์ง€ ์•Š์ง€๋งŒ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ์„ฑ์žฅํ•จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ๋กœ๋“œ๋˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐ์—๋Š” ๋งŽ์€ ์„ธ๋ถ€ ์‚ฌํ•ญ๋“ค์ด ์—ฐ๊ด€๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ํ•œ ์ ์€ ์–‘์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๋ฅผ ์ „์†กํ•˜์ง€๋งŒ ํŽ˜์ด์ง€์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ๋‹จ์ผ ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„์˜ ์™•๋ณต์œผ๋กœ ์ด๋ฃจ์–ด์ง€๊ฒŒ ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. JavaScript ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ๋„ ์ „์— ํŽ˜์ด์ง€์— ์ƒํ˜ธ์ž‘์šฉ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ ์ง„์ ์ธ ๊ฐœ์„ ์„ ํ•˜๊ณ  ์‹ถ์–ด์งˆ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ผ€ํŒ… ๋ชฉ์ ์˜ ์™„์ „ํžˆ ์ •์ ์ธ HTML ํŒŒ์ผ๋“ค์ด ์†ํ•œ ํด๋”๋ฅผ ์ƒ์„ฑํ•˜์—ฌ JavaScript ๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋œ ํ™˜๊ฒฝ์—์„œ๋„ ์ด๋ฅผ ์ž‘๋™ํ•˜๊ฒŒ ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ๋“ค์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์‹ค์ œ๋กœ ๋งŽ์€ ์ž‘์—…์„ ์š”ํ•ฉ๋‹ˆ๋‹ค. +**์ด๋Ÿฌํ•œ ๋ฌธ์ œ๊ฐ€ React์—๋งŒ ๊ตญํ•œ๋œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ Svelte์— SvelteKit์ด ์กด์žฌํ•˜๊ณ , Vue์—๋Š” Nuxt๊ฐ€ ์žˆ๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค.** ์ž์ฒด ์„œ๋น„์Šค์—์„œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ผ์šฐํ„ฐ<sup>Router</sup>์™€ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ<sup>Data Fetching</sup> ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ฒˆ๋“ค๋Ÿฌ์™€ ํ†ตํ•ฉํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ์„ธํŒ…์„ ๊ตฌ๋™ํ•˜๋Š” ๊ฑด ๊ทธ๋‹ค์ง€ ์–ด๋ ต์ง€ ์•Š์ง€๋งŒ, ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด์„œ ์•ฑ์ด ์ปค์ ธ๋„ ๋น ๋ฅด๊ฒŒ ๋กœ๋“œ๋˜๋Š” ์•ฑ์„ ๋งŒ๋“œ๋Š” ๋ฐ์—๋Š” ๋งŽ์€ ์„ธ๋ถ€ ์‚ฌํ•ญ๋“ค์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์•ฑ ์ฝ”๋“œ์˜ ์ตœ์†Œํ•œ์˜ ์–‘๋งŒ ์ „์†กํ•˜๋˜, ํŽ˜์ด์ง€์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด์„œ ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ๊ฐ„์˜ ๋‹จ์ผ ์™•๋ณต<sup>Single Roundtrip</sup>์œผ๋กœ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ๋„ ์ „์— ํŽ˜์ด์ง€๊ฐ€ ์ƒํ˜ธ์ž‘์šฉ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ ์ง„์ ์ธ ๊ฐœ์„ ์„ ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ผ€ํŒ… ๋ชฉ์ ์˜ ์™„์ „ํžˆ ์ •์ ์ธ HTML ํŒŒ์ผ๋“ค์ด ์†ํ•œ ํด๋”๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋น„ํ™œ์„ฑํ™”๋œ ํ™˜๊ฒฝ์—์„œ๋„ ์ด๋ฅผ ์ž‘๋™ํ•˜๊ฒŒ ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ๋“ค์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์‹ค์ œ๋กœ ๋งŽ์€ ์ž‘์—…์„ ์š”ํ•ฉ๋‹ˆ๋‹ค. -**์ด ํŽ˜์ด์ง€์˜ React ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ์ถ”๊ฐ€ ์ž‘์—… ์—†์ด๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.** ์ด๋“ค์€ ๋งค์šฐ ๊ฐ„์†Œํ™”๋œ ์ƒํƒœ๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๊ณ  ์• ํ”Œ๋ ˆ์ผ€์ด์…˜์˜ ํ•„์š”์— ๋”ฐ๋ผ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ React ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์žˆ์–ด ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋‹ต์„ ์–ป๊ณ  ๋„๊ตฌ๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์€ ๋” ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. ๋˜ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ์ฝ”๋“œ์— ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ๋“ค๊ฐ„์˜ ๋งฅ๋ฝ๊ณผ ์Šคํ‚ฌ์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ์— ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋Œ€๋กœ, ๋งž์ถค ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋ฉด ์ง€์›๋˜์ง€ ์•Š๋Š” ์˜์กด์„ฑ ๋ฒ„์ „์— ๋น ์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฒฐ๊ตญ์—” ์ปค๋ฎค๋‹ˆํ‹ฐ๋‚˜ ์—…๊ทธ๋ ˆ์ด๋“œ ๊ฒฝ๋กœ๊ฐ€ ์—†๋Š” ์ž์ฒด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. (๊ทธ๋ฆฌ๊ณ  ๊ณผ๊ฑฐ์—์„œ์ฒ˜๋Ÿผ ์šฐ์—ฐํžˆ ๊ณ ์•ˆ๋œ ๊ฒƒ๋“ค์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.) +**ํ˜„์žฌ ํŽ˜์ด์ง€์˜ React ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ์ถ”๊ฐ€ ์ž‘์—… ์—†์ด๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.** ์ด๋“ค์€ ๋งค์šฐ ๊ฐ„์†Œํ™”๋œ ์ƒํƒœ๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ•„์š”์— ๋”ฐ๋ผ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ React ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์žˆ์–ด ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋‹ต์„ ์–ป๊ณ  ๋„๊ตฌ๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. ๋˜ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ์ฝ”๋“œ์— ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ๋“ค๊ฐ„์˜ ๋งฅ๋ฝ๊ณผ ์Šคํ‚ฌ์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ์— ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋Œ€๋กœ, ๋งž์ถค ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋ฉด ์ง€์›๋˜์ง€ ์•Š๋Š” ์˜์กด์„ฑ<sup>Dependency</sup> ๋ฒ„์ „์— ๋น ์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฒฐ๊ตญ์—” ์ปค๋ฎค๋‹ˆํ‹ฐ๋‚˜ ์—…๊ทธ๋ ˆ์ด๋“œ ๊ฒฝ๋กœ๊ฐ€ ์—†๋Š” ์ž์ฒด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. (๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ ์ด์ „์— ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ๊ฒƒ๋“ค๊ณผ ๋น„์Šทํ•˜๋‹ค๋ฉด, ๋” ์—‰์„ฑํ•˜๊ฒŒ ์„ค๊ณ„๋œ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.) -์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ด๋Ÿฌํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์˜ ์ง€์›์„ ์ž˜ ๋ฐ›์ง€ ๋ชปํ•˜๋Š” ํŠน์ˆ˜ํ•œ ์ œ์•ฝ์— ๋†“์—ฌ ์žˆ๊ฑฐ๋‚˜, ์Šค์Šค๋กœ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด React๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์ฒด ๋งž์ถค ์„ค์ •์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. npm์—์„œ `react` ์™€ `react-dom` ๋ฅผ ์ฑ„ํƒํ•˜๊ณ , [Vite](https://vitejs.dev/) ๋‚˜ [Parcel](https://parceljs.org/) ๊ฐ™์€ ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋งž์ถค ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ •๋ฆฝํ•œ ๋‹ค์Œ, ๋ผ์šฐํŒ…, ์ •์  ์ƒ์„ฑ ํ˜น์€ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ๋“ฑ ํ•„์š”์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋„๊ตฌ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ด๋Ÿฌํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์˜ ์ง€์›์„ ์ž˜ ๋ฐ›์ง€ ๋ชปํ•˜๋Š” ํŠน์ˆ˜ํ•œ ์ œ์•ฝ์— ๋†“์—ฌ ์žˆ๊ฑฐ๋‚˜, ์Šค์Šค๋กœ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด React๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์ฒด ๋งž์ถค ์„ค์ •์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. npm์—์„œ `react` ์™€ `react-dom`์„ ์„ค์น˜ํ•˜๊ณ , [Vite](https://vitejs.dev/) ๋‚˜ [Parcel](https://parceljs.org/) ๊ฐ™์€ ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋งž์ถค ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ •๋ฆฝํ•œ ๋‹ค์Œ, ๋ผ์šฐํŒ…<sup>Routing</sup>, ์ •์  ์ƒ์„ฑ<sup>Static Generation</sup> ํ˜น์€ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง<sup>SSR, Server Side Rendering</sup> ๋“ฑ ํ•„์š”์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋„๊ตฌ๋“ค์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </DeepDive> ## ํ”„๋กœ๋•์…˜ ์ˆ˜์ค€์˜ React ํ”„๋ ˆ์ž„์›Œํฌ {/*production-grade-react-frameworks*/} -์ด ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ํ”„๋กœ๋•์…˜์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•˜๊ณ  ํ™•์žฅํ•˜๋Š” ๋ฐ์— ํ•„์š”ํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋ฉฐ [ํ’€์Šคํƒ ์•„ํ‚คํ…์ฒ˜ ๋น„์ „](#which-features-make-up-the-react-teams-full-stack-architecture-vision) ์„ ์ง€์›ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ํ™œ๋ฐœํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ง€์›์„ ๋ฐ›๋Š” ์˜คํ”ˆ์†Œ์Šค์ด๋ฉฐ, ์ž์ฒด ์„œ๋ฒ„๋‚˜ ํ˜ธ์ŠคํŒ… ์ œ๊ณต์ž์— ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์ผ ์ด ๋ชฉ๋ก์— ํฌํ•จ๋˜๊ธธ ์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์ €์ž๊ฐ€ ์žˆ๋‹ค๋ฉด, [์—ฌ๊ธฐ์—์„œ ์•Œ๋ ค์ฃผ์„ธ์š”.](https://github.com/reactjs/react.dev/issues/new?assignees=&labels=type%3A+framework&projects=&template=3-framework.yml&title=%5BFramework%5D%3A+) +์•„๋ž˜ ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ํ”„๋กœ๋•์…˜์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•˜๊ณ  ํ™•์žฅํ•˜๋Š” ๋ฐ์— ํ•„์š”ํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋ฉฐ [ํ’€์Šคํƒ ์•„ํ‚คํ…์ฒ˜ ๋น„์ „](#which-features-make-up-the-react-teams-full-stack-architecture-vision)์„ ์ง€์›ํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ํ™œ๋ฐœํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ง€์›์„ ๋ฐ›๋Š” ์˜คํ”ˆ ์†Œ์Šค์ด๋ฉฐ, ์ž์ฒด ์„œ๋ฒ„๋‚˜ ํ˜ธ์ŠคํŒ… ์ œ๊ณต์ž์— ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์ผ ์ด ๋ชฉ๋ก์— ํฌํ•จ๋˜๊ธธ ์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์ €์ž๊ฐ€ ์žˆ๋‹ค๋ฉด, [์—ฌ๊ธฐ์—์„œ ์•Œ๋ ค์ฃผ์„ธ์š”.](https://github.com/reactjs/react.dev/issues/new?assignees=&labels=type%3A+framework&projects=&template=3-framework.yml&title=%5BFramework%5D%3A+) + +### Next.js {/*nextjs-pages-router*/} -**[Next.js' Pages Router](https://nextjs.org/)๋Š” ํ’€์Šคํƒ React ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.** ๋‹ค์žฌ๋‹ค๋Šฅํ•œ ๋„๊ตฌ์ด๋ฉฐ, ์ •์ ์ธ ๋ธ”๋กœ๊ทธ๋ถ€ํ„ฐ ๋ณต์žกํ•œ ๋™์  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊นŒ์ง€ ๋‹ค์–‘ํ•œ ํฌ๊ธฐ์˜ React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด Next.js ํ”„๋กœ์ ํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๋ฉด ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ•˜์„ธ์š”. +**[Next.js์˜ Pages Router](https://nextjs.org/)๋Š” ํ’€์Šคํƒ React ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.** ๋‹ค์žฌ๋‹ค๋Šฅํ•œ ๋„๊ตฌ์ด๋ฉฐ, ์ •์ ์ธ ๋ธ”๋กœ๊ทธ๋ถ€ํ„ฐ ๋ณต์žกํ•œ ๋™์  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊นŒ์ง€ ๋‹ค์–‘ํ•œ ํฌ๊ธฐ์˜ React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด Next.js ํ”„๋กœ์ ํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๋ฉด ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ์„ ์‹คํ–‰ํ•˜์„ธ์š”. <TerminalBlock> npx create-next-app@latest @@ -43,7 +44,7 @@ npx create-next-app@latest Next.js๋ฅผ ์ฒ˜์Œ ์‚ฌ์šฉํ•˜๋Š” ๋ถ„์ด๋ผ๋ฉด [Next.js ๋ฐฐ์šฐ๊ธฐ ์ฝ”์Šค](https://nextjs.org/learn)๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”. -Next.js๋Š” [Vercel](https://vercel.com/)์ด ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์–ด๋А Node.js ์„œ๋ฒ„, ์„œ๋ฒ„๋ฆฌ์Šค ํ˜ธ์ŠคํŒ… ๋˜๋Š” ์ง์ ‘ ์†Œ์œ ํ•œ ์„œ๋ฒ„ ์–ด๋А ๊ณณ์—๋ผ๋„ [Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌ](https://nextjs.org/docs/app/building-your-application/deploying)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Next.js ๋Š” ์„œ๋ฒ„๊ฐ€ ํ•„์š”์—†๋Š” [static export](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports) ๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +Next.js๋Š” [Vercel](https://vercel.com/)์ด ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค Node.js ์„œ๋ฒ„, ์„œ๋ฒ„๋ฆฌ์Šค ํ˜ธ์ŠคํŒ… ๋˜๋Š” ์ง์ ‘ ์†Œ์œ ํ•œ ์„œ๋ฒ„ ์–ด๋А ๊ณณ์—์„œ๋ผ๋„ [Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌ](https://nextjs.org/docs/app/building-your-application/deploying)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Next.js๋Š” ์„œ๋ฒ„๊ฐ€ ํ•„์š”์—†๋Š” [์ •์  ๋‚ด๋ณด๋‚ด๊ธฐ<sup>Static Exports</sup>](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports) ๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ### Remix {/*remix*/} @@ -55,7 +56,7 @@ npx create-remix Remix๋ฅผ ์ฒ˜์Œ ์‚ฌ์šฉํ•˜๋Š” ๋ถ„์ด๋ผ๋ฉด Remix [๋ธ”๋กœ๊ทธ ์ž์Šต์„œ](https://remix.run/docs/en/main/tutorials/blog) (์งง์€ ๋ฌธ์„œ)์™€ [์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž์Šต์„œ](https://remix.run/docs/en/main/tutorials/jokes) (๊ธด ๋ฌธ์„œ)๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”. -Remix๋Š” [Shopify](https://www.shopify.com/)๊ฐ€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Remix ํ”„๋กœ์ ํŠธ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ๋Š” [๋ฐฐํฌํ•  ๋Œ€์ƒ์„ ์„ ํƒ](https://remix.run/docs/en/main/guides/deployment)ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Remix ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์–ด๋А Node.js ์„œ๋ฒ„๋‚˜ ์„œ๋ฒ„๋ฆฌ์Šค ํ˜ธ์ŠคํŒ…์—๋ผ๋„ [์–ด๋Œ‘ํ„ฐ](https://remix.run/docs/en/main/other-api/adapter)๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ง์ ‘ ์ž‘์„ฑํ•˜์—ฌ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +Remix๋Š” [Shopify](https://www.shopify.com/)๊ฐ€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Remix ํ”„๋กœ์ ํŠธ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ๋Š” [๋ฐฐํฌํ•  ๋Œ€์ƒ์„ ์„ ํƒ](https://remix.run/docs/en/main/guides/deployment)ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Remix ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์–ด๋–ค Node.js ์„œ๋ฒ„๋‚˜ ์„œ๋ฒ„๋ฆฌ์Šค ํ˜ธ์ŠคํŒ…์—๋ผ๋„ [์–ด๋Œ‘ํ„ฐ<sup>Adapter</sup>](https://remix.run/docs/en/main/other-api/adapter)๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ง์ ‘ ์ž‘์„ฑํ•˜์—ฌ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ### Gatsby {/*gatsby*/} @@ -83,22 +84,22 @@ Expo๋Š” [Expo (๊ธฐ์—…)](https://expo.dev/about)์ด ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Expo๋ฅผ ์‚ฌ ## Bleeding-edge React frameworks {/*bleeding-edge-react-frameworks*/} -React๋ฅผ ์ง€์†์ ์œผ๋กœ ๊ฐœ์„ ํ•  ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๊ฐ€๋Š” ๊ณผ์ •์—์„œ, ์šฐ๋ฆฌ๋Š” React๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ(ํŠนํžˆ ๋ผ์šฐํŒ…, ๋ฒˆ๋“ค๋ง, ์„œ๋ฒ„ ๊ธฐ์ˆ )์™€ ๋” ๋ฐ€์ ‘ํ•˜๊ฒŒ ํ†ตํ•ฉํ•˜๋Š” ๊ฒƒ์ด React ์‚ฌ์šฉ์ž๊ฐ€ ๋” ๋‚˜์€ ์•ฑ์„ ๋งŒ๋“œ๋Š” ๋ฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ํฐ ๊ธฐํšŒ๋ผ๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. Next.js ํŒ€์€ [React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components)์™€ ๊ฐ™์€ ๊ฐ€์žฅ ์ตœ์‹ ์˜ React ๊ธฐ๋Šฅ์„ ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š” ํ˜•ํƒœ๋กœ ์—ฐ๊ตฌ, ๊ฐœ๋ฐœ, ํ†ตํ•ฉ, ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐ์— ํ˜‘๋ ฅํ•˜๊ธฐ๋กœ ํ•ฉ์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. +React๋ฅผ ์ง€์†์ ์œผ๋กœ ๊ฐœ์„ ํ•  ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๊ฐ€๋Š” ๊ณผ์ •์—์„œ, ์šฐ๋ฆฌ๋Š” React๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ(ํŠนํžˆ ๋ผ์šฐํŒ…, ๋ฒˆ๋“ค๋ง, ์„œ๋ฒ„ ๊ธฐ์ˆ )์™€ ๋” ๋ฐ€์ ‘ํ•˜๊ฒŒ ํ†ตํ•ฉํ•˜๋Š” ๊ฒƒ์ด React ์‚ฌ์šฉ์ž์—๊ฒŒ ๋” ๋‚˜์€ ์•ฑ์„ ๋งŒ๋“œ๋Š” ๋ฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ํฐ ๊ธฐํšŒ๋ผ๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. Next.js ํŒ€์€ [React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components)์™€ ๊ฐ™์€ ๊ฐ€์žฅ ์ตœ์‹ ์˜ React ๊ธฐ๋Šฅ์„ ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š” ํ˜•ํƒœ๋กœ ์—ฐ๊ตฌ, ๊ฐœ๋ฐœ, ํ†ตํ•ฉ, ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐ์— ํ˜‘๋ ฅํ•˜๊ธฐ๋กœ ํ•ฉ์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. -์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ๋“ค์€ ๋งค์ผ ํ”„๋กœ๋•์…˜ ์ˆ˜์ค€์— ๊ทผ์ ‘ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋‹ค๋ฅธ ๋ฒˆ๋“ค๋Ÿฌ ๋ฐ ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ์ด๋ฅผ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•ด ํ˜‘์˜ ์ค‘์ž…๋‹ˆ๋‹ค. ํฌ๋ง์œผ๋กœ๋Š” 1, 2๋…„ ํ›„์— ์ด ํŽ˜์ด์ง€์— ๋‚˜์—ด๋œ ๋ชจ๋“  ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ง€์›ํ–ˆ์œผ๋ฉด ํ•ฉ๋‹ˆ๋‹ค. (์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์‹คํ—˜ํ•ด ๋ณด๊ธฐ ์œ„ํ•ด ์šฐ๋ฆฌ์™€ ํ˜‘๋ ฅํ•˜๊ณ  ์‹ถ์€ ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”!) +์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ๋“ค์€ ๋งค์ผ ํ”„๋กœ๋•์…˜ ์ˆ˜์ค€์— ๊ทผ์ ‘ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ๋‹ค๋ฅธ ๋ฒˆ๋“ค๋Ÿฌ ๋ฐ ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ์ด๋ฅผ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•ด ํ˜‘์˜ ์ค‘์ž…๋‹ˆ๋‹ค. ๋ฐ”๋ผ๊ฑด๋ฐ 1, 2๋…„ ํ›„์— ์ด ํŽ˜์ด์ง€์— ๋‚˜์—ด๋œ ๋ชจ๋“  ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ง€์›ํ–ˆ์œผ๋ฉด ํ•ฉ๋‹ˆ๋‹ค. (์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์‹คํ—˜ํ•ด ๋ณด๊ธฐ ์œ„ํ•ด ์šฐ๋ฆฌ์™€ ํ˜‘๋ ฅํ•˜๊ณ  ์‹ถ์€ ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”!) ### Next.js (App Router) {/*nextjs-app-router*/} -**[Next.js's App Router](https://nextjs.org/docs)๋Š” React ํŒ€์˜ ํ’€์Šคํƒ ์•„ํ‚คํ…์ฒ˜ ๋น„์ „์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์žฌ์„ค๊ณ„๋œ Next.js API์ž…๋‹ˆ๋‹ค.** ์ด๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ๋˜๋Š” ๋นŒ๋“œ ์ค‘์— ์‹คํ–‰๋˜๋Š” ๋น„๋™๊ธฐ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +**[Next.js์˜ App Router](https://nextjs.org/docs)๋Š” React ํŒ€์˜ ํ’€์Šคํƒ ์•„ํ‚คํ…์ฒ˜ ๋น„์ „์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์žฌ์„ค๊ณ„๋œ Next.js API์ž…๋‹ˆ๋‹ค.** ์ด๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ๋˜๋Š” ๋นŒ๋“œ ์ค‘์— ์‹คํ–‰๋˜๋Š” ๋น„๋™๊ธฐ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Next.js๋Š” [Vercel](https://vercel.com/)์ด ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์–ด๋А Node.js ์„œ๋ฒ„, ์„œ๋ฒ„๋ฆฌ์Šค ํ˜ธ์ŠคํŒ… ๋˜๋Š” ์ง์ ‘ ์†Œ์œ ํ•œ ์„œ๋ฒ„ ์–ด๋А ๊ณณ์—๋ผ๋„ [Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌ](https://nextjs.org/docs/app/building-your-application/deploying)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Next.js ๋Š” ์„œ๋ฒ„๊ฐ€ ํ•„์š”์—†๋Š” [static export](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports) ๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +Next.js๋Š” [Vercel](https://vercel.com/)์ด ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค Node.js ์„œ๋ฒ„, ์„œ๋ฒ„๋ฆฌ์Šค ํ˜ธ์ŠคํŒ… ๋˜๋Š” ์ง์ ‘ ์†Œ์œ ํ•œ ์„œ๋ฒ„ ์–ด๋А ๊ณณ์—๋ผ๋„ [Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌ](https://nextjs.org/docs/app/building-your-application/deploying)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Next.js ๋Š” ์„œ๋ฒ„๊ฐ€ ํ•„์š”์—†๋Š” [์ •์  ๋‚ด๋ณด๋‚ด๊ธฐ<sup>Static Exports</sup>](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports)๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. <DeepDive> #### React ํŒ€์˜ ํ’€์Šคํƒ ์•„ํ‚คํ…์ฒ˜ ๋น„์ „์„ ๊ตฌํ˜„ํ•œ ๊ธฐ๋Šฅ์€ ๋ฌด์—‡์ธ๊ฐ€์š”? {/*which-features-make-up-the-react-teams-full-stack-architecture-vision*/} -Next.js์˜ App Router ๋ฒˆ๋“ค๋Ÿฌ๋Š” ๊ณต์‹ [React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๋ช…์„ธ](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md) ์ „์ฒด๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋นŒ๋“œ ์‹œ๊ฐ„, ์„œ๋ฒ„ ์ „์šฉ, ๋Œ€ํ™”ํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•˜๋‚˜์˜ React ํŠธ๋ฆฌ์—์„œ ํ˜ผํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +Next.js์˜ App Router ๋ฒˆ๋“ค๋Ÿฌ๋Š” ๊ณต์‹ [React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๋ช…์„ธ](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md) ์ „์ฒด๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋นŒ๋“œ ์‹œ๊ฐ„<sup>Build-Time</sup>, ์„œ๋ฒ„ ์ „์šฉ<sup>Server-Only</sup>, ๊ทธ๋ฆฌ๊ณ  ๋Œ€ํ™”ํ˜•<sup>Interactive</sup> ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•˜๋‚˜์˜ React ํŠธ๋ฆฌ<sup>Tree</sup>์—์„œ ํ˜ผํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚˜ ํŒŒ์ผ์„ ์ฝ๋Š” `async` ํ•จ์ˆ˜๋กœ ์„œ๋ฒ„ ์ „์šฉ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋Œ€ํ™”ํ˜• ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -108,7 +109,7 @@ async function Talks({ confId }) { // 1. ์„œ๋ฒ„์— ์žˆ์œผ๋ฏ€๋กœ ๋ฐ์ดํ„ฐ ๊ณ„์ธต๊ณผ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. API ์—”๋“œํฌ์ธํŠธ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. const talks = await db.Talks.findAll({ confId }); - // 2. ๋ Œ๋”๋ง ๋กœ์ง์„ ์–ผ๋งˆ๋“ ์ง€ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. JavaScript ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ์ปค์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + // 2. ๋ Œ๋”๋ง ๋กœ์ง์„ ์–ผ๋งˆ๋“ ์ง€ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ์ปค์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. const videos = talks.map(talk => talk.video); // 3. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰๋  ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. @@ -116,7 +117,7 @@ async function Talks({ confId }) { } ``` -Next.js์˜ App Router๋Š” ๋˜ํ•œ Suspense๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ ํ†ต์‹ ๊ณผ๋„ ์ž˜ ์–ด์šธ๋ฆฝ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด React ํŠธ๋ฆฌ์—์„œ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์— ๋Œ€ํ•œ ๋กœ๋”ฉ ์ƒํƒœ(์Šค์ผˆ๋ ˆํ†ค ํ”Œ๋ ˆ์ด์Šคํ™€๋”์™€ ๊ฐ™์€)๋ฅผ ์ง์ ‘ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +Next.js์˜ App Router๋Š” ๋˜ํ•œ Suspense๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ ํ†ต์‹ ๊ณผ๋„ ์ž˜ ์–ด์šธ๋ฆฝ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด React ํŠธ๋ฆฌ์—์„œ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์— ๋Œ€ํ•œ ๋กœ๋”ฉ ์ƒํƒœ(์Šค์ผˆ๋ ˆํ†ค<sup>Skeleton</sup> ํ”Œ๋ ˆ์ด์Šคํ™€๋”<sup>Placeholder</sup>์™€ ๊ฐ™์€)๋ฅผ ์ง์ ‘ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js <Suspense fallback={<TalksLoading />}> @@ -124,6 +125,6 @@ Next.js์˜ App Router๋Š” ๋˜ํ•œ Suspense๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ ํ†ต์‹ ๊ณผ๋„ </Suspense> ``` -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ Suspense๋Š” Next.js์˜ ๊ธฐ๋Šฅ์ด ์•„๋‹Œ React์˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋ ˆ์ž„์›Œํฌ ์ˆ˜์ค€์—์„œ ์ด๋ฅผ ์ฑ„ํƒํ•˜๋ ค๋ฉด ๋งŽ์€ ๋…ธ๋ ฅ๊ณผ ๋น„๊ต์  ๋ณต์žกํ•œ ๊ตฌํ˜„ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ๊ธฐ์ค€์œผ๋กœ๋Š” Next.js์˜ App Router๊ฐ€ ๊ฐ€์žฅ ์™„๋ฒฝํ•œ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค. React ํŒ€์€ ์ฐจ์„ธ๋Œ€ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์‰ฝ๋„๋ก ๋ฒˆ๋“ค๋Ÿฌ ๊ฐœ๋ฐœ์ž์™€ ๊ณต๋™์œผ๋กœ ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ Suspense๋Š” Next.js์˜ ๊ธฐ๋Šฅ์ด ์•„๋‹Œ React์˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋ ˆ์ž„์›Œํฌ ์ˆ˜์ค€์—์„œ ์ด๋ฅผ ์ฑ„ํƒํ•˜๋ ค๋ฉด ๋งŽ์€ ๋…ธ๋ ฅ๊ณผ ๋น„๊ต์  ๋ณต์žกํ•œ ๊ตฌํ˜„ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ๋กœ์„œ๋Š” Next.js์˜ App Router๊ฐ€ ๊ฐ€์žฅ ์™„๋ฒฝํ•œ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค. React ํŒ€์€ ์ฐจ์„ธ๋Œ€ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์‰ฝ๋„๋ก ๋ฒˆ๋“ค๋Ÿฌ ๊ฐœ๋ฐœ์ž์™€ ํ•จ๊ป˜ ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. </DeepDive> From b16e4a21fcbe8b156849afb3e0a98f8367883fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 00:18:22 +0900 Subject: [PATCH 0341/1059] docs: update `add-react-to-an-existing-project.md` --- src/components/Layout/Footer.tsx | 4 +- .../learn/add-react-to-an-existing-project.md | 51 ++++++++++--------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/components/Layout/Footer.tsx b/src/components/Layout/Footer.tsx index 4b2dedd48..ed5324d45 100644 --- a/src/components/Layout/Footer.tsx +++ b/src/components/Layout/Footer.tsx @@ -347,9 +347,7 @@ export function Footer() { <div className="flex flex-col"> <FooterLink isHeader={true}>๋” ๋ณด๊ธฐ</FooterLink> <FooterLink href="/blog">๋ธ”๋กœ๊ทธ</FooterLink> - <FooterLink href="https://reactnative.dev/"> - React ๋„ค์ดํ‹ฐ๋ธŒ - </FooterLink> + <FooterLink href="https://reactnative.dev/">React Native</FooterLink> <FooterLink href="https://opensource.facebook.com/legal/privacy"> ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ </FooterLink> 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 c79c0d7f7..37852b95c 100644 --- a/src/content/learn/add-react-to-an-existing-project.md +++ b/src/content/learn/add-react-to-an-existing-project.md @@ -4,57 +4,57 @@ title: ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— React ์ถ”๊ฐ€ํ•˜๊ธฐ <Intro> -๊ธฐ์กด ํ”„๋กœ์ ํŠธ์™€ ์ผ๋ถ€ ์ƒํ˜ธ์ž‘์šฉ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, React์— ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ ์Šคํƒ์— React๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์–ด๋””์—์„œ๋‚˜ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜์„ธ์š”. +๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ์ƒํ˜ธ์ž‘์šฉ ์š”์†Œ๋ฅผ ์ผ๋ถ€ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, React๋กœ ๋‹ค์‹œ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ์Šคํƒ์— React๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์–ด๋””์—์„œ๋‚˜ ๋ Œ๋”๋งํ•˜์„ธ์š”. </Intro> <Note> -**๋กœ์ปฌ ๊ฐœ๋ฐœํ™˜๊ฒฝ์— [Node.js](https://nodejs.org/en/)๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** ์˜จ๋ผ์ธ์—์„œ [try React](/learn/installation#try-react)๋ฅผ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ๊ฐ„๋‹จํ•œ HTML์—์„œ๋„ React๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํ˜„์‹ค์ ์œผ๋กœ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ JavaScript ๋„๊ตฌ๋Š” Node.js๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. +**๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— [Node.js](https://nodejs.org/en/)๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** ์˜จ๋ผ์ธ์—์„œ [React](/learn/installation#try-react)๋ฅผ ์‹œ๋„ํ•˜๊ฑฐ๋‚˜ ๊ฐ„๋‹จํ•œ HTML์—์„œ React๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ํ˜„์‹ค์ ์ธ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋„๊ตฌ์—๋Š” Node.js๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. </Note> -## ๊ธฐ์กด ์›น์‚ฌ์ดํŠธ์˜ ์ „์ฒด ํ•˜์œ„ ๊ฒฝ๋กœ์— React ์‚ฌ์šฉํ•˜๊ธฐ {/*using-react-for-an-entire-subroute-of-your-existing-website*/} +## ๊ธฐ์กด ์›น์‚ฌ์ดํŠธ์˜ ํ•˜์œ„ ๊ฒฝ๋กœ ์ „์ฒด์— React ์‚ฌ์šฉํ•˜๊ธฐ {/*using-react-for-an-entire-subroute-of-your-existing-website*/} -`example.com`์ด๋ผ๋Š” ๋˜ ๋‹ค๋ฅธ ์„œ๋ฒ„ ๊ธฐ์ˆ  (Rails์™€ ๊ฐ™์€) ๋กœ ๋นŒ๋“œํ•œ ๊ธฐ์กด ์›น ์•ฑ์ด ์žˆ๊ณ , `example.com/some-app/`์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ React๋กœ ์™„์ „ํžˆ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. +`example.com`์ด๋ผ๋Š” ๋˜ ๋‹ค๋ฅธ ์„œ๋ฒ„ ๊ธฐ์ˆ (Rails์™€ ๊ฐ™์€)๋กœ ๋นŒ๋“œํ•œ ๊ธฐ์กด ์›น ์•ฑ์ด ์žˆ๊ณ , `example.com/some-app/`์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ React๋กœ ์™„์ „ํžˆ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. 1. [React ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ](/learn/start-a-new-react-project) ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ **์•ฑ์˜ React ๋ถ€๋ถ„์„ ๋นŒ๋“œํ•˜์„ธ์š”.** -2. ์‚ฌ์šฉํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์„ค์ •์—์„œ **`/some-app` ์„ *๊ธฐ๋ณธ ๊ฒฝ๋กœ*๋กœ ๋ช…์‹œํ•˜์„ธ์š”.** (๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. [Next.js](https://nextjs.org/docs/api-reference/next.config.js/basepath), [Gatsby](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/path-prefix/)) -3. **์„œ๋ฒ„ ๋˜๋Š” ํ”„๋ก์‹œ๋ฅผ ๊ตฌ์„ฑ**ํ•˜์—ฌ `/some-app/` ์•„๋ž˜์˜ ๋ชจ๋“  ์š”์ฒญ์ด React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ฒ˜๋ฆฌ๋˜๋„๋ก ํ•˜์„ธ์š”. +2. ์‚ฌ์šฉํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์„ค์ •์—์„œ **`/some-app` ์„ *๊ธฐ๋ณธ ๊ฒฝ๋กœ*<sup>*Base Path*</sup>๋กœ ๋ช…์‹œํ•˜์„ธ์š”**. (์ด๋•Œ, [Next.js](https://nextjs.org/docs/api-reference/next.config.js/basepath), [Gatsby](https://www.gatsbyjs.com/docs/how-to/previews-deploys-hosting/path-prefix/)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”!) +3. **์„œ๋ฒ„ ๋˜๋Š” ํ”„๋ก์‹œ๋ฅผ ๊ตฌ์„ฑ**ํ•˜์—ฌ `/some-app/` ํ•˜์œ„์˜ ๋ชจ๋“  ์š”์ฒญ์ด React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ฒ˜๋ฆฌ๋˜๋„๋ก ํ•˜์„ธ์š”. -์ด๋Š” ์•ฑ์˜ React ๋ถ€๋ถ„์ด ์ด๋Ÿฌํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋‚ด์žฅ๋œ [์ตœ๊ณ ์˜ ์‚ฌ๋ก€๋“ค๋กœ๋ถ€ํ„ฐ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.](/learn/start-a-new-react-project#can-i-use-react-without-a-framework) +์ด๋Š” ์•ฑ์˜ React ๋ถ€๋ถ„์ด ์ด๋Ÿฌํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋‚ด์žฅ๋œ [์ตœ๊ณ ์˜ ์‚ฌ๋ก€๋“ค<sup>Best Practices</sup>๋กœ๋ถ€ํ„ฐ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.](/learn/start-a-new-react-project#can-i-use-react-without-a-framework) -๋งŽ์€ React ๊ธฐ๋ฐ˜์˜ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ํ’€์Šคํƒ์ด๋ฉฐ React ์•ฑ์ด ์„œ๋ฒ„๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์„œ๋ฒ„์—์„œ JavaScript๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๊ฑฐ๋‚˜ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋„ ๋™์ผํ•œ ์ ‘๊ทผ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ์—๋Š” HTML/CSS/JS ๋‚ด๋ณด๋‚ด๊ธฐ(Next.js์˜ ๊ฒฝ์šฐ [`next export` output](https://nextjs.org/docs/advanced-features/static-html-export), Gatsby์˜ ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’)๋ฅผ `/some-app/`์—์„œ ๋Œ€์‹  ์ œ๊ณตํ•˜์„ธ์š”. +๋งŽ์€ React ๊ธฐ๋ฐ˜์˜ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ํ’€์Šคํƒ์ด๋ฉฐ React ์•ฑ์ด ์„œ๋ฒ„๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์„œ๋ฒ„์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๊ฑฐ๋‚˜ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋„ ๋™์ผํ•œ ์ ‘๊ทผ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ์—๋Š” HTML/CSS/JS ๋‚ด๋ณด๋‚ด๊ธฐ(Next.js์˜ ๊ฒฝ์šฐ [`next export` output](https://nextjs.org/docs/advanced-features/static-html-export), Gatsby์˜ ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’)๋ฅผ `/some-app/`์—์„œ ๋Œ€์‹  ์ œ๊ณตํ•˜์„ธ์š”. ## ๊ธฐ์กด ํŽ˜์ด์ง€์˜ ์ผ๋ถ€๋ถ„์— React ์‚ฌ์šฉํ•˜๊ธฐ {/*using-react-for-a-part-of-your-existing-page*/} -์ด๋ฏธ ๋‹ค๋ฅธ ๊ธฐ์ˆ (Rails์™€ ๊ฐ™์€ ์„œ๋ฒ„ ๊ธฐ์ˆ  ๋˜๋Š” Backbone๊ณผ ๊ฐ™์€ ํด๋ผ์ด์–ธํŠธ ๊ธฐ์ˆ )๋กœ ๋นŒ๋“œ๋œ ๊ธฐ์กด ํŽ˜์ด์ง€๊ฐ€ ์žˆ๊ณ  ํ•ด๋‹น ํŽ˜์ด์ง€ ์–ด๋”˜๊ฐ€์— ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ์ด๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•ฉํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.-- ์‹ค์ œ๋กœ ์ˆ˜๋…„ ๋™์•ˆ Meta์—์„œ ๋Œ€๋ถ€๋ถ„์˜ React ์‚ฌ์šฉ์„ ์ด๋Ÿฐ ์‹์œผ๋กœ ํ•˜์˜€์Šต๋‹ˆ๋‹ค! +์ด๋ฏธ ๋‹ค๋ฅธ ๊ธฐ์ˆ (Rails์™€ ๊ฐ™์€ ์„œ๋ฒ„ ๊ธฐ์ˆ  ๋˜๋Š” Backbone๊ณผ ๊ฐ™์€ ํด๋ผ์ด์–ธํŠธ ๊ธฐ์ˆ )๋กœ ๋นŒ๋“œ๋œ ๊ธฐ์กด ํŽ˜์ด์ง€๊ฐ€ ์žˆ๊ณ , ํ•ด๋‹น ํŽ˜์ด์ง€ ์–ด๋”˜๊ฐ€์— ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•ฉํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ˆ˜๋…„ ๋™์•ˆ Meta์—์„œ ๋Œ€๋ถ€๋ถ„์˜ React ์‚ฌ์šฉ์„ ์ด๋Ÿฐ ์‹์œผ๋กœ ํ•˜์˜€์Šต๋‹ˆ๋‹ค! ์ด ๋ฐฉ์‹์€ ๋‘ ๊ฐ€์ง€ ๋‹จ๊ณ„๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -1. [JSX ๋ฌธ๋ฒ•](/learn/writing-markup-with-jsx)์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ **JavaScript ํ™˜๊ฒฝ์„ ์„ค์ •**ํ•˜๊ณ  [`import`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import) / [`export`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/export) ๋ฌธ๋ฒ•์„ ํ†ตํ•ด ์ฝ”๋“œ๋ฅผ ๋ชจ๋“ˆ๋กœ ๋ถ„๋ฆฌํ•œ ๋‹ค์Œ [npm](https://www.npmjs.com/) ํŒจํ‚ค์ง€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์˜ ํŒจํ‚ค์ง€(์˜ˆ์‹œ: React)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. +1. [JSX ๊ตฌ๋ฌธ](/learn/writing-markup-with-jsx)์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ **์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์„ ์„ค์ •**ํ•˜๊ณ , [`import`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import) / [`export`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/export) ๊ตฌ๋ฌธ์„ ํ†ตํ•ด ์ฝ”๋“œ๋ฅผ ๋ชจ๋“ˆ๋กœ ๋ถ„๋ฆฌํ•œ ๋‹ค์Œ, [npm](https://www.npmjs.com/) ํŒจํ‚ค์ง€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ํŒจํ‚ค์ง€(์˜ˆ์‹œ: React)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. -2. ํ•ด๋‹น ํŽ˜์ด์ง€์—์„œ ๋ณด๊ณ  ์‹ถ์€ ๊ณณ์— **React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜์„ธ์š”.** +2. ํ•ด๋‹น ํŽ˜์ด์ง€์—์„œ ์›ํ•˜๋Š” ์œ„์น˜์— **React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜์„ธ์š”.** ์ •ํ™•ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์€ ๊ธฐ์กด ํŽ˜์ด์ง€์˜ ์„ค์ •์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, ๋ช‡ ๊ฐ€์ง€ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ํ•จ๊ป˜ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -### 1๋‹จ๊ณ„ : ๋ชจ๋“ˆ JavaScript ํ™˜๊ฒฝ ์„ค์ •ํ•˜๊ธฐ {/*step-1-set-up-a-modular-javascript-environment*/} +### 1๋‹จ๊ณ„: ๋ชจ๋“ˆ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ ์„ค์ •ํ•˜๊ธฐ {/*step-1-set-up-a-modular-javascript-environment*/} -๋ชจ๋“ˆ JavaScript ํ™˜๊ฒฝ์€ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ํ•œ ํŒŒ์ผ์— ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๊ฐ๊ฐ์˜ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐœ๋ณ„ ํŒŒ์ผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ React ์ž์ฒด๋ฅผ ํฌํ•จํ•œ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์ด [npm](https://www.npmjs.com/) ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋ฐฐํฌํ•œ ๋ชจ๋“  ํ›Œ๋ฅญํ•œ ํŒจํ‚ค์ง€๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ๊ธฐ์กด ์„ค์ •์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์ง„ํ–‰๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +๋ชจ๋“ˆ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์€ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ํ•œ ํŒŒ์ผ์— ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ๊ฐ๊ฐ์˜ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐœ๋ณ„ ํŒŒ์ผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ (React ์ž์ฒด๋ฅผ ํฌํ•จํ•œ) ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์ด [npm](https://www.npmjs.com/) ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋ฐฐํฌํ•œ ํ›Œ๋ฅญํ•œ ํŒจํ‚ค์ง€๋“ค์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ธฐ์กด ์„ค์ •์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. -* **์ด๋ฏธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด `import` ๋ฌธ๋ฒ•์„ ์ด์šฉํ•ด ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ์žˆ๋‹ค๋ฉด** ๊ธฐ์กด์— ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์„ค์ •์„ ์ด์šฉํ•ด ๋ณด์„ธ์š”. JS ์ฝ”๋“œ์—์„œ `<div />`๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋ฌธ๋ฒ• ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•ด ๋ณด์„ธ์š”. ๋ฌธ๋ฒ• ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด [Babel์„ ์ด์šฉํ•œ JavaScript ์ฝ”๋“œ ๋ณ€ํ™˜](https://babeljs.io/setup)์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ JSX๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด [Babel React ํ”„๋ฆฌ์…‹](https://babeljs.io/docs/babel-preset-react)์„ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* **์ด๋ฏธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด `import` ๋ฌธ์„ ์ด์šฉํ•ด ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ์žˆ๋‹ค๋ฉด** ๊ธฐ์กด์— ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์„ค์ •์„ ์ด์šฉํ•ด ๋ณด์„ธ์š”. JS ์ฝ”๋“œ์—์„œ `<div />`๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋ฌธ๋ฒ• ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•ด ๋ณด์„ธ์š”. ๋ฌธ๋ฒ• ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด [Babel์„ ์ด์šฉํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ ๋ณ€ํ™˜](https://babeljs.io/setup)์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, JSX๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด [Babel React ํ”„๋ฆฌ์…‹](https://babeljs.io/docs/babel-preset-react)์„ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -* **์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด JavaScript ๋ชจ๋“ˆ์„ ์ปดํŒŒ์ผํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ์กด ์„ค์ •์ด ์—†๋‹ค๋ฉด,** [Vite](https://vitejs.dev/)๋ฅผ ์ด์šฉํ•˜์—ฌ ์„ค์ •ํ•˜์„ธ์š”. Vite ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” Rails, Django, Laravel์„ ํฌํ•จํ•œ [๋‹ค์–‘ํ•œ ๋ฐฑ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ์™€์˜ ํ†ตํ•ฉ](https://github.com/vitejs/awesome-vite#integrations-with-backends)์„ ์ง€์›ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ ์ค‘์ธ ๋ฐฑ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋ชฉ๋ก์— ์—†๋‹ค๋ฉด [์ด ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ](https://vitejs.dev/guide/backend-integration.html) Vite ๋นŒ๋“œ๋ฅผ ๋ฐฑ์—”๋“œ์™€ ์ˆ˜๋™์œผ๋กœ ํ†ตํ•ฉํ•˜์„ธ์š”. +* **์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ชจ๋“ˆ์„ ์ปดํŒŒ์ผํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ์กด ์„ค์ •์ด ์—†๋‹ค๋ฉด,** [Vite](https://vitejs.dev/)๋ฅผ ์ด์šฉํ•˜์—ฌ ์„ค์ •ํ•˜์„ธ์š”. Vite ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” Rails, Django, Laravel์„ ํฌํ•จํ•œ [๋‹ค์–‘ํ•œ ๋ฐฑ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ์™€์˜ ํ†ตํ•ฉ](https://github.com/vitejs/awesome-vite#integrations-with-backends)์„ ์ง€์›ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ ์ค‘์ธ ๋ฐฑ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋ชฉ๋ก์— ์—†๋‹ค๋ฉด [๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ](https://vitejs.dev/guide/backend-integration.html) Vite ๋นŒ๋“œ๋ฅผ ๋ฐฑ์—”๋“œ์™€ ์ˆ˜๋™์œผ๋กœ ํ†ตํ•ฉํ•˜์„ธ์š”. -์„ค์ •์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด ํ”„๋กœ์ ํŠธ ํด๋”์—์„œ ์•„๋ž˜ ์ปค๋งจ๋“œ๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”. +์„ค์ •์ด ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด ํ”„๋กœ์ ํŠธ ํด๋”์—์„œ ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”. <TerminalBlock> npm install react react-dom </TerminalBlock> -๊ทธ๋ฆฌ๊ณ  ๋ฉ”์ธ JavaScript ํŒŒ์ผ(`index.js` ํ˜น์€ `main.js`๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ํŒŒ์ผ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)์˜ ์ตœ์ƒ๋‹จ์— ๋‹ค์Œ ์ฝ”๋“œ ๋ผ์ธ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”. +๊ทธ๋ฆฌ๊ณ  ๋ฉ”์ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ(`index.js` ํ˜น์€ `main.js`๋ผ๋Š” ํŒŒ์ผ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)์˜ ์ตœ์ƒ๋‹จ์— ๋‹ค์Œ ์ฝ”๋“œ ๋ผ์ธ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”. <Sandpack> @@ -81,17 +81,18 @@ root.render(<h1>Hello, world</h1>); </Sandpack> -ํŽ˜์ด์ง€์˜ ์ „์ฒด ๋‚ด์šฉ์ด "Hello, world!"๋กœ ๋ฐ”๋€Œ์—ˆ๋‹ค๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๊ณ  ์žˆ๋Š” ๊ฒ๋‹ˆ๋‹ค! ๊ณ„์†ํ•ด์„œ ์ฝ์–ด๋ณด์„ธ์š”. +ํŽ˜์ด์ง€์˜ ์ „์ฒด ๋‚ด์šฉ์ด "Hello, world!"๋กœ ๋ฐ”๋€Œ์—ˆ๋‹ค๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๊ณ  ์žˆ๋Š” ๊ฒ๋‹ˆ๋‹ค! ๊ณ„์†ํ•ด์„œ ์ฝ์–ด๋ณด์„ธ์š”. <Note> -์ฒ˜์Œ์œผ๋กœ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ๋ชจ๋“ˆ JavaScript ํ™˜๊ฒฝ์„ ํ†ตํ•ฉํ•˜๊ธฐ๋Š” ๋‹ค์†Œ ์–ด๋ ค์›Œ ๋ณด์ผ ์ˆ˜ ์žˆ์œผ๋‚˜ ๊ทธ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š” ์ผ์ž…๋‹ˆ๋‹ค! ์–ด๋ ค์›€์„ ๊ฒช๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ์šฐ๋ฆฌ์˜ [์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฆฌ์†Œ์Šค](/community)๋‚˜ [Vite ์ฑ„ํŒ…](https://chat.vitejs.dev/)์„ ์ด์šฉํ•ด ๋ณด์„ธ์š”. +์ฒ˜์Œ์œผ๋กœ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์— ๋ชจ๋“ˆ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ™˜๊ฒฝ์„ ํ†ตํ•ฉํ•˜๊ธฐ๋Š” ๋‹ค์†Œ ์–ด๋ ค์›Œ ๋ณด์ผ ์ˆ˜ ์žˆ์œผ๋‚˜, ๊ทธ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š” ์ผ์ž…๋‹ˆ๋‹ค! ์–ด๋ ค์›€์„ ๊ฒช๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด [์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฆฌ์†Œ์Šค](/community)๋‚˜ [Vite ์ฑ„ํŒ…](https://chat.vitejs.dev/)์„ ์ด์šฉํ•ด ๋ณด์„ธ์š”. </Note> -### 2๋‹จ๊ณ„ : ํŽ˜์ด์ง€ ์–ด๋””์—์„œ๋“  React ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋งํ•˜๊ธฐ {/*step-2-render-react-components-anywhere-on-the-page*/} -์ด์ „ ๋‹จ๊ณ„์—์„œ๋Š”, ๋ฉ”์ธ ํŒŒ์ผ ์ตœ์ƒ๋‹จ์— ์ด ์ฝ”๋“œ๋ฅผ ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค. +### 2๋‹จ๊ณ„: ํŽ˜์ด์ง€ ์–ด๋””์—์„œ๋“  React ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋งํ•˜๊ธฐ {/*step-2-render-react-components-anywhere-on-the-page*/} + +์ด์ „ ๋‹จ๊ณ„์—์„œ๋Š”, ๋ฉ”์ธ ํŒŒ์ผ ์ตœ์ƒ๋‹จ์— ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค. ```js import { createRoot } from 'react-dom/client'; @@ -108,7 +109,7 @@ root.render(<h1>Hello, world</h1>); ์ด ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•˜์„ธ์š”. -๋Œ€์‹  React ์ปดํฌ๋„ŒํŠธ๋ฅผ HTML์˜ ํŠน์ • ์œ„์น˜์— ๋ Œ๋”๋งํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. HTML ํŽ˜์ด์ง€๋ฅผ ์—ด๊ณ (๋˜๋Š” ์ด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์„œ๋ฒ„ ํ…œํ”Œ๋ฆฟ) HTML ํƒœ๊ทธ์— ๊ณ ์œ ํ•œ `id` ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”. +๋Œ€์‹  React ์ปดํฌ๋„ŒํŠธ๋ฅผ HTML์˜ ํŠน์ • ์œ„์น˜์— ๋ Œ๋”๋งํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. HTML ํŽ˜์ด์ง€๋ฅผ ์—ด๊ณ (๋˜๋Š” ์ด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์„œ๋ฒ„ ํ…œํ”Œ๋ฆฟ) HTML ํƒœ๊ทธ์— ๊ณ ์œ ํ•œ [`id`](https://developer.mozilla.org/ko/docs/Web/HTML/Global_attributes/id) ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”. ```html <!-- ... html์˜ ์–ด๋”˜๊ฐ€ ... --> @@ -116,7 +117,7 @@ root.render(<h1>Hello, world</h1>); <!-- ... ๋” ๋งŽ์€ html ... --> ``` -์ด๋ ‡๊ฒŒ ํ•˜๋ฉด [`document.getElementById`](https://developer.mozilla.org/ko/docs/Web/API/Document/getElementById)๋กœ HTML ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ฐพ์•„์„œ [`createRoot`](/reference/react-dom/client/createRoot)์— ์ „๋‹ฌํ•จ์œผ๋กœ์จ ํ•ด๋‹น ์š”์†Œ ๋‚ด๋ถ€์— React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ํ•˜๋ฉด [`document.getElementById`](https://developer.mozilla.org/ko/docs/Web/API/Document/getElementById)๋กœ HTML ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ฐพ์•„ [`createRoot`](/reference/react-dom/client/createRoot)์— ์ „๋‹ฌํ•จ์œผ๋กœ์จ ํ•ด๋‹น ์š”์†Œ ๋‚ด๋ถ€์— React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <Sandpack> @@ -147,10 +148,10 @@ root.render(<NavigationBar />); </Sandpack> -๊ธฐ์กด์— ์กด์žฌํ•˜๋˜ 'index.html'์˜ ์›๋ณธ HTML ์ปจํ…์ธ ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‚จ์•„์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด์ œ๋Š” `<nav id="navigation">` ์•ˆ์— ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์ž‘์„ฑํ•œ `NavigationBar` React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด HTML ํŽ˜์ด์ง€์—์„œ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋˜๋Š” ๊ฒƒ์— ๋Œ€ํ•˜์—ฌ ๋” ์•Œ์•„๋ณด๋ ค๋ฉด [`createRoot` ์‚ฌ์šฉ๋ฒ• ๋ฌธ์„œ](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react)๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”. +๊ธฐ์กด์— ์กด์žฌํ•˜๋˜ `index.html`์˜ ์›๋ณธ HTML ์ปจํ…์ธ ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‚จ์•„์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด์ œ๋Š” `<nav id="navigation">` ์•ˆ์— ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์ž‘์„ฑํ•œ `NavigationBar` React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด HTML ํŽ˜์ด์ง€์—์„œ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋˜๋Š” ๊ฒƒ์— ๋Œ€ํ•˜์—ฌ ๋” ์•Œ์•„๋ณด๋ ค๋ฉด [`createRoot` ์‚ฌ์šฉ๋ฒ• ๋ฌธ์„œ](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react)๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”. ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์—์„œ React๋ฅผ ๋„์ž…ํ•  ๋•Œ, ์ผ๋ฐ˜์ ์œผ๋กœ ์ž‘์€ ์ƒํ˜ธ์ž‘์šฉ ์ปดํฌ๋„ŒํŠธ(์˜ˆ์‹œ: ๋ฒ„ํŠผ)์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ์ ์ง„์ ์œผ๋กœ "์ƒ์œ„ ๊ตฌ์กฐ๋กœ ํ™•์žฅํ•˜๋ฉด์„œ" ๊ฒฐ๊ตญ์—๋Š” ์ „์ฒด ํŽ˜์ด์ง€๊ฐ€ React๋กœ ๋นŒ๋“œ๋  ๋•Œ๊นŒ์ง€ ์ด ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ์ง€์ ์— ๋„๋‹ฌํ•œ๋‹ค๋ฉด React์˜ ์žฅ์ ์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด [React ํ”„๋ ˆ์ž„์›Œํฌ](/learn/start-a-new-react-project)๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ## ๊ธฐ์กด ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋ฐ”์ผ ์•ฑ์—์„œ React Native ์‚ฌ์šฉํ•˜๊ธฐ {/*using-react-native-in-an-existing-native-mobile-app*/} -[React Native](https://reactnative.dev/) ์—ญ์‹œ ๊ธฐ์กด ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์— ์ ์ง„์ ์œผ๋กœ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ˆ๋“œ๋กœ์ด๋“œ(Java ๋˜๋Š” Kotlin)๋‚˜ iOS(Objective-C ๋˜๋Š” Swift) ์•ฑ์„ ๊ฐœ๋ฐœํ•˜๊ณ  ์žˆ๋‹ค๋ฉด,[์ด ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ](https://reactnative.dev/docs/integration-with-existing-apps) React Native ํ™”๋ฉด์„ ์ถ”๊ฐ€ํ•ด๋ณด์„ธ์š”. +[React Native](https://reactnative.dev/) ์—ญ์‹œ ๊ธฐ์กด ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ์— ์ ์ง„์ ์œผ๋กœ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ˆ๋“œ๋กœ์ด๋“œ(Java ๋˜๋Š” Kotlin)๋‚˜ iOS(Objective-C ๋˜๋Š” Swift) ์•ฑ์„ ๊ฐœ๋ฐœํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, [๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ](https://reactnative.dev/docs/integration-with-existing-apps) React Native ํ™”๋ฉด์„ ์ถ”๊ฐ€ํ•ด๋ณด์„ธ์š”. From ba07b3d9dd31671756875e4cb7be2cbe15533b32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 01:27:43 +0900 Subject: [PATCH 0342/1059] docs: resolve conflict and update `react-compiler.md` --- src/content/learn/react-compiler.md | 285 +++++----------------------- 1 file changed, 48 insertions(+), 237 deletions(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 503bc1e11..5f66d54f8 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -3,50 +3,31 @@ title: React ์ปดํŒŒ์ผ๋Ÿฌ --- <Intro> -<<<<<<< HEAD -์ด ํŽ˜์ด์ง€๋Š” ์ƒˆ๋กœ์šด ์‹คํ—˜์  React ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ ์†Œ๊ฐœ์™€ ์ด๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์‹œ๋„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. -======= -This page will give you an introduction to React Compiler and how to try it out successfully. ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 +์ด ํŽ˜์ด์ง€๋Š” React ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ ์†Œ๊ฐœ์™€ ์ด๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์‹œ๋„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. </Intro> <Wip> -์ด ๋ฌธ์„œ๋Š” ์•„์ง ์ž‘์—… ์ค‘์ž…๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ์ •๋ณด๋Š” [React ์ปดํŒŒ์ผ๋Ÿฌ ์›Œํ‚น ๊ทธ๋ฃน ์ €์žฅ์†Œ](https://github.com/reactwg/react-compiler/discussions)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, React ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋” ์•ˆ์ •ํ™”๋˜๋ฉด ์ด ๋ฌธ์„œ์— ๋ฐ˜์˜๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ด ๋ฌธ์„œ๋Š” ์•„์ง ์ž‘์—… ์ค‘์ž…๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ์ •๋ณด๋Š” [React ์ปดํŒŒ์ผ๋Ÿฌ ์›Œํ‚น ๊ทธ๋ฃน ์ €์žฅ์†Œ](https://github.com/reactwg/react-compiler/discussions)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, React ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋”์šฑ ์•ˆ์ •ํ™”๋˜๋ฉด ์ด ๋ฌธ์„œ์— ๋ฐ˜์˜๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. </Wip> <YouWillLearn> -<<<<<<< HEAD * ์ปดํŒŒ์ผ๋Ÿฌ ์‹œ์ž‘ํ•˜๊ธฐ -* ์ปดํŒŒ์ผ๋Ÿฌ ๋ฐ eslint ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜ +* ์ปดํŒŒ์ผ๋Ÿฌ ๋ฐ ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜ * ๋ฌธ์ œ ํ•ด๊ฒฐ -======= -* Getting started with the compiler -* Installing the compiler and ESLint plugin -* Troubleshooting ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 </YouWillLearn> <Note> -<<<<<<< HEAD -React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ๋ถ€ํ„ฐ ์ดˆ๊ธฐ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ์˜คํ”ˆ์†Œ์Šค๋กœ ๊ณต๊ฐœํ•œ ์ƒˆ๋กœ์šด ์‹คํ—˜์  ์ปดํŒŒ์ผ๋Ÿฌ์ž…๋‹ˆ๋‹ค. ์•„์ง ์•ˆ์ •์ ์ด์ง€ ์•Š์œผ๋ฉฐ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์™„์ „ํžˆ ์ค€๋น„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. -React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React 19 RC๋ฅผ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ [์›Œํ‚น ๊ทธ๋ฃน](https://github.com/reactwg/react-compiler/discussions/6)์— ์„ค๋ช…๋œ ๋Œ€๋กœ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ์บ์‹œ ํ•จ์ˆ˜ ๊ตฌํ˜„์„ ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋ฐฉ๋ฒ•์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์œผ๋ฉฐ ๊ฐ€๋Šฅํ•œ ํ•œ React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. -</Note> - -React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋นŒ๋“œ ํƒ€์ž„ ์ „์šฉ ๋„๊ตฌ๋กœ React ์•ฑ์„ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ˆœ์ˆ˜ JavaScript๋กœ ๋™์ž‘ํ•˜๋ฉฐ [React์˜ ๊ทœ์น™](/reference/rules)์„ ์ดํ•ดํ•˜๋ฏ€๋กœ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. - -์ปดํŒŒ์ผ๋Ÿฌ์—๋Š” ์—๋””ํ„ฐ ๋‚ด์—์„œ ๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” [eslint ํ”Œ๋Ÿฌ๊ทธ์ธ](#installing-eslint-plugin-react-compiler)๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์ปดํŒŒ์ผ๋Ÿฌ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฉฐ, ์•ฑ์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  React ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ํ’ˆ์งˆ์„ ํ–ฅ์ƒํ•˜๊ธฐ ์œ„ํ•ด ์ด eslint ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. -======= -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). +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ๋ถ€ํ„ฐ ์ดˆ๊ธฐ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ์˜คํ”ˆ์†Œ์Šค๋กœ ๊ณต๊ฐœํ•œ ๋ฒ ํƒ€<sup>Beta</sup> ๋ฒ„์ „์˜ ์ƒˆ๋กœ์šด ์ปดํŒŒ์ผ๋Ÿฌ์ž…๋‹ˆ๋‹ค. 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`. </Note> -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. +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ๋ถ€ํ„ฐ ์ดˆ๊ธฐ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ์˜คํ”ˆ์†Œ์Šค๋กœ ๊ณต๊ฐœํ•œ ์ƒˆ๋กœ์šด ์ปดํŒŒ์ผ๋Ÿฌ์ž…๋‹ˆ๋‹ค. React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋นŒ๋“œ ํƒ€์ž„ ์ „์šฉ ๋„๊ตฌ๋กœ React ์•ฑ์„ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ˆœ์ˆ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋™์ž‘ํ•˜๋ฉฐ, [React์˜ ๊ทœ์น™](/reference/rules)์„ ์ดํ•ดํ•˜๋ฏ€๋กœ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. -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. +์ปดํŒŒ์ผ๋Ÿฌ์—๋Š” ์—๋””ํ„ฐ ๋‚ด์—์„œ ๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” [ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ](#installing-eslint-plugin-react-compiler)๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. **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: @@ -61,37 +42,32 @@ yarn add -D babel-plugin-react-compiler@beta eslint-plugin-react-compiler@beta </TerminalBlock> If you are not using React 19 yet, please see [the section below](#using-react-compiler-with-react-17-or-18) for further instructions. ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 ### ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฌด์—‡์„ ํ•˜๋‚˜์š”? {/*what-does-the-compiler-do*/} -React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ `useMemo`, `useCallback`, `React.memo`์™€ ๊ฐ™์€ API๋ฅผ ํ†ตํ•ด ์ ์šฉํ•˜๋Š” ๋ฉ”๋ชจ์ด์ œ์ด์…˜์— ์ต์ˆ™ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด React์— ์ž…๋ ฅ์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ํŠน์ • ๋ถ€๋ถ„์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๊ณ  ์•Œ๋ฆด ์ˆ˜ ์žˆ์–ด ์—…๋ฐ์ดํŠธ ์‹œ ์ž‘์—…์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์„ ์žŠ๊ฑฐ๋‚˜ ์ž˜๋ชป ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ React๊ฐ€ _์˜๋ฏธ ์žˆ๋Š”_ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์—†๋Š” UI ์ผ๋ถ€๋ฅผ ํ™•์ธํ•ด์•ผ ํ•˜๋ฏ€๋กœ ํšจ์œจ์ ์ด์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜<sup>Memoization</sup>ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ `useMemo`, `useCallback`, `React.memo`์™€ ๊ฐ™์€ API๋ฅผ ํ†ตํ•œ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์— ์ต์ˆ™ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด React์—๊ฒŒ ์ž…๋ ฅ์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ํŠน์ • ๋ถ€๋ถ„์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๊ณ  ์•Œ๋ฆด ์ˆ˜ ์žˆ์–ด ์—…๋ฐ์ดํŠธ ์‹œ ์ž‘์—…๋Ÿ‰์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์„ ์žŠ๊ฑฐ๋‚˜ ์ž˜๋ชป ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ React๊ฐ€ _์˜๋ฏธ ์žˆ๋Š”_ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์—†๋Š” UI ์ผ๋ถ€๋ฅผ ํ™•์ธํ•ด์•ผ ํ•˜๋ฏ€๋กœ ํšจ์œจ์ ์ด์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ปดํŒŒ์ผ๋Ÿฌ๋Š” JavaScript์™€ React์˜ ๊ทœ์น™์— ๋Œ€ํ•œ ์ง€์‹์„ ํ™œ์šฉํ•˜์—ฌ ์ž๋™์œผ๋กœ ์ปดํฌ๋„ŒํŠธ์™€ Hooks ๋‚ด์˜ ๊ฐ’ ๋˜๋Š” ๊ฐ’ ๊ทธ๋ฃน์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•ฉ๋‹ˆ๋‹ค. ๊ทœ์น™ ์œ„๋ฐ˜์„ ๊ฐ์ง€ํ•  ๊ฒฝ์šฐ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ๋˜๋Š” Hooks๋ฅผ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. +์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ React์˜ ๊ทœ์น™์— ๋Œ€ํ•œ ์ง€์‹์„ ํ™œ์šฉํ•˜์—ฌ ์ž๋™์œผ๋กœ ์ปดํฌ๋„ŒํŠธ์™€ Hook ๋‚ด๋ถ€์˜ ๊ฐ’ ๋˜๋Š” ๊ฐ’ ๊ทธ๋ฃน์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•ฉ๋‹ˆ๋‹ค. ๊ทœ์น™ ์œ„๋ฐ˜์„ ๊ฐ์ง€ํ•  ๊ฒฝ์šฐ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ๋˜๋Š” Hook์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. -<<<<<<< HEAD -์ด๋ฏธ ์ฝ”๋“œ๋ฒ ์ด์Šค์— ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ์ž˜ ๋˜์–ด ์žˆ๋‹ค๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ†ตํ•ด ์ฃผ์š” ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ๊ธฐ๋Œ€ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ๋กœ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š” ์˜ฌ๋ฐ”๋ฅธ ์˜์กด์„ฑ์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜๋Š” ๊ฒƒ์€ ์ˆ˜์ž‘์—…์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -======= <Note> 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. </Note> -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. ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 +์ด๋ฏธ ์ฝ”๋“œ๋ฒ ์ด์Šค์— ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ์ž˜ ๋˜์–ด ์žˆ๋‹ค๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ†ตํ•ด ์ฃผ์š” ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ๊ธฐ๋Œ€ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ๋กœ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š” ์˜ฌ๋ฐ”๋ฅธ ์˜์กด์„ฑ<sup>dependencies</sup>์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜๋Š” ๊ฒƒ์€ ์ง์ ‘ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <DeepDive> -#### React Compiler์€ ์–ด๋–ค ๊ฒƒ์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜๋‚˜์š”? {/*what-kind-of-memoization-does-react-compiler-add*/} +#### React Compiler๋Š” ์–ด๋–ค ๊ฒƒ์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜๋‚˜์š”? {/*what-kind-of-memoization-does-react-compiler-add*/} React ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์ดˆ๊ธฐ ๋ฆด๋ฆฌ์ฆˆ๋Š” ์ฃผ๋กœ **์—…๋ฐ์ดํŠธ ์„ฑ๋Šฅ ๊ฐœ์„ **(๊ธฐ์กด ์ปดํฌ๋„ŒํŠธ์˜ ๋ฆฌ๋ Œ๋”๋ง)์— ์ดˆ์ ์„ ๋งž์ถ”์—ˆ์œผ๋ฏ€๋กœ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ค‘์ ์„ ๋‘๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 1. **์ปดํฌ๋„ŒํŠธ์˜ ์—ฐ์‡„์ ์ธ ๋ฆฌ๋ Œ๋”๋ง ๊ฑด๋„ˆ๋›ฐ๊ธฐ** - * `<Parent />`๋ฅผ ๋ฆฌ๋ Œ๋”๋งํ•˜๋ฉด `<Parent />`๋งŒ์ด ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ทธ ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ ๋‚ด์˜ ๋งŽ์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง๋˜๋Š” ๊ฒฝ์šฐ + * `<Parent />`๋ฅผ ๋ฆฌ๋ Œ๋”๋งํ•˜๋ฉด `<Parent />`๋งŒ์ด ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ทธ ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ ๋‚ด์˜ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง๋˜๋Š” ๊ฒฝ์šฐ. 2. **React ์™ธ๋ถ€์—์„œ์˜ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ณ„์‚ฐ ๊ฑด๋„ˆ๋›ฐ๊ธฐ** - * ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook ๋‚ด์—์„œ `expensivelyProcessAReallyLargeArrayOfObjects()`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ + * ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook ๋‚ด์—์„œ `expensivelyProcessAReallyLargeArrayOfObjects()`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ. #### ๋ฆฌ๋ Œ๋”๋ง ์ตœ์ ํ™” {/*optimizing-re-renders*/} -React๋Š” props, state, context์™€ ๊ฐ™์€ ํ˜„์žฌ state์— ๋Œ€ํ•œ ํ•จ์ˆ˜๋กœ UI๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. `useMemo()`, `useCallback()`, `React.memo()`๋กœ ์ˆ˜๋™ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ์šฉํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ํ˜„์žฌ ๊ตฌํ˜„์—์„œ ์ปดํฌ๋„ŒํŠธ์˜ state๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด, React๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์™€ _ํ•˜์œ„ ๋ชจ๋“  ์ž์‹ ์ปดํฌ๋„ŒํŠธ_ ๋ฅผ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ์˜ˆ์‹œ์—์„œ๋Š” `<FriendList>`์˜ state๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค `<MessageButton>`์ด ๋ฆฌ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. +React๋Š” Props, State, Context์™€ ๊ฐ™์€ ํ˜„์žฌ State์— ๋Œ€ํ•œ ํ•จ์ˆ˜๋กœ UI๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. `useMemo()`, `useCallback()`, ๋˜๋Š” `React.memo()`๋กœ ์ˆ˜๋™ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ์šฉํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ํ˜„์žฌ ๊ตฌํ˜„์—์„œ ์ปดํฌ๋„ŒํŠธ์˜ State๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด, React๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์™€ <em>ํ•˜์œ„ ๋ชจ๋“  ์ž์‹ ์ปดํฌ๋„ŒํŠธ</em>๋ฅผ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ์˜ˆ์‹œ์—์„œ๋Š” `<FriendList>`์˜ State๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค `<MessageButton>`์ด ๋ฆฌ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. ```javascript function FriendList({ friends }) { @@ -110,21 +86,21 @@ function FriendList({ friends }) { ); } ``` -[_React ์ปดํŒŒ์ผ๋Ÿฌ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ์—์„œ ์ด ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”_](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEAYjHgpgCYAyeYOAFMEWuZVWEQL4CURwADrEicQgyKEANnkwIAwtEw4iAXiJQwCMhWoB5TDLmKsTXgG5hRInjRFGbXZwB0UygHMcACzWr1ABn4hEWsYBBxYYgAeADkIHQ4uAHoAPksRbisiMIiYYkYs6yiqPAA3FMLrIiiwAAcAQ0wU4GlZBSUcbklDNqikusaKkKrgR0TnAFt62sYHdmp+VRT7SqrqhOo6Bnl6mCoiAGsEAE9VUfmqZzwqLrHqM7ubolTVol5eTOGigFkEMDB6u4EAAhKA4HCEZ5DNZ9ErlLIWYTcEDcIA) +[_React ์ปดํŒŒ์ผ๋Ÿฌ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ์—์„œ ์ด ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”_](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEAYjHgpgCYAyeYOAFMEWuZVWEQL4CURwADrEicQgyKEANnkwIAwtEw4iAXiJQwCMhWoB5TDLmKsTXgG5hRInjRFGbXZwB0UygHMcACzWr1ABn4hEWsYBBxYYgAeADkIHQ4uAHoAPksRbisiMIiYYkYs6yiqPAA3FMLrIiiwAAcAQ0wU4GlZBSUcbklDNqikusaKkKrgR0TnAFt62sYHdmp+VRT7SqrqhOo6Bnl6mCoiAGsEAE9VUfmqZzwqLrHqM7ubolTVol5eTOGigFkEMDB6u4EAAhKA4HCEZ5DNZ9ErlLIWYTcEDcIA). -React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ƒํƒœ ๋ณ€๊ฒฝ ์‹œ ์•ฑ์—์„œ ๊ด€๋ จ๋œ ๋ถ€๋ถ„๋งŒ ๋ฆฌ๋ Œ๋”๋ง๋˜๋„๋ก ์ˆ˜๋™ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๊ณผ ๋™๋“ฑํ•œ ๊ธฐ๋Šฅ์„ ์ž๋™์œผ๋กœ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ "์„ธ๋ถ„ํ™”๋œ ๋ฐ˜์‘์„ฑ(fine-grained reactivity)"์ด๋ผ๊ณ ๋„ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์‹œ์—์„œ React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” `friends`๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ `<FriendListCard />`์˜ ๋ฐ˜ํ™˜ ๊ฐ’์ด ์žฌ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Œ์„ ๊ฒฐ์ •ํ•˜๊ณ , JSX๋ฅผ ์žฌ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  `<MessageButton>`์˜ ๋ฆฌ๋ Œ๋”๋ง๋„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ƒํƒœ ๋ณ€๊ฒฝ ์‹œ ์•ฑ์—์„œ ๊ด€๋ จ๋œ ๋ถ€๋ถ„๋งŒ ๋ฆฌ๋ Œ๋”๋ง๋˜๋„๋ก ์ˆ˜๋™ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๊ณผ ๋™๋“ฑํ•œ ๊ธฐ๋Šฅ์„ ์ž๋™์œผ๋กœ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ "์„ธ๋ถ„ํ™”๋œ ๋ฐ˜์‘์„ฑ<sup>Fine-Grained Reactivity</sup>"์ด๋ผ๊ณ ๋„ ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์œ„ ์˜ˆ์‹œ์—์„œ React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” `friends`๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ `<FriendListCard />`์˜ ๋ฐ˜ํ™˜ ๊ฐ’์ด ์žฌ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Œ์„ ๊ฒฐ์ •ํ•˜๊ณ , JSX๋ฅผ ์žฌ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  `<MessageButton>`์˜ ๋ฆฌ๋ Œ๋”๋ง๋„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #### ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ณ„์‚ฐ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ {/*expensive-calculations-also-get-memoized*/} ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ Œ๋”๋ง ๋„์ค‘ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ณ„์‚ฐ์— ๋Œ€ํ•ด ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ```js -// ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— React ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด **๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค** +// ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— React ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด **๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** function expensivelyProcessAReallyLargeArrayOfObjects() { /* ... */ } -// ์ปดํฌ๋„ŒํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— React ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋ฉ๋‹ˆ๋‹ค +// ์ปดํฌ๋„ŒํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— React ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋ฉ๋‹ˆ๋‹ค. function TableContainer({ items }) { - // ์ด ํ•จ์ˆ˜ ํ˜ธ์ถœ์€ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค + // ์ด ํ•จ์ˆ˜ ํ˜ธ์ถœ์€ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. const data = expensivelyProcessAReallyLargeArrayOfObjects(items); // ... } @@ -133,78 +109,31 @@ function TableContainer({ items }) { ๊ทธ๋Ÿฌ๋‚˜ `expensivelyProcessAReallyLargeArrayOfObjects`๊ฐ€ ์‹ค์ œ๋กœ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ํ•จ์ˆ˜๋ผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ React ์™ธ๋ถ€์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜์˜ ๋ณ„๋„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ๊ณ ๋ คํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -- React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React ์ปดํฌ๋„ŒํŠธ์™€ Hooks๋งŒ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜๋ฉฐ, ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -- React ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋‚˜ Hooks ์‚ฌ์ด์—์„œ ๊ณต์œ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +- React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React ์ปดํฌ๋„ŒํŠธ์™€ Hook๋งŒ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜๋ฉฐ, ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +- React ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook ์‚ฌ์ด์—์„œ ๊ณต์œ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ `expensivelyProcessAReallyLargeArrayOfObjects`๊ฐ€ ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค๋ฉด ๋™์ผํ•œ ์•„์ดํ…œ์ด ์ „๋‹ฌ๋˜๋”๋ผ๋„ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ณ„์‚ฐ์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๋” ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์ „์— ๋จผ์ € [ํ”„๋กœํŒŒ์ผ๋ง](/reference/react/useMemo#how-to-tell-if-a-calculation-is-expensive)์„ ํ†ตํ•ด ํ•ด๋‹น ๊ณ„์‚ฐ์ด ์‹ค์ œ๋กœ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. </DeepDive> -<<<<<<< HEAD -### ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฌด์—‡์„ ๊ฐ€์ •ํ•˜๋‚˜์š”? {/*what-does-the-compiler-assume*/} - -React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. - -1. ์˜ฌ๋ฐ”๋ฅด๊ณ  ์˜๋ฏธ ์žˆ๋Š” JavaScript ์ฝ”๋“œ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -2. nullable/optional ๊ฐ’๊ณผ ์†์„ฑ์— ์ ‘๊ทผํ•˜๊ธฐ ์ „์— ๊ทธ ๊ฐ’์ด ์ •์˜๋˜์–ด ์žˆ๋Š”์ง€ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค. TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ [`strictNullChecks`](https://www.typescriptlang.org/ko/tsconfig/#strictNullChecks)์„ ํ™œ์„ฑํ™”ํ•˜์—ฌ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `if (object.nullableProperty) { object.nullableProperty.foo }`์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜, ์˜ต์…”๋„ ์ฒด์ด๋‹์„ ์‚ฌ์šฉํ•˜์—ฌ `object.nullableProperty?.foo`์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. -3. [React์˜ ๊ทœ์น™](/reference/rules)์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. - -React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React์˜ ๋งŽ์€ ๊ทœ์น™์„ ์ •์ ์œผ๋กœ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์—๋Ÿฌ๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ์•ˆ์ „ํ•˜๊ฒŒ ์ปดํŒŒ์ผ์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด [`eslint-plugin-react-compiler`](https://www.npmjs.com/package/eslint-plugin-react-compiler)์˜ ์„ค์น˜๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. - ### ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹œ๋„ํ•ด ๋ด์•ผ ํ•˜๋‚˜์š”? {/*should-i-try-out-the-compiler*/} ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์—ฌ์ „ํžˆ ์‹คํ—˜์ ์ด๋ฉฐ ๋‹ค์–‘ํ•œ ๊ฒฐํ•จ์ด ์žˆ๋‹ค๋Š” ์ ์„ ์œ ์˜ํ•˜์„ธ์š”. Meta์™€ ๊ฐ™์€ ํšŒ์‚ฌ์—์„œ๋Š” ์ด๋ฏธ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜์˜€์ง€๋งŒ, ์•ฑ์˜ ํ”„๋กœ๋•์…˜์— ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์ ์ง„์ ์œผ๋กœ ๋„์ž…ํ• ์ง€๋Š” ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๊ฑด๊ฐ• ์ƒํƒœ์™€ [React์˜ ๊ทœ์น™](/reference/rules)์„ ์–ผ๋งˆ๋‚˜ ์ž˜ ๋”ฐ๋ž๋Š”์ง€์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -======= -### Should I try out the compiler? {/*should-i-try-out-the-compiler*/} - -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). ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 -**์ง€๊ธˆ ๋‹น์žฅ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ์— ๊ธ‰๊ธ‰ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์ฆˆ์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.** ํ•˜์ง€๋งŒ ์•ฑ์—์„œ ์ž‘์€ ์‹คํ—˜์„ ํ†ตํ•ด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹œ๋„ํ•ด ๋ณด๊ณ  [ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณต](#reporting-issues)ํ•˜์—ฌ ์ปดํŒŒ์ผ๋Ÿฌ ๊ฐœ์„ ์— ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +**์ง€๊ธˆ ๋‹น์žฅ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ์— ๊ธ‰๊ธ‰ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์ฆˆ์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.** ํ•˜์ง€๋งŒ ์•ฑ์—์„œ์˜ ์ž‘์€ ์‹คํ—˜์„ ํ†ตํ•ด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹œ๋„ํ•ด ๋ณด๊ณ  [ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณต](#reporting-issues)ํ•˜์—ฌ ์ปดํŒŒ์ผ๋Ÿฌ ๊ฐœ์„ ์— ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ์‹œ์ž‘ํ•˜๊ธฐ {/*getting-started*/} -์ด ๋ฌธ์„œ ์™ธ์—๋„ [React ์ปดํŒŒ์ผ๋Ÿฌ ์›Œํ‚น ๊ทธ๋ฃน](https://github.com/reactwg/react-compiler)์„ ํ™•์ธํ•˜์—ฌ ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด์™€ ๋…ผ์˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. - -<<<<<<< HEAD -### ํ˜ธํ™˜์„ฑ ํ™•์ธ {/*checking-compatibility*/} - -์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์„ค์น˜ํ•˜๊ธฐ ์ „์—, ๋จผ์ € ์ฝ”๋“œ๋ฒ ์ด์Šค๊ฐ€ ํ˜ธํ™˜๋˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -<TerminalBlock> -npx react-compiler-healthcheck@experimental -</TerminalBlock> - -์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค์Œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. - -- ์„ฑ๊ณต์ ์œผ๋กœ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ ์ˆ˜ ํ™•์ธ: ์ˆซ์ž๊ฐ€ ๋†’์„์ˆ˜๋ก ์ข‹์Šต๋‹ˆ๋‹ค. -- `<StrictMode>` ์‚ฌ์šฉ ์—ฌ๋ถ€ ํ™•์ธ: ์ด๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ณ  ์ค€์ˆ˜ํ•  ๊ฒฝ์šฐ [React์˜ ๊ทœ์น™](/reference/rules)์„ ์ž˜ ๋”ฐ๋ฅด๋Š” ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. -- ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ์—ฌ๋ถ€ ํ™•์ธ: ์•Œ๋ ค์ง„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. - -์˜ˆ์‹œ: - -<TerminalBlock> -Successfully compiled 8 out of 9 components. -StrictMode usage not found. -Found no usage of incompatible libraries. -</TerminalBlock> +ํ˜„์žฌ ๋ฌธ์„œ ์™ธ์—๋„ [React ์ปดํŒŒ์ผ๋Ÿฌ ์›Œํ‚น ๊ทธ๋ฃน](https://github.com/reactwg/react-compiler)์„ ํ™•์ธํ•˜์—ฌ ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด์™€ ๋…ผ์˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ### `eslint-plugin-react-compiler` ์„ค์น˜ {/*installing-eslint-plugin-react-compiler*/} -React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” eslint ํ”Œ๋Ÿฌ๊ทธ์ธ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. eslint ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์ปดํŒŒ์ผ๋Ÿฌ์™€ **๋…๋ฆฝ์ ์œผ๋กœ** ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„ eslint ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -======= -### 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. ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์ปดํŒŒ์ผ๋Ÿฌ์™€ **๋…๋ฆฝ์ ์œผ๋กœ** ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„ ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <TerminalBlock> npm install -D eslint-plugin-react-compiler@beta </TerminalBlock> -<<<<<<< HEAD -๊ทธ๋Ÿฐ ๋‹ค์Œ, eslint ๊ตฌ์„ฑ ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•˜์„ธ์š”. -======= -Then, add it to your ESLint config: +๊ทธ๋Ÿฐ ๋‹ค์Œ, ESLint ์„ค์ •<sup>Config</sup> ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•˜์„ธ์š”. ```js import reactCompiler from 'eslint-plugin-react-compiler' @@ -222,7 +151,6 @@ export default [ ``` Or, in the deprecated eslintrc config format: ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 ```js module.exports = { @@ -235,24 +163,19 @@ module.exports = { } ``` -<<<<<<< HEAD -eslint ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์—๋””ํ„ฐ์—์„œ React ๊ทœ์น™ ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์˜ ์ตœ์ ํ™”๋ฅผ ๊ฑด๋„ˆ๋›ฐ์—ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์™„์ „ํžˆ ์ •์ƒ์ ์ธ ๋™์ž‘์ด๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด๋ฅผ ๋ณต๊ตฌํ•˜๊ณ  ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ณ„์†ํ•ด์„œ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -**๋ชจ๋“  eslint ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ์ฆ‰์‹œ ์ˆ˜์ •ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.** ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ํ•ด๊ฒฐํ•˜๋ฉด์„œ ์ตœ์ ํ™”๋˜๋Š” ์ปดํฌ๋„ŒํŠธ์™€ Hooks์˜ ์ˆ˜๋ฅผ ๋Š˜๋ฆด ์ˆ˜ ์žˆ์ง€๋งŒ, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋ชจ๋“  ๊ฒƒ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. -======= -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. +ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์—๋””ํ„ฐ์—์„œ React์˜ ๊ทœ์น™ ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์˜ ์ตœ์ ํ™”๋ฅผ ๊ฑด๋„ˆ๋›ฐ์—ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์™„์ „ํžˆ ์ •์ƒ์ ์ธ ๋™์ž‘์ด๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด๋ฅผ ๋ณต๊ตฌํ•˜๊ณ  ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ณ„์†ํ•ด์„œ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <Note> -**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. +**๋ชจ๋“  eslint ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ์ฆ‰์‹œ ์ˆ˜์ •ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.** ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ํ•ด๊ฒฐํ•˜๋ฉด์„œ ์ตœ์ ํ™”๋˜๋Š” ์ปดํฌ๋„ŒํŠธ์™€ Hook์˜ ์ˆ˜๋ฅผ ๋Š˜๋ฆด ์ˆ˜ ์žˆ์ง€๋งŒ, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋ชจ๋“  ๊ฒƒ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. </Note> ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 ### ์ฝ”๋“œ๋ฒ ์ด์Šค์— ์ปดํŒŒ์ผ๋Ÿฌ ์ ์šฉํ•˜๊ธฐ {/*using-the-compiler-effectively*/} #### ๊ธฐ์กด ํ”„๋กœ์ ํŠธ {/*existing-projects*/} -์ปดํŒŒ์ผ๋Ÿฌ๋Š” [React์˜ ๊ทœ์น™](/reference/rules)์„ ๋”ฐ๋ฅด๋Š” ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์™€ Hooks๋ฅผ ์ปดํŒŒ์ผํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๋Ÿฌํ•œ ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•˜๋Š” ์ฝ”๋“œ๋„ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋‚˜ Hooks๋ฅผ ๊ฑด๋„ˆ๋›ฐ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ JavaScript์˜ ์œ ์—ฐํ•œ ํŠน์„ฑ์œผ๋กœ ์ธํ•ด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ์žก์•„๋‚ด์ง€๋Š” ๋ชปํ•˜๋ฉฐ, ๊ฐ€๋” ๊ฑฐ์ง“ ์–‘์„ฑ(false positive)์œผ๋กœ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React์˜ ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์„ ์‹ค์ˆ˜๋กœ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์–ด ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘์œผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋”ฐ๋ผ์„œ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๋„์ž…ํ•˜๋ ค๋ฉด, ๋จผ์ € ์ œํ’ˆ ์ฝ”๋“œ์˜ ์ž‘์€ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ์‹คํ–‰ํ•ด ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํŠน์ • ๋””๋ ‰ํ„ฐ๋ฆฌ ์„ธํŠธ์—์„œ๋งŒ ์‹คํ–‰ํ•˜๋„๋ก ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ปดํŒŒ์ผ๋Ÿฌ๋Š” [React์˜ ๊ทœ์น™](/reference/rules)์„ ๋”ฐ๋ฅด๋Š” ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์™€ Hook์„ ์ปดํŒŒ์ผํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๋Ÿฌํ•œ ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•˜๋Š” ์ฝ”๋“œ๋„ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์„ ๊ฑด๋„ˆ๋›ฐ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์œ ์—ฐํ•œ ํŠน์„ฑ์œผ๋กœ ์ธํ•ด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ์žก์•„๋‚ด์ง€๋Š” ๋ชปํ•˜๋ฉฐ, ๊ฐ€๋” ๊ฑฐ์ง“ ์Œ์„ฑ<sup>False Negatives</sup>์œผ๋กœ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React์˜ ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์„ ์‹ค์ˆ˜๋กœ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์–ด ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘์œผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๋”ฐ๋ผ์„œ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๋„์ž…ํ•˜๋ ค๋ฉด, ๋จผ์ € ์ œํ’ˆ ์ฝ”๋“œ์˜ ์ž‘์€ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ์‹คํ–‰ํ•ด ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํŠน์ • ๋””๋ ‰ํ† ๋ฆฌ ์ง‘ํ•ฉ<sup>Set</sup>์—์„œ๋งŒ ์‹คํ–‰ํ•˜๋„๋ก ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {3} const ReactCompilerConfig = { @@ -262,33 +185,12 @@ const ReactCompilerConfig = { }; ``` -<<<<<<< HEAD -๋“œ๋ฌผ์ง€๋งŒ ๋•Œ์— ๋”ฐ๋ผ์„œ๋Š” `compilationMode: "annotation"` ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ "opt-in" ๋ชจ๋“œ๋กœ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“œ์—์„œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ `"use memo"` ์ง€์‹œ์–ด๋กœ ์ฃผ์„ ์ฒ˜๋ฆฌ๋œ ์ปดํฌ๋„ŒํŠธ์™€ Hooks๋งŒ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. `annotation` ๋ชจ๋“œ๋Š” ์ดˆ๊ธฐ ์‚ฌ์šฉ์ž๋ฅผ ๋•๊ธฐ ์œ„ํ•œ ์ž„์‹œ ๋ชจ๋“œ๋กœ, `"use memo"` ์ง€์‹œ์–ด๋ฅผ ์žฅ๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์˜๋„๋Š” ์—†์Œ์„ ์œ ์˜ํ•˜์„ธ์š”. - -```js {2,7} -const ReactCompilerConfig = { - compilationMode: "annotation", -}; - -// src/app.jsx -export default function App() { - "use memo"; - // ... -} -``` - ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜๋Š” ๋ฐ ๋” ์ž์‹ ๊ฐ์„ ๊ฐ€์ง€๊ฒŒ ๋˜๋ฉด, ๋‹ค๋ฅธ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋Œ€ํ•œ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ํ™•๋Œ€ํ•˜๊ณ  ์ ์ง„์ ์œผ๋กœ ์ „์ฒด ์•ฑ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -======= -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. ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 #### ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ {/*new-projects*/} -์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•  ๊ฒฝ์šฐ, ๊ธฐ๋ณธ ๋™์ž‘์œผ๋กœ ์ „์ฒด ์ฝ”๋“œ๋ฒ ์ด์Šค์— ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•  ๊ฒฝ์šฐ, ๊ธฐ๋ณธ ๋™์ž‘์œผ๋กœ ์ „์ฒด ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -<<<<<<< HEAD -## ์‚ฌ์šฉ ๋ฐฉ๋ฒ• {/*installation*/} -======= ### 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. @@ -325,7 +227,6 @@ Library code can often require more complex patterns and usage of escape hatches 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*/} ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 ### Babel {/*usage-with-babel*/} @@ -335,7 +236,7 @@ npm install babel-plugin-react-compiler@beta ์ปดํŒŒ์ผ๋Ÿฌ์—๋Š” ๋นŒ๋“œ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. -์„ค์น˜ ํ›„์— Babel ๊ตฌ์„ฑ ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•˜์„ธ์š”. ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ **๋จผ์ €** ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. +์„ค์น˜ ํ›„ Babel ์„ค์ •<sup>Config</sup> ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•˜์„ธ์š”. ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ **๋จผ์ €** ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ```js {7} // babel.config.js @@ -351,7 +252,7 @@ module.exports = function () { }; ``` -`babel-plugin-react-compiler`๋Š” ๋‹ค๋ฅธ Babel ํ”Œ๋Ÿฌ๊ทธ์ธ๋ณด๋‹ค ๋จผ์ € ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์‚ฌ์šด๋“œ ๋ถ„์„(sound analysis)์„ ์œ„ํ•ด ์ž…๋ ฅ ์†Œ์Šค ์ •๋ณด๋ฅผ ํ•„์š”๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +`babel-plugin-react-compiler`๋Š” ๋‹ค๋ฅธ Babel ํ”Œ๋Ÿฌ๊ทธ์ธ๋ณด๋‹ค ๋จผ์ € ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์‚ฌ์šด๋“œ ๋ถ„์„<sup>Sound Analysis</sup>์„ ์œ„ํ•ด ์ž…๋ ฅ ์†Œ์Šค ์ •๋ณด๋ฅผ ํ•„์š”๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ### Vite {/*usage-with-vite*/} @@ -379,40 +280,7 @@ export default defineConfig(() => { ### Next.js {/*usage-with-nextjs*/} -<<<<<<< HEAD -Next.js์—๋Š” React ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” ์‹คํ—˜์ ์ธ ๊ตฌ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌ์„ฑ์€ ์ž๋™์œผ๋กœ Babel์ด `babel-plugin-react-compiler`์™€ ํ•จ๊ป˜ ์„ค์ •๋˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. - -- React 19 ๋ฆด๋ฆฌ์ฆˆ ํ›„๋ณด ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” Next.js ์นด๋‚˜๋ฆฌ(Canary) ๋ฒ„์ „์„ ์„ค์น˜ํ•˜์„ธ์š”. -- `babel-plugin-react-compiler`๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”. - -<TerminalBlock> -npm install next@canary babel-plugin-react-compiler@experimental -</TerminalBlock> - -๊ทธ๋Ÿฐ ๋‹ค์Œ `next.config.js`์—์„œ ์‹คํ—˜์  ์˜ต์…˜์„ ์„ค์ •ํ•˜์„ธ์š”. - -```js {4,5,6} -// next.config.js -/** @type {import('next').NextConfig} */ -const nextConfig = { - experimental: { - reactCompiler: true, - }, -}; - -module.exports = nextConfig; -``` - -์‹คํ—˜์  ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด React ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์ง€์›์„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณณ์—์„œ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. - -- ์•ฑ ๋ผ์šฐํ„ฐ (App Router) -- ํŽ˜์ด์ง€ ๋ผ์šฐํ„ฐ (Pages Router) -- Webpack (๊ธฐ๋ณธ) -- Turbopack (`--turbo` ์˜ต์…˜์„ ํ†ตํ•ด ํ™œ์„ฑํ™”) - -======= Please refer to the [Next.js docs](https://nextjs.org/docs/app/api-reference/next-config-js/reactCompiler) for more information. ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 ### Remix {/*usage-with-remix*/} `vite-plugin-babel`์„ ์„ค์น˜ํ•˜๊ณ  ์ปดํŒŒ์ผ๋Ÿฌ์˜ Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”. @@ -433,7 +301,7 @@ export default defineConfig({ babel({ filter: /\.[jt]sx?$/, babelConfig: { - presets: ["@babel/preset-typescript"], // TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ + presets: ["@babel/preset-typescript"], // TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ. plugins: [ ["babel-plugin-react-compiler", ReactCompilerConfig], ], @@ -445,52 +313,11 @@ export default defineConfig({ ### Webpack {/*usage-with-webpack*/} -<<<<<<< HEAD -๋‹ค์Œ๊ณผ ๊ฐ™์ด React ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์œ„ํ•œ ์ž์ฒด ๋กœ๋”๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -```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; -``` - -### Expo {/*usage-with-expo*/} - -Expo ์•ฑ์—์„œ React Compiler ๋ฅผ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” [Expo's docs](https://docs.expo.dev/preview/react-compiler/) ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. -======= A community Webpack loader is [now available here](https://github.com/SukkaW/react-compiler-webpack). ### Expo {/*usage-with-expo*/} Please refer to [Expo's docs](https://docs.expo.dev/guides/react-compiler/) to enable and use the React Compiler in Expo apps. ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 ### Metro (React Native) {/*usage-with-react-native-metro*/} @@ -498,55 +325,39 @@ React Native๋Š” Metro๋ฅผ ํ†ตํ•ด Babel์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์„ค์น˜ ์ง€์นจ์€ [Babel ### Rspack {/*usage-with-rspack*/} -Rspack ์•ฑ์—์„œ React Compiler ๋ฅผ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” [Rspack's docs](https://rspack.dev/guide/tech/react#react-compiler) ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. +Rspack ์•ฑ์—์„œ React ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” [Rspack's docs](https://rspack.dev/guide/tech/react#react-compiler)๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. ### Rsbuild {/*usage-with-rsbuild*/} -Rsbuild ์•ฑ์—์„œ React Compiler ๋ฅผ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” [Rsbuild's docs](https://rsbuild.dev/guide/framework/react#react-compiler) ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. +Rsbuild ์•ฑ์—์„œ React ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” [Rsbuild's docs](https://rsbuild.dev/guide/framework/react#react-compiler)๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. ## Troubleshooting {/*troubleshooting*/} ๋ฌธ์ œ๋ฅผ ๋ณด๊ณ ํ•˜๋ ค๋ฉด ๋จผ์ € [React ์ปดํŒŒ์ผ๋Ÿฌ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ](https://playground.react.dev/)์—์„œ ์ตœ์†Œํ•œ์˜ ์žฌํ˜„ ์‚ฌ๋ก€๋ฅผ ๋งŒ๋“ค์–ด ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ์— ํฌํ•จํ•˜์„ธ์š”. [facebook/react](https://github.com/facebook/react/issues) ์ €์žฅ์†Œ์—์„œ ์ด์Šˆ๋ฅผ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -React ์ปดํŒŒ์ผ๋Ÿฌ ์›Œํ‚น ๊ทธ๋ฃน์—์„œ๋„ ํšŒ์›์œผ๋กœ ์‹ ์ฒญํ•˜์—ฌ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [๊ฐ€์ž…์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ README](https://github.com/reactwg/react-compiler)์—์„œ ํ™•์ธํ•˜์„ธ์š”. - -<<<<<<< HEAD -### `(0 , _c) is not a function` ์—๋Ÿฌ {/*0--_c-is-not-a-function-error*/} +React ์ปดํŒŒ์ผ๋Ÿฌ ์›Œํ‚น ๊ทธ๋ฃน์—์„œ๋„ ํšŒ์›์œผ๋กœ ์ง€์›ํ•˜์—ฌ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [๊ฐ€์ž…์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ README](https://github.com/reactwg/react-compiler)์—์„œ ํ™•์ธํ•˜์„ธ์š”. -์ด ์—๋Ÿฌ๋Š” React 19 RC ์ด์ƒ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๋จผ์ € [React 19 RC๋กœ ์•ฑ์„ ์—…๊ทธ๋ ˆ์ด๋“œ](/blog/2024/04/25/react-19-upgrade-guide)ํ•˜์„ธ์š”. - -React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ, [์›Œํ‚น ๊ทธ๋ฃน](https://github.com/reactwg/react-compiler/discussions/6)์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ์บ์‹œ ํ•จ์ˆ˜ ๊ตฌํ˜„์„ ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ€๋Šฅํ•˜๋ฉด React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. -======= -### What does the compiler assume? {/*what-does-the-compiler-assume*/} +### ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฌด์—‡์„ ๊ฐ€์ •ํ•˜๋‚˜์š”? {/*what-does-the-compiler-assume*/} -React Compiler assumes that your code: +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. -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). +1. ์˜ฌ๋ฐ”๋ฅด๊ณ  ์˜๋ฏธ ์žˆ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +2. nullable/optional ๊ฐ’๊ณผ ์†์„ฑ์— ์ ‘๊ทผํ•˜๊ธฐ ์ „์— ๊ทธ ๊ฐ’์ด ์ •์˜๋˜์–ด ์žˆ๋Š”์ง€ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ [`strictNullChecks`](https://www.typescriptlang.org/ko/tsconfig/#strictNullChecks)์„ ํ™œ์„ฑํ™”ํ•˜์—ฌ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, `if (object.nullableProperty) { object.nullableProperty.foo }`์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜, ์˜ต์…”๋„ ์ฒด์ด๋‹<sup>Optional Chaning</sup>์„ ์‚ฌ์šฉํ•˜์—ฌ `object.nullableProperty?.foo`์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. +3. [React์˜ ๊ทœ์น™](/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). ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React์˜ ๋งŽ์€ ๊ทœ์น™์„ ์ •์ ์œผ๋กœ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์—๋Ÿฌ๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ์•ˆ์ „ํ•˜๊ฒŒ ์ปดํŒŒ์ผ์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด [`eslint-plugin-react-compiler`](https://www.npmjs.com/package/eslint-plugin-react-compiler)์˜ ์„ค์น˜๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ### ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ตœ์ ํ™”๋˜์—ˆ๋Š”์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ์š”? {/*how-do-i-know-my-components-have-been-optimized*/} [React Devtools](/learn/react-developer-tools) (v5.0+)์—๋Š” React ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋‚ด์žฅ ์ง€์›ํ•˜๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ตœ์ ํ™”๋œ ์ปดํฌ๋„ŒํŠธ ์˜†์— "Memo โœจ" ๋ฐฐ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. -<<<<<<< HEAD ### ์ปดํŒŒ์ผ ํ›„ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ {/*something-is-not-working-after-compilation*/} -`eslint-plugin-react-compiler`์„ ์„ค์น˜ํ•œ ๊ฒฝ์šฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์—๋””ํ„ฐ์—์„œ React ๊ทœ์น™ ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์˜ ์ตœ์ ํ™”๋ฅผ ๊ฑด๋„ˆ๋›ฐ์—ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์™„์ „ํžˆ ์ •์ƒ์ ์ธ ๋™์ž‘์ด๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด๋ฅผ ๋ณต๊ตฌํ•˜๊ณ  ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ณ„์†ํ•ด์„œ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **๋ชจ๋“  eslint ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ์ฆ‰์‹œ ์ˆ˜์ •ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.** ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ํ•ด๊ฒฐํ•˜๋ฉด์„œ ์ตœ์ ํ™”๋˜๋Š” ์ปดํฌ๋„ŒํŠธ์™€ Hooks์˜ ์ˆ˜๋ฅผ ์ ์ง„์ ์œผ๋กœ ๋Š˜๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -======= -### 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. ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 -๊ทธ๋Ÿฌ๋‚˜ JavaScript์˜ ์œ ์—ฐํ•˜๊ณ  ๋™์ ์ธ ํŠน์„ฑ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ์ฒ ์ €ํ•˜๊ฒŒ ๊ฐ์ง€ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌ๋ฉด ๋ฒ„๊ทธ๋‚˜ ๋ฌดํ•œ ๋ฃจํ”„์™€ ๊ฐ™์€ ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`eslint-plugin-react-compiler`์„ ์„ค์น˜ํ•œ ๊ฒฝ์šฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์—๋””ํ„ฐ์—์„œ React ๊ทœ์น™ ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์˜ ์ตœ์ ํ™”๋ฅผ ๊ฑด๋„ˆ๋›ฐ์—ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์™„์ „ํžˆ ์ •์ƒ์ ์ธ ๋™์ž‘์ด๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด๋ฅผ ๋ณต๊ตฌํ•˜๊ณ  ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ณ„์†ํ•ด์„œ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **๋ชจ๋“  ESLint ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ์ฆ‰์‹œ ์ˆ˜์ •ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.** ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ํ•ด๊ฒฐํ•˜๋ฉด์„œ ์ตœ์ ํ™”๋˜๋Š” ์ปดํฌ๋„ŒํŠธ์™€ Hooks์˜ ์ˆ˜๋ฅผ ์ ์ง„์ ์œผ๋กœ ๋Š˜๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฌ๋‚˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์œ ์—ฐํ•˜๊ณ  ๋™์ ์ธ ํŠน์„ฑ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ์ฒ ์ €ํ•˜๊ฒŒ ๊ฐ์ง€ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌ๋ฉด ๋ฒ„๊ทธ๋‚˜ ๋ฌดํ•œ ๋ฃจํ”„์™€ ๊ฐ™์€ ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -<<<<<<< HEAD -์ปดํŒŒ์ผ ํ›„ ์•ฑ์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๊ณ  eslint ์—๋Ÿฌ๋„ ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ž˜๋ชป ์ปดํŒŒ์ผํ•œ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด ๊ด€๋ จ๋œ ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์„ [`"use no memo"` ์ง€์‹œ์–ด](#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). ->>>>>>> 84f29eb20af17e9c154b9ad71c21af4c9171e4a2 +์ปดํŒŒ์ผ ํ›„ ์•ฑ์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๊ณ  ESLint ์—๋Ÿฌ๋„ ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ž˜๋ชป ์ปดํŒŒ์ผํ•œ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด ๊ด€๋ จ๋œ ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์„ [`"use no memo"` ์ง€์‹œ์–ด](#opt-out-of-the-compiler-for-a-component)๋ฅผ ํ†ตํ•ด ๊ฐ•๋ ฅํ•˜๊ฒŒ ์ œ์™ธํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ด ๋ณด์„ธ์š”. ```js {2} function SuspiciousComponent() { @@ -565,6 +376,6 @@ function SuspiciousComponent() { ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์„ ๋•Œ ์ง€์‹œ์–ด๋ฅผ ์ œ๊ฑฐํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋‹ค์‹œ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. ๊ทธ๋Ÿฐ ๋‹ค์Œ [React ์ปดํŒŒ์ผ๋Ÿฌ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ](https://playground.react.dev)๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ์ตœ์†Œํ•œ์˜ ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์˜ˆ์‹œ๋กœ ๋‹จ์ˆœํ™”ํ•ด ๋ณด๊ฑฐ๋‚˜, ์˜คํ”ˆ ์†Œ์Šค ์ฝ”๋“œ๋ผ๋ฉด ์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋ถ™์—ฌ ๋„ฃ์–ด ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ๋ฅผ ๊ณต์œ ํ•ด์ฃผ์„ธ์š”. ์ด๋ฅผ ํ†ตํ•ด ๋ฌธ์ œ๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ๋„์›€์„ ๋“œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -### ๊ธฐํƒ€ ๋ฌธ์ œ {/*other-issues*/} +### ์ด์™ธ์˜ ๋ฌธ์ œ {/*other-issues*/} -์ž์„ธํ•œ ๋‚ด์šฉ์€ https://github.com/reactwg/react-compiler/discussions/7 ๋ฅผ ์ฐธ์กฐํ•ด ์ฃผ์„ธ์š”. +์ž์„ธํ•œ ๋‚ด์šฉ์€ https://github.com/reactwg/react-compiler/discussions/7 ์„ ์ฐธ์กฐํ•ด ์ฃผ์„ธ์š”. From c4514bd2a55e56306f078c628af4695aaeddb572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 01:31:42 +0900 Subject: [PATCH 0343/1059] chore: add missing newline --- public/.well-known/atproto-did | 2 +- src/content/blog/2024/10/21/react-compiler-beta-release.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/.well-known/atproto-did b/public/.well-known/atproto-did index ad8b0a36b..a73fe2232 100644 --- a/public/.well-known/atproto-did +++ b/public/.well-known/atproto-did @@ -1 +1 @@ -did:plc:uorpbnp2q32vuvyeruwauyhe \ No newline at end of file +did:plc:uorpbnp2q32vuvyeruwauyhe 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 f5a870b22..ff45fa54d 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 @@ -123,4 +123,4 @@ Thanks to [Sathya Gunasekaran](https://twitter.com/_gsathya), [Joe Savona](https [^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 +[^3]: After controlling on author tenure, diff length/complexity, and other potential confounding factors. From ea4fc354decc44f79edabf47c196ea20dd31b945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 15:38:46 +0900 Subject: [PATCH 0344/1059] docs: resolve conflict in `README.md` --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index 9512dde59..606d4d9d8 100644 --- a/README.md +++ b/README.md @@ -22,17 +22,10 @@ ### ์‚ฌ์ „ ์ค€๋น„ 1. Git -<<<<<<< HEAD 1. Node: v16.8.0 ์ด์ƒ์˜ ๋ชจ๋“  ๋ฒ„์ „ 1. Yarn v1(`yarn@1.22.22`): [Yarn ์„ค์น˜ ์•ˆ๋‚ด](https://yarnpkg.com/lang/en/docs/install/) ์ฐธ๊ณ  1. ํฌํฌ<sup>Fork</sup>ํ•œ ๊ฐœ์ธ ์ €์žฅ์†Œ 1. ๋กœ์ปฌ์— ํด๋ก <sup>Clone</sup>ํ•œ [ko.react.dev ์ €์žฅ์†Œ](https://github.com/reactjs/ko.react.dev) -======= -1. Node: any version starting with v16.8.0 or greater -1. Yarn: See [Yarn website for installation instructions](https://yarnpkg.com/lang/en/docs/install/) -1. A fork of the repo (for any contributions) -1. A clone of the [react.dev repo](https://github.com/reactjs/react.dev) on your local machine ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ### ์„ค์น˜ From ff21c195c9912a4dcde67ff7d00842afef305465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 15:42:34 +0900 Subject: [PATCH 0345/1059] chore: resolve conflict in `sidebarReference.json` --- src/sidebarReference.json | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/sidebarReference.json b/src/sidebarReference.json index ebe359a75..2e9dfe1eb 100644 --- a/src/sidebarReference.json +++ b/src/sidebarReference.json @@ -304,7 +304,6 @@ "title": "prerenderToNodeStream", "path": "/reference/react-dom/static/prerenderToNodeStream" } - ] }, { @@ -334,23 +333,12 @@ "sectionHeader": "React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ" }, { -<<<<<<< HEAD "title": "์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ", - "path": "/reference/rsc/server-components", - "canary": true - }, - { - "title": "์„œ๋ฒ„ ์•ก์…˜", - "path": "/reference/rsc/server-actions", - "canary": true -======= - "title": "Server Components", "path": "/reference/rsc/server-components" }, { - "title": "Server Functions", - "path": "/reference/rsc/server-functions" ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc + "title": "์„œ๋ฒ„ ์•ก์…˜", + "path": "/reference/rsc/server-actions" }, { "title": "์ง€์‹œ์–ด", From 446273e994d312fbf517a09cf84d58f16a08c382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 15:47:20 +0900 Subject: [PATCH 0346/1059] chore: delete stale names from `CODEOWNERS` --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index eb881b609..b7e5c36c1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @hg-pyun @taehwanno @simsim0709 @gnujoow @b9words @taggon @MaxKim-J @eomttt @lumirlumir +* @hg-pyun @gnujoow @eomttt @lumirlumir From 00d9e6f594f2ccaeeccf1718820862d07568aaf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 16:08:16 +0900 Subject: [PATCH 0347/1059] docs: update `versions.md` --- src/content/versions.md | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/content/versions.md b/src/content/versions.md index 07f53a6f8..33d2ad180 100644 --- a/src/content/versions.md +++ b/src/content/versions.md @@ -1,27 +1,22 @@ --- -title: React Versions +title: React ๋ฒ„์ „ --- <Intro> -[react.dev](https://react.dev)์˜ React ๋ฌธ์„œ๋Š” ์ตœ์‹  ๋ฒ„์ „์˜ React์— ๋Œ€ํ•œ ๋ฌธ์„œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +[ko.react.dev](/)์˜ React ๋ฌธ์„œ๋Š” ์ตœ์‹  ๋ฒ„์ „์˜ React์— ๋Œ€ํ•œ ๋ฌธ์„œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. </Intro> -์ฃผ์š” ๋ฒ„์ „ ๋‚ด์—์„œ ๋ฌธ์„œ๋ฅผ ์ตœ์‹  ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๋ฉฐ ๊ฐ ์†Œ๊ทœ๋ชจ ๋˜๋Š” ํŒจ์น˜ ๋ฒ„์ „์— ๋Œ€ํ•œ ๋ฌธ์„œ๋Š” ๊ฒŒ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์ฃผ์š” ๋ฒ„์ „์ด ์ถœ์‹œ๋˜๋ฉด ์ด์ „ ๋ฒ„์ „์˜ ๋ฌธ์„œ๋Š” `x.react.dev`๋กœ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ [๋ฒ„์ „ ๊ด€๋ฆฌ ์ •์ฑ…](/community/versioning-policy)์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. +์ฃผ<sup>Major, ไธป</sup> ๋ฒ„์ „ ๋‚ด์—์„œ ๋ฌธ์„œ๋ฅผ ์ตœ์‹  ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๋ฉฐ, ๋ถ€<sup>Minor, ้ƒจ</sup> ๋˜๋Š” ์ˆ˜<sup>Patch, ไฟฎ</sup> ๋ฒ„์ „์— ๋Œ€ํ•œ ๋ฌธ์„œ๋Š” ๊ฒŒ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์ฃผ<sup>Major, ไธป</sup> ๋ฒ„์ „์ด ์ถœ์‹œ๋˜๋ฉด ์ด์ „ ๋ฒ„์ „์˜ ๋ฌธ์„œ๋Š” `x.react.dev`๋กœ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ [๋ฒ„์ „ ๊ด€๋ฆฌ ์ •์ฑ…](/community/versioning-policy)์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. -์ด์ „ ์ฃผ์š” ๋ฒ„์ „์˜ ๊ธฐ๋ก์€ ์•„๋ž˜์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด์ „์˜ ์ฃผ<sup>Major, ไธป</sup> ๋ฒ„์ „์— ๋Œ€ํ•œ ๊ธฐ๋ก์€ ์•„๋ž˜์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -<<<<<<< HEAD -## Future versions {/*future-versions*/} -======= -You can find an archive of previous major versions below. -## Latest version: 19.0 {/*latest-version*/} ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +## ์ตœ์‹  ๋ฒ„์ „: 19.0 {/*latest-version*/} - [react.dev](https://react.dev) {/*docs-19*/} -## Previous versions {/*previous-versions*/} +## ์ด์ „ ๋ฒ„์ „ {/*previous-versions*/} - [18.react.dev](https://18.react.dev) {/*docs-18*/} - [17.react.dev](https://17.react.dev) {/*docs-17*/} @@ -32,7 +27,7 @@ You can find an archive of previous major versions below. #### ์ด์ „ ๋ฌธ์„œ๋“ค {/*legacy-docs*/} -2023๋…„, React 18์— ๋Œ€ํ•œ [์ƒˆ๋กœ์šด ๋ฌธ์„œ](/blog/2023/03/16/introducing-react-dev)๋ฅผ [react.dev](https://react.dev)๋กœ ์ถœ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด React 18 ๋ฌธ์„œ๋Š” [legacy.reactjs.org](https://legacy.reactjs.org)์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ„์ „ 17 ์ดํ•˜์˜ ๋ฌธ์„œ๋Š” ๊ธฐ์กด ์‚ฌ์ดํŠธ์— ํ˜ธ์ŠคํŒ…๋ฉ๋‹ˆ๋‹ค. +2023๋…„, React 18์— ๋Œ€ํ•œ [์ƒˆ๋กœ์šด ๋ฌธ์„œ](/blog/2023/03/16/introducing-react-dev)๋ฅผ [react.dev](https://react.dev)๋กœ ์ถœ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์˜ React 18 ๋ฌธ์„œ๋Š” [legacy.reactjs.org](https://legacy.reactjs.org)์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ„์ „ 17 ์ดํ•˜์˜ ๋ฌธ์„œ๋Š” ์ด์ „ ์‚ฌ์ดํŠธ์— ํ˜ธ์ŠคํŒ…๋ฉ๋‹ˆ๋‹ค. React 15 ์ด์ „ ๋ฒ„์ „์˜ ๊ฒฝ์šฐ, [15.react.dev](https://15.react.dev)๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”. @@ -296,12 +291,12 @@ React 15 ์ด์ „ ๋ฒ„์ „์˜ ๊ฒฝ์šฐ, [15.react.dev](https://15.react.dev)๋ฅผ ์ฐธ๊ณ  - [v0.3.1 (May 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#031-may-30-2013) - [v0.3.0 (May 2013)](https://github.com/facebook/react/blob/main/CHANGELOG.md#031-may-30-2013) -### ์ดˆ๊ธฐ ์ปค๋ฐ‹ {/*initial-commit*/} +### ์ตœ์ดˆ์˜ ์ปค๋ฐ‹ {/*initial-commit*/} -React๋Š” 2013๋…„ 5์›” 29์ผ์— ์˜คํ”ˆ์†Œ์Šค๋กœ ๊ณต๊ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ์ปค๋ฐ‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. [`75897c`: ์ตœ์ดˆ ๊ณต๊ฐœ ๋ฆด๋ฆฌ์ฆˆ](https://github.com/facebook/react/commit/75897c2dcd1dd3a6ca46284dd37e13d22b4b16b4) +React๋Š” 2013๋…„ 5์›” 29์ผ์— ์˜คํ”ˆ์†Œ์Šค๋กœ ๊ณต๊ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์ดˆ์˜ ์ปค๋ฐ‹์€ [`75897c`: ์ตœ์ดˆ ๊ณต๊ฐœ ๋ฆด๋ฆฌ์ฆˆ](https://github.com/facebook/react/commit/75897c2dcd1dd3a6ca46284dd37e13d22b4b16b4)์ž…๋‹ˆ๋‹ค. ์ฒซ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๊ธ€์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. [์™œ ์šฐ๋ฆฌ๋Š” React๋ฅผ ๋งŒ๋“ค์—ˆ๋Š”๊ฐ€?](https://legacy.reactjs.org/blog/2013/06/05/why-react.html) -React๋Š” 2013๋…„์— Facebook ์‹œ์• ํ‹€์—์„œ ์˜คํ”ˆ์†Œ์Šค๋กœ ๊ณต๊ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +React๋Š” 2013๋…„์— ํŽ˜์ด์Šค๋ถ<sup>Facebook</sup> ์‹œ์• ํ‹€์—์„œ ์˜คํ”ˆ์†Œ์Šค๋กœ ๊ณต๊ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. <iframe width="560" height="315" src="https://www.youtube.com/embed/XxVg_s8xAms?si=466vSJrnXTn05j9A" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> From 5040d2964481235cd4338a8d80160adebe6243cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 16:53:44 +0900 Subject: [PATCH 0348/1059] docs: update `blog/index.md` --- src/content/blog/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/blog/index.md b/src/content/blog/index.md index da3907b3e..b5bec0f05 100644 --- a/src/content/blog/index.md +++ b/src/content/blog/index.md @@ -4,7 +4,7 @@ title: React ๋ธ”๋กœ๊ทธ <Intro> -์ด ๋ธ”๋กœ๊ทธ๋Š” React ํŒ€์—์„œ ์—…๋ฐ์ดํŠธํ•œ ๋‚ด์šฉ๋“ค์˜ ๊ณต์‹ ์†Œ์Šค์ž…๋‹ˆ๋‹ค. ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ ๋ฐ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ํ‘œํ˜„์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋น„๋กฏํ•˜์—ฌ ์ค‘์š”ํ•œ ๋‚ด์šฉ์€ ์ด๊ณณ์— ๋จผ์ € ๊ณต์œ ๋ฉ๋‹ˆ๋‹ค. ๋˜, ํŠธ์œ„ํ„ฐ์—์„œ [@reactjs](https://twitter.com/reactjs) ๊ณ„์ •์„ ํŒ”๋กœ์šฐํ•˜์…”๋„ ์ข‹์ง€๋งŒ, ์ด ๋ธ”๋กœ๊ทธ๋งŒ์œผ๋กœ๋„ ๋ชจ๋“  ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด ๋ธ”๋กœ๊ทธ๋Š” React ํŒ€์˜ ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•œ ๊ณต์‹ ์ถœ์ฒ˜์ž…๋‹ˆ๋‹ค. ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ ๋ฐ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ๋“ค์— ๋Œ€ํ•œ ๊ณต์ง€<sup>Deprecation Notice</sup>๋ฅผ ๋น„๋กฏํ•œ ์ค‘์š” ๋‚ด์šฉ๋“ค์ด ์ด๊ณณ์— ๋จผ์ € ๊ณต์œ ๋ฉ๋‹ˆ๋‹ค. ํŠธ์œ„ํ„ฐ์—์„œ [@reactjs](https://twitter.com/reactjs) ๊ณ„์ •์„ ํŒ”๋กœ์šฐํ•ด๋„ ์ข‹์ง€๋งŒ, ์ด ๋ธ”๋กœ๊ทธ๋งŒ์œผ๋กœ๋„ ๋ชจ๋“  ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Intro> @@ -90,7 +90,7 @@ React ํŒ€์€ ๋ช‡ ๊ฐ€์ง€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ### ๋ชจ๋“  ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ {/*all-release-notes*/} -React์˜ ๋ชจ๋“  ๋ฆด๋ฆฌ์Šค ๋‚ด์šฉ์ด ๋ณ„๋„์˜ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๊ธ€๋กœ ์ž‘์„ฑ๋˜์ง€๋Š” ์•Š์ง€๋งŒ, ๋ชจ๋“  ๋ฆด๋ฆฌ์Šค์— ๋Œ€ํ•œ ์„ธ๋ถ€ ๋ณ€๊ฒฝ ๋ช…์„ธ๋Š” React ์ €์žฅ์†Œ์˜ [`CHANGELOG.md`](https://github.com/facebook/react/blob/main/CHANGELOG.md) ํŒŒ์ผ ๋˜๋Š” [Releases](https://github.com/facebook/react/releases) ํŽ˜์ด์ง€์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +React์˜ ๋ชจ๋“  ๋ฆด๋ฆฌ์Šค ๋‚ด์šฉ์ด ๋ณ„๋„์˜ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๊ธ€๋กœ ์ž‘์„ฑ๋˜์ง€๋Š” ์•Š์ง€๋งŒ, ๋ชจ๋“  ๋ฆด๋ฆฌ์Šค์— ๋Œ€ํ•œ ์„ธ๋ถ€ ๋ณ€๊ฒฝ ๋‚ด์—ญ์€ React ์ €์žฅ์†Œ์˜ [`CHANGELOG.md`](https://github.com/facebook/react/blob/main/CHANGELOG.md) ํŒŒ์ผ ๋˜๋Š” [Releases](https://github.com/facebook/react/releases) ํŽ˜์ด์ง€์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --- From 5feba882c6be5285c3c0d0e40866c635df9a0b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 18:16:02 +0900 Subject: [PATCH 0349/1059] docs: update `data-fetching-with-react-server-components` --- ...data-fetching-with-react-server-components.md | 16 ++++++++-------- src/content/blog/index.md | 4 ++-- src/sidebarBlog.json | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/content/blog/2020/12/21/data-fetching-with-react-server-components.md b/src/content/blog/2020/12/21/data-fetching-with-react-server-components.md index 78709dc61..190461156 100644 --- a/src/content/blog/2020/12/21/data-fetching-with-react-server-components.md +++ b/src/content/blog/2020/12/21/data-fetching-with-react-server-components.md @@ -1,8 +1,8 @@ --- -title: "์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์†Œ๊ฐœ" +title: "์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค" author: Dan Abramov, Lauren Tan, Joseph Savona, and Sebastian Markbage date: 2020/12/21 -description: 2020๋…„์€ ๊ธด ํ•œ ํ•ด์˜€์Šต๋‹ˆ๋‹ค. ์—ฐ๋ง์ด ๋‹ค๊ฐ€์˜ด์— ๋”ฐ๋ผ ์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ์˜ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์—ฐ๊ตฌ์— ๋Œ€ํ•œ ํŠน๋ณ„ํ•œ ํ™€๋ฆฌ๋ฐ์ด ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. +description: 2020๋…„์€ ๊ธด ํ•œ ํ•ด์˜€์Šต๋‹ˆ๋‹ค. ์—ฐ๋ง์ด ๋‹ค๊ฐ€์˜ด์— ๋”ฐ๋ผ ์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ์˜ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์—ฐ๊ตฌ์— ๋Œ€ํ•œ ํŠน๋ณ„ ์—ฐํœด ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. --- 2020๋…„ 12์›” 21์ผ, [Dan Abramov](https://twitter.com/dan_abramov), [Lauren Tan](https://twitter.com/potetotes), [Joseph Savona](https://twitter.com/en_JS), [Sebastian Markbรฅge](https://twitter.com/sebmarkbage) @@ -11,24 +11,24 @@ description: 2020๋…„์€ ๊ธด ํ•œ ํ•ด์˜€์Šต๋‹ˆ๋‹ค. ์—ฐ๋ง์ด ๋‹ค๊ฐ€์˜ด์— ๋”ฐ๋ผ <Intro> -2020๋…„์€ ๊ธด ํ•œ ํ•ด์˜€์Šต๋‹ˆ๋‹ค. ์—ฐ๋ง์ด ๋‹ค๊ฐ€์˜ด์— ๋”ฐ๋ผ ์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ์˜ **React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ** ์—ฐ๊ตฌ์— ๋Œ€ํ•œ ํŠน๋ณ„ํ•œ ํ™€๋ฆฌ๋ฐ์ด ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. +2020๋…„์€ ๊ธด ํ•œ ํ•ด์˜€์Šต๋‹ˆ๋‹ค. ์—ฐ๋ง์ด ๋‹ค๊ฐ€์˜ด์— ๋”ฐ๋ผ ์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ **React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ** ์—ฐ๊ตฌ์— ๋Œ€ํ•œ ํŠน๋ณ„ ์—ฐํœด ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. </Intro> --- -React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ•์—ฐ๊ณผ ๋ฐ๋ชจ๋ฅผ ์ค€๋น„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์—ฐํœด ๊ธฐ๊ฐ„ ๋˜๋Š” ์ƒˆํ•ด์— ์—…๋ฌด๊ฐ€ ์žฌ๊ฐœ๋˜๋Š” ์‹œ์ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ•์—ฐ๊ณผ ๋ฐ๋ชจ๋ฅผ ์ค€๋น„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์—ฐํœด ๊ธฐ๊ฐ„ ๋˜๋Š” ์ƒˆํ•ด์— ์—…๋ฌด๊ฐ€ ์žฌ๊ฐœ๋˜๋Š” ์‹œ์ ์— ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <YouTubeIframe src="https://www.youtube.com/embed/TQQPAU21ZUw" /> -**React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์•„์ง ์—ฐ๊ตฌ ๊ฐœ๋ฐœ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค.** ์šฐ๋ฆฌ๋Š” ํˆฌ๋ช…์„ฑ์˜ ์ •์‹ ์œผ๋กœ React ์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ๋ถ€ํ„ฐ ์ดˆ๊ธฐ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ์ด ์ž‘์—…์„ ๊ณต์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ๊ฒƒ์ด๋ฏ€๋กœ **์ง€๊ธˆ ๋‹น์žฅ ๋”ฐ๋ผ์žก์•„์•ผ ํ•œ๋‹ค๊ณ  ๋А๋ผ์ง€ ๋งˆ์„ธ์š”!** +**React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์•„์ง ์—ฐ๊ตฌ ๊ฐœ๋ฐœ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค.** ํˆฌ๋ช…์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  React ์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ๋ถ€ํ„ฐ ์ดˆ๊ธฐ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ์ž‘์—…์„ ๊ณต์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ๊ฒƒ์ด๋ฏ€๋กœ **์ง€๊ธˆ ๋‹น์žฅ ๋”ฐ๋ผ์žก์•„์•ผ ํ•œ๋‹ค๊ณ  ๋А๋ผ์ง€ ๋งˆ์„ธ์š”!** -์ด๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์ง„ํ–‰ํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. +์ด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜์™€ ๊ฐ™์€ ์ˆœ์„œ๋ฅผ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. 1. **๊ฐ•์—ฐ**์„ ์‹œ์ฒญํ•˜์—ฌ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด ํ•™์Šตํ•˜๊ณ  ๋ฐ๋ชจ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. -2. **[๋ฐ๋ชจ๋ฅผ ํด๋ก ](http://github.com/reactjs/server-components-demo)** ํ•˜์—ฌ ์ปดํ“จํ„ฐ์—์„œ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š”. +2. <strong>[๋ฐ๋ชจ๋ฅผ ํด๋ก ](http://github.com/reactjs/server-components-demo)</strong>ํ•˜์—ฌ ์ปดํ“จํ„ฐ์—์„œ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š”. -3. ์ž์„ธํ•œ ๊ธฐ์ˆ  ๋ถ„์„๊ณผ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๋ ค๋ฉด **[RFC ํ™•์ธํ•˜๊ธฐ(FAQ๊ฐ€ ๋งˆ์ง€๋ง‰์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค)](https://github.com/reactjs/rfcs/pull/188)** ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. +3. ์ž์„ธํ•œ ๊ธฐ์ˆ  ๋ถ„์„๊ณผ ํ”ผ๋“œ๋ฐฑ ์ œ๊ณต์„ ์œ„ํ•ด <strong>[RFC(FAQ๊ฐ€ ๋งˆ์ง€๋ง‰์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค)](https://github.com/reactjs/rfcs/pull/188)</strong>๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”. RFC ๋˜๋Š” [@reactjs](https://twitter.com/reactjs) ํŠธ์œ„ํ„ฐ ๊ณ„์ •์—์„œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์˜๊ฒฌ์„ ๊ธฐ๋‹ค๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฆ๊ฑฐ์šด ์—ฐ๋ง์—ฐ์‹œ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด๋‚ด์‹œ๊ณ  ๋‚ด๋…„์— ๋ต™๊ฒ ์Šต๋‹ˆ๋‹ค! diff --git a/src/content/blog/index.md b/src/content/blog/index.md index b5bec0f05..f412442b6 100644 --- a/src/content/blog/index.md +++ b/src/content/blog/index.md @@ -80,8 +80,8 @@ React ํŒ€์€ ๋ช‡ ๊ฐ€์ง€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. - ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๊ฐ€ ์‚ฌ์šฉํ•ด ๋ณด๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก React 18 ์•ŒํŒŒ๋ฅผ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. </BlogCard> -<BlogCard title="์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์†Œ๊ฐœ" date="2020๋…„ 12์›” 21์ผ" url="/blog/2020/12/21/data-fetching-with-react-server-components"> -2020๋…„์€ ๊ธด ํ•œ ํ•ด์˜€์Šต๋‹ˆ๋‹ค. ์—ฐ๋ง์ด ๋‹ค๊ฐ€์˜ด์— ๋”ฐ๋ผ ์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ์˜ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์—ฐ๊ตฌ์— ๋Œ€ํ•œ ํŠน๋ณ„ํ•œ ํ™€๋ฆฌ๋ฐ์ด ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ•์—ฐ๊ณผ ๋ฐ๋ชจ๋ฅผ ์ค€๋น„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์—ฐํœด ๊ธฐ๊ฐ„ ๋˜๋Š” ์ƒˆํ•ด์— ์—…๋ฌด๊ฐ€ ์žฌ๊ฐœ๋˜๋Š” ์‹œ์ ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +<BlogCard title="์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค" date="2020๋…„ 12์›” 21์ผ" url="/blog/2020/12/21/data-fetching-with-react-server-components"> +2020๋…„์€ ๊ธด ํ•œ ํ•ด์˜€์Šต๋‹ˆ๋‹ค. ์—ฐ๋ง์ด ๋‹ค๊ฐ€์˜ด์— ๋”ฐ๋ผ ์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ์˜ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์—ฐ๊ตฌ์— ๋Œ€ํ•œ ํŠน๋ณ„ ์—ฐํœด ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ•์—ฐ๊ณผ ๋ฐ๋ชจ๋ฅผ ์ค€๋น„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์—ฐํœด ๊ธฐ๊ฐ„ ๋˜๋Š” ์ƒˆํ•ด์— ์—…๋ฌด๊ฐ€ ์žฌ๊ฐœ๋˜๋Š” ์‹œ์ ์— ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </BlogCard> </div> diff --git a/src/sidebarBlog.json b/src/sidebarBlog.json index 01923387c..8ff8995c1 100644 --- a/src/sidebarBlog.json +++ b/src/sidebarBlog.json @@ -110,7 +110,7 @@ "path": "/blog/2021/06/08/the-plan-for-react-18" }, { - "title": "์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์†Œ๊ฐœ", + "title": "์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค", "titleForHomepage": "์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์†Œ๊ฐœ", "icon": "labs", "date": "2020.12.21", From 1a8f84bafe91318c468d9579ee40c0488bdf7419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 18:57:46 +0900 Subject: [PATCH 0350/1059] docs: update `the-plan-for-react-18.md` --- .../blog/2021/06/08/the-plan-for-react-18.md | 44 +++++++++---------- src/content/blog/index.md | 4 +- src/content/community/versioning-policy.md | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/content/blog/2021/06/08/the-plan-for-react-18.md b/src/content/blog/2021/06/08/the-plan-for-react-18.md index e87d9740e..36f1d8e9b 100644 --- a/src/content/blog/2021/06/08/the-plan-for-react-18.md +++ b/src/content/blog/2021/06/08/the-plan-for-react-18.md @@ -1,8 +1,8 @@ --- -title: "React 18 ๊ณ„ํš" +title: "React 18์— ๋Œ€ํ•œ ๊ณ„ํš" author: Andrew Clark, Brian Vaughn, Christine Abernathy, Dan Abramov, Rachel Nabors, Rick Hanlon, Sebastian Markbage, and Seth Webster date: 2021/06/08 -description: React ํŒ€์€ ๋ช‡ ๊ฐ€์ง€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฃผ์š” ๋ฒ„์ „์ด ๋  React 18 ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•œ ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ ์ง„์ ์œผ๋กœ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด ์›Œํ‚น ๊ทธ๋ฃน์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๊ฐ€ ์‚ฌ์šฉํ•ด ๋ณด๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก React 18 ์•ŒํŒŒ๋ฅผ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค... +description: React ํŒ€์€ ๋ช‡ ๊ฐ€์ง€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ฃผ์š” ๋ฒ„์ „์ด ๋  React 18 ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•œ ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ ์ง„์ ์œผ๋กœ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด ์›Œํ‚น ๊ทธ๋ฃน์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๊ฐ€ ์‚ฌ์šฉํ•ด ๋ณด๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก React 18 Alpha๋ฅผ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค... --- 2021๋…„ 6์›” 8์ผ, [Andrew Clark](https://twitter.com/acdlite), [Brian Vaughn](https://github.com/bvaughn), [Christine Abernathy](https://twitter.com/abernathyca), [Dan Abramov](https://twitter.com/dan_abramov), [Rachel Nabors](https://twitter.com/rachelnabors), [Rick Hanlon](https://twitter.com/rickhanlonii), [Sebastian Markbรฅge](https://twitter.com/sebmarkbage), [Seth Webster](https://twitter.com/sethwebster) @@ -13,11 +13,11 @@ description: React ํŒ€์€ ๋ช‡ ๊ฐ€์ง€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ React ํŒ€์€ ๋ช‡ ๊ฐ€์ง€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. -1. ๋‹ค์Œ ์ฃผ์š” ๋ฒ„์ „์ด ๋  React 18 ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•œ ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. -2. ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ ์ง„์ ์œผ๋กœ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด ์›Œํ‚น ๊ทธ๋ฃน์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. -3. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๊ฐ€ ์‚ฌ์šฉํ•ด ๋ณด๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก React 18 ์•ŒํŒŒ๋ฅผ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. +1. ๋‹ค์Œ๋ฒˆ ์ฃผ<sup>Major, ไธป</sup> ๋ฒ„์ „์ด ๋  React 18 ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•œ ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. +2. ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ ์ง„์ ์œผ๋กœ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด ์›Œํ‚น ๊ทธ๋ฃน<sup>Working Group</sup>์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. +3. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๊ฐ€ ์‚ฌ์šฉํ•ด ๋ณด๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก React 18 Alpha๋ฅผ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. -์ด ์—…๋ฐ์ดํŠธ๋Š” ์ฃผ๋กœ ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ์ž๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. React๋ฅผ ๋ฐฐ์šฐ๊ฑฐ๋‚˜ ๊ฐ€๋ฅด์น˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ด ๊ฒŒ์‹œ๋ฌผ์„ ๋ฌด์‹œํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ์œผ์‹œ๋‹ค๋ฉด React 18 ์›Œํ‚น ๊ทธ๋ฃน์—์„œ ํ† ๋ก ์„ ๋”ฐ๋ผ๊ฐ€์…”๋„ ์ข‹์Šต๋‹ˆ๋‹ค! +์ด๋ฒˆ ์—…๋ฐ์ดํŠธ๋Š” ์ฃผ๋กœ ์„œ๋“œํŒŒํ‹ฐ<sup>Third Party</sup> ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ์ž๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. React๋ฅผ ๋ฐฐ์šฐ๊ฑฐ๋‚˜ ๊ฐ€๋ฅด์น˜๊ฑฐ๋‚˜, ํ˜น์€ ์‚ฌ์šฉ์ž ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ด ๊ฒŒ์‹œ๋ฌผ์„ ๋ฌด์‹œํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ์œผ์‹œ๋‹ค๋ฉด React 18 ์›Œํ‚น ๊ทธ๋ฃน์˜ ํ† ๋ก ์— ์ฐธ์—ฌํ•˜์…”๋„ ์ข‹์Šต๋‹ˆ๋‹ค! --- @@ -25,47 +25,47 @@ React ํŒ€์€ ๋ช‡ ๊ฐ€์ง€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ## React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ {/*whats-coming-in-react-18*/} -React 18์ด ์ถœ์‹œ๋˜๋ฉด [์ž๋™ ์ผ๊ด„ ์ฒ˜๋ฆฌ](https://github.com/reactwg/react-18/discussions/21)์™€ ๊ฐ™์€ ์ฆ‰์‹œ ์‚ฌ์šฉํ•œ ๊ฐœ์„  ์‚ฌํ•ญ ๋ฐ [`startTransition`](https://github.com/reactwg/react-18/discussions/41)๊ณผ ๊ฐ™์€ ์ƒˆ๋กœ์šด API, `React.lazy`๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์ง€์›ํ•˜๋Š” [์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ](https://github.com/reactwg/react-18/discussions/37)๊ฐ€ ํฌํ•จ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +React 18์ด ์ถœ์‹œ๋˜๋ฉด [์ž๋™ ์ผ๊ด„ ์ฒ˜๋ฆฌ<sup>Automatic Batching</sup>](https://github.com/reactwg/react-18/discussions/21)์™€ ๊ฐ™์€ ๊ธฐ๋ณธ ๊ฐœ์„  ์‚ฌํ•ญ ๋ฐ [`startTransition`](https://github.com/reactwg/react-18/discussions/41)๊ณผ ๊ฐ™์€ ์ƒˆ๋กœ์šด API, `React.lazy`๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” [์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ<sup>Streaming Server Renderer</sup>](https://github.com/reactwg/react-18/discussions/37)๊ฐ€ ํฌํ•จ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์€ React 18์— ์ถ”๊ฐ€๋˜๋Š” ์ƒˆ๋กœ์šด ์˜ตํŠธ์ธ ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•๋ถ„์— ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ "๋™์‹œ ๋ Œ๋”๋ง"์ด๋ผ๊ณ  ํ•˜๋ฉฐ, ์ด ๊ธฐ๋Šฅ์„ ํ†ตํ•ด React๋Š” ๋™์‹œ์— ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ UI๋ฅผ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ๋Œ€๋ถ€๋ถ„ ๋ณด์ด์ง€ ์•Š์ง€๋งŒ, ์•ฑ์˜ ์‹ค์ œ ์„ฑ๋Šฅ๊ณผ ์ฒด๊ฐ ์„ฑ๋Šฅ์„ ๋ชจ๋‘ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๊ฐ€๋Šฅ์„ฑ์„ ์—ด์–ด์ค๋‹ˆ๋‹ค. +์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ๋“ค์€ React 18์— ์ถ”๊ฐ€๋  ์ƒˆ๋กœ์šด ์„ ํƒ์ <sup>Opt-In</sup> ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•๋ถ„์— ๊ฐ€๋Šฅํ•ด์กŒ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ "๋™์‹œ ๋ Œ๋”๋ง<sup>Concurrent Rendering</sup>"์ด๋ผ๊ณ  ํ•˜๋ฉฐ, ์ด ๊ธฐ๋Šฅ์„ ํ†ตํ•ด React๋Š” ๋™์‹œ์— ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ UI๋ฅผ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋“ค์€ ๋Œ€๋ถ€๋ถ„ ์ง์ ‘ ๋ณผ ์ˆ˜๋Š” ์—†์ง€๋งŒ, ์•ฑ์˜ ์‹ค์ œ ์„ฑ๋Šฅ๊ณผ ์ฒด๊ฐ ์„ฑ๋Šฅ์„ ๋ชจ๋‘ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๊ฐ€๋Šฅ์„ฑ์„ ์—ด์–ด์ค๋‹ˆ๋‹ค. -React์˜ ๋ฏธ๋ž˜์— ๋Œ€ํ•œ ์ €ํฌ์˜ ์—ฐ๊ตฌ๋ฅผ ๊ณ„์† ์ง€์ผœ๋ณด์…จ๋‹ค๋ฉด(๊ทธ๋Ÿด ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค!) "๋™์‹œ ๋ชจ๋“œ"๋ผ๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋“ค์–ด๋ณด์…จ๊ฑฐ๋‚˜ ์•ฑ์ด ์†์ƒ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ๋ฅผ ๋“ค์–ด๋ณด์…จ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜์˜ํ•˜์—ฌ ์ ์ง„์ ์ธ ๋„์ž…์„ ์œ„ํ•ด ์—…๊ทธ๋ ˆ์ด๋“œ ์ „๋žต์„ ์žฌ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค. "๋ชจ๋“œ"๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋Œ€์‹ , ๋™์‹œ ๋ Œ๋”๋ง์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์— ์˜ํ•ด ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•ด์„œ๋งŒ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, **์‹ค์ œ๋กœ๋Š” ์žฌ์ž‘์„ฑ ์—†์ด React 18์„ ๋„์ž…ํ•˜๊ณ  ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค**. +React์˜ ๋ฏธ๋ž˜์— ๋Œ€ํ•œ ์ €ํฌ๋“ค์˜ ์—ฐ๊ตฌ๋ฅผ ๊ณ„์† ์ง€์ผœ๋ณด์…จ๋‹ค๋ฉด(๋ฌผ๋ก , ๊ทธ๋Ÿด ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค!), "๋™์‹œ ๋ชจ๋“œ<sup>Concurrent Mode</sup>"๋ผ๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋“ค์–ด๋ณด์…จ๊ฑฐ๋‚˜, ๊ทธ๊ฒƒ์ด ์—ฌ๋Ÿฌ๋ถ„๋“ค์˜ ์•ฑ์„ ๋ง์น  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ๋ฅผ ๋“ค์œผ์…จ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜์˜ํ•˜์—ฌ ์ ์ง„์ ์ธ ๋„์ž…์„ ์œ„ํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ ์ „๋žต์„ ์žฌ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค. "๋ชจ๋“œ"๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋Œ€์‹ , ๋™์‹œ ๋ Œ๋”๋ง<sup>Concurrent Rendering</sup>์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์— ์˜ํ•ด ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•ด์„œ๋งŒ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, **์žฌ์ž‘์„ฑ ์—†์ด React 18์„ ๋„์ž…ํ•˜๊ณ  ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค**. ## ์ ์ง„์ ์ธ ๋„์ž… ์ „๋žต {/*a-gradual-adoption-strategy*/} -React 18์˜ ๋™์‹œ์„ฑ์€ ์˜ตํŠธ์ธ ๋ฐฉ์‹์ด๋ฏ€๋กœ ์ปดํฌ๋„ŒํŠธ ๋™์ž‘์— ๋Œ€ํ•œ ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์—†์Šต๋‹ˆ๋‹ค. **์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๋ฅผ ๊ฑฐ์˜ ๋˜๋Š” ์ „ํ˜€ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ์ผ๋ฐ˜์ ์ธ ์ฃผ์š” React ๋ฆด๋ฆฌ์ฆˆ์™€ ๋น„์Šทํ•œ ์ˆ˜์ค€์˜ ๋…ธ๋ ฅ์œผ๋กœ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค**. ์—ฌ๋Ÿฌ ์•ฑ์„ React 18๋กœ ์ „ํ™˜ํ•œ ๊ฒฝํ—˜์— ๋น„์ถ”์–ด ๋ณผ ๋•Œ, ๋งŽ์€ ์‚ฌ์šฉ์ž๊ฐ€ ํ•˜๋ฃจ ์˜คํ›„ ์•ˆ์— ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. +React 18์˜ ๋™์‹œ์„ฑ์€ ์„ ํƒ์ <sup>Opt-In</sup>์ด๋ฏ€๋กœ ์ปดํฌ๋„ŒํŠธ ๋™์ž‘์— ๋Œ€ํ•œ ์ค‘์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ<sup>Breaking Changes</sup>์€ ์—†์Šต๋‹ˆ๋‹ค. **์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๋ฅผ ๊ฑฐ์˜ ๋˜๋Š” ์ „ํ˜€ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„, ์ผ๋ฐ˜์ ์ธ ์ฃผ์š” React ๋ฆด๋ฆฌ์ฆˆ์™€ ๋น„์Šทํ•œ ์ˆ˜์ค€์˜ ๋…ธ๋ ฅ์œผ๋กœ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค**. ์—ฌ๋Ÿฌ ์•ฑ์„ React 18๋กœ ์ „ํ™˜ํ•œ ๊ฒฝํ—˜์— ๋น„์ถ”์–ด ๋ณผ ๋•Œ, ๋งŽ์€ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ˜๋‚˜์ ˆ ์•ˆ์— ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. -์šฐ๋ฆฌ๋Š” Facebook์—์„œ ์ˆ˜๋งŒ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ์— ๋™์‹œ ๊ธฐ๋Šฅ์„ ์„ฑ๊ณต์ ์œผ๋กœ ์ œ๊ณตํ–ˆ์œผ๋ฉฐ, ๊ฒฝํ—˜์ƒ ๋Œ€๋ถ€๋ถ„์˜ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€ ๋ณ€๊ฒฝ ์—†์ด "๋ฐ”๋กœ ์ž‘๋™"ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. ์ „์ฒด ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ์œ„ํ•œ ์›ํ™œํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋„๋ก ์ตœ์„ ์„ ๋‹คํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์˜ค๋Š˜ React 18 ์›Œํ‚น ๊ทธ๋ฃน์„ ๋ฐœํ‘œํ•ฉ๋‹ˆ๋‹ค. +์šฐ๋ฆฌ๋Š” ํŽ˜์ด์Šค๋ถ<sup>Facebook</sup>์—์„œ ์ˆ˜๋งŒ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ์— ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ๋“ค์„ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐฐํฌํ–ˆ์œผ๋ฉฐ, ๊ฒฝํ—˜์ƒ ๋Œ€๋ถ€๋ถ„์˜ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€ ๋ณ€๊ฒฝ ์—†์ด "๋ฐ”๋กœ ์ž‘๋™"ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ ์ „์ฒด๋ฅผ ์œ„ํ•œ ์›ํ™œํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋„๋ก ์ตœ์„ ์„ ๋‹คํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์˜ค๋Š˜ React 18 ์›Œํ‚น ๊ทธ๋ฃน์„ ๋ฐœํ‘œํ•ฉ๋‹ˆ๋‹ค. ## ์ปค๋ฎค๋‹ˆํ‹ฐ์™€์˜ ํ˜‘๋ ฅ {/*working-with-the-community*/} -์ด๋ฒˆ ๋ฆด๋ฆฌ์ฆˆ์—์„œ๋Š” ์ƒˆ๋กœ์šด ์‹œ๋„๋ฅผ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. React ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ „๋ฌธ๊ฐ€, ๊ฐœ๋ฐœ์ž, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž, ๊ต์œก์ž๋“ค๋กœ ๊ตฌ์„ฑ๋œ ํŒจ๋„์„ [React 18 ์›Œํ‚น ๊ทธ๋ฃน](https://github.com/reactwg/react-18)์— ์ดˆ๋Œ€ํ•˜์—ฌ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๊ณ , ์งˆ๋ฌธํ•˜๊ณ , ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•ด ํ˜‘์—…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์†Œ๊ทœ๋ชจ ๊ทธ๋ฃน์—๋Š” ์›ํ•˜๋Š” ๋ชจ๋“  ๋ถ„์„ ์ดˆ๋Œ€ํ•  ์ˆ˜๋Š” ์—†์—ˆ์ง€๋งŒ, ์ด ์‹คํ—˜์ด ์„ฑ๊ณตํ•œ๋‹ค๋ฉด ์•ž์œผ๋กœ ๋” ๋งŽ์€ ๋ถ„์„ ์ดˆ๋Œ€ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค! +์ด๋ฒˆ ๋ฆด๋ฆฌ์ฆˆ์—์„œ๋Š” ์ƒˆ๋กœ์šด ์‹œ๋„๋ฅผ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. React ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ „๋ฌธ๊ฐ€, ๊ฐœ๋ฐœ์ž, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž, ๊ต์œก์ž๋“ค๋กœ ๊ตฌ์„ฑ๋œ ํŒจ๋„์„ [React 18 ์›Œํ‚น ๊ทธ๋ฃน](https://github.com/reactwg/react-18)์— ์ดˆ๋Œ€ํ•˜์—ฌ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๊ณ , ์งˆ๋ฌธํ•˜๊ณ , ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•ด ํ˜‘์—…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์†Œ๊ทœ๋ชจ ๊ทธ๋ฃน์— ์›ํ•˜๋Š” ๋ชจ๋“  ๋ถ„๋“ค์„ ์ดˆ๋Œ€ํ•  ์ˆ˜๋Š” ์—†์—ˆ์ง€๋งŒ, ์ด๋ฒˆ ์‹คํ—˜์ด ์„ฑ๊ณตํ•˜์—ฌ ์•ž์œผ๋กœ ๋” ๋งŽ์€ ๋ถ„์„ ์ดˆ๋Œ€ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค! -**React 18 ์›Œํ‚น ๊ทธ๋ฃน์˜ ๋ชฉํ‘œ๋Š” ๊ธฐ๋ณธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ React 18์„ ์›ํ™œํ•˜๊ณ  ์ ์ง„์ ์œผ๋กœ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ์ƒํƒœ๊ณ„๋ฅผ ์ค€๋น„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.** ์›Œํ‚น ๊ทธ๋ฃน์€ [GitHub ํ† ๋ก ](https://github.com/reactwg/react-18/discussions)์—์„œ ํ˜ธ์ŠคํŒ…๋˜๋ฉฐ, ์ผ๋ฐ˜์ธ๋„ ์—ด๋žŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›Œํ‚น ๊ทธ๋ฃน์˜ ๊ตฌ์„ฑ์›์€ ํ”ผ๋“œ๋ฐฑ์„ ๋‚จ๊ธฐ๊ณ , ์งˆ๋ฌธํ•˜๊ณ , ์•„์ด๋””์–ด๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ต์‹ฌ ํŒ€๋„ ํ† ๋ก  ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ตฌ ๊ฒฐ๊ณผ๋ฅผ ๊ณต์œ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•ˆ์ • ๋ฒ„์ „ ์ถœ์‹œ๊ฐ€ ๊ฐ€๊นŒ์›Œ์ง€๋ฉด ์ค‘์š”ํ•œ ์ •๋ณด๋„ ์ด ๋ธ”๋กœ๊ทธ์— ๊ฒŒ์‹œ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +**React 18 ์›Œํ‚น ๊ทธ๋ฃน์˜ ๋ชฉํ‘œ๋Š” ๊ธฐ๋ณธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ React 18์„ ์›ํ™œํ•˜๊ณ  ์ ์ง„์ ์œผ๋กœ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๊ณ„๋ฅผ ์ค€๋น„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.** ์›Œํ‚น ๊ทธ๋ฃน์€ [๊นƒํ—ˆ๋ธŒ ํ† ๋ก <sup>GitHub Discussions</sup>](https://github.com/reactwg/react-18/discussions)์—์„œ ํ˜ธ์ŠคํŒ…๋˜๋ฉฐ, ์ผ๋ฐ˜์ธ๋„ ์—ด๋žŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›Œํ‚น ๊ทธ๋ฃน์˜ ๊ตฌ์„ฑ์›์€ ํ”ผ๋“œ๋ฐฑ์„ ๋‚จ๊ธฐ๊ณ , ์งˆ๋ฌธํ•˜๊ณ , ์•„์ด๋””์–ด๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ต์‹ฌ ํŒ€๋„ ํ† ๋ก  ์ €์žฅ์†Œ<sup>Repository</sup>๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ตฌ ๊ฒฐ๊ณผ๋ฅผ ๊ณต์œ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•ˆ์ •์ ์ธ ๋ฒ„์ „์˜ ์ถœ์‹œ๊ฐ€ ๊ฐ€๊นŒ์›Œ์ง€๋ฉด, ์ค‘์š” ์ •๋ณด๋“ค์„ ๋ธ”๋กœ๊ทธ์— ๊ฒŒ์‹œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. -React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‚˜ ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ [React 18 ๋ฐœํ‘œ ๊ฒŒ์‹œ๋ฌผ](https://github.com/reactwg/react-18/discussions/4)์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. +React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‚˜, ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•œ ์ถ”๊ฐ€์ ์ธ ์ •๋ณด๋“ค์€ [React 18 ๋ฐœํ‘œ ๊ฒŒ์‹œ๋ฌผ](https://github.com/reactwg/react-18/discussions/4)์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. ## React 18 ์›Œํ‚น ๊ทธ๋ฃน์— ์ ‘๊ทผํ•˜๊ธฐ {/*accessing-the-react-18-working-group*/} -๋ˆ„๊ตฌ๋‚˜ [React 18 ์›Œํ‚น ๊ทธ๋ฃน ๋ฆฌํฌ์ง€ํ† ๋ฆฌ](https://github.com/reactwg/react-18)์—์„œ ํ† ๋ก  ๋‚ด์šฉ์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ˆ„๊ตฌ๋‚˜ [React 18 ์›Œํ‚น ๊ทธ๋ฃน ์ €์žฅ์†Œ](https://github.com/reactwg/react-18)์—์„œ ํ† ๋ก  ๋‚ด์šฉ์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์›Œํ‚น ๊ทธ๋ฃน์— ๋Œ€ํ•œ ์ดˆ๊ธฐ ๊ด€์‹ฌ์ด ๊ธ‰์ฆํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋ฏ€๋กœ ์ดˆ๋Œ€๋ฐ›์€ ํšŒ์›๋งŒ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋Œ“๊ธ€์„ ๋‹ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ† ๋ก ๊ธ€์€ ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ์™„์ „ํžˆ ๊ณต๊ฐœ๋˜๋ฏ€๋กœ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ๋™์ผํ•œ ์ •๋ณด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์›Œํ‚น ๊ทธ๋ฃน ๊ตฌ์„ฑ์›์„ ์œ„ํ•œ ์ƒ์‚ฐ์ ์ธ ํ™˜๊ฒฝ์„ ์กฐ์„ฑํ•˜๋Š” ๋™์‹œ์— ๋” ๋งŽ์€ ์ปค๋ฎค๋‹ˆํ‹ฐ์™€์˜ ํˆฌ๋ช…์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ์ข‹์€ ์ ˆ์ถฉ์•ˆ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. +์›Œํ‚น ๊ทธ๋ฃน์— ๋Œ€ํ•œ ์ดˆ๊ธฐ ๊ด€์‹ฌ์ด ๊ธ‰์ฆํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋ฏ€๋กœ, ์ดˆ๋Œ€๋ฐ›์€ ํšŒ์›๋งŒ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋Œ“๊ธ€์„ ๋‹ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ํ† ๋ก ๊ธ€์€ ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ์™„์ „ํžˆ ๊ณต๊ฐœ๋˜๋ฏ€๋กœ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ๋™์ผํ•œ ์ •๋ณด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์›Œํ‚น ๊ทธ๋ฃน ๊ตฌ์„ฑ์›์„ ์œ„ํ•œ ์ƒ์‚ฐ์ ์ธ ํ™˜๊ฒฝ์„ ์กฐ์„ฑํ•˜๋Š” ๋™์‹œ์— ๋” ๋งŽ์€ ์ปค๋ฎค๋‹ˆํ‹ฐ์™€์˜ ํˆฌ๋ช…์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ์ข‹์€ ์ ˆ์ถฉ์•ˆ์ด๋ผ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์–ธ์ œ๋‚˜ ๊ทธ๋ ‡๋“ฏ์ด [์ด์Šˆ ํŠธ๋ž˜์ปค](https://github.com/facebook/react/issues)์— ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ, ์งˆ๋ฌธ ๋ฐ ์ผ๋ฐ˜์ ์ธ ํ”ผ๋“œ๋ฐฑ์„ ์ œ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## ์ง€๊ธˆ React 18 ์•ŒํŒŒ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด๋Š” ๋ฐฉ๋ฒ• {/*how-to-try-react-18-alpha-today*/} +## ์ง€๊ธˆ React 18 Alpha๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• {/*how-to-try-react-18-alpha-today*/} -์ƒˆ๋กœ์šด ์•ŒํŒŒ๋Š” [์ •๊ธฐ์ ์œผ๋กœ `@alpha` ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ npm์— ๊ฒŒ์‹œ๋ฉ๋‹ˆ๋‹ค](https://github.com/reactwg/react-18/discussions/9). ์ด๋Ÿฌํ•œ ๋ฆด๋ฆฌ์ฆˆ๋Š” ๋ฉ”์ธ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ๋Œ€ํ•œ ๊ฐ€์žฅ ์ตœ๊ทผ ์ปค๋ฐ‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋นŒ๋“œ๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์ด๋‚˜ ๋ฒ„๊ทธ ์ˆ˜์ •์ด ๋ณ‘ํ•ฉ๋˜๋ฉด ๋‹ค์Œ ์ฃผ์ผ์— ์•ŒํŒŒ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. +์ƒˆ๋กœ์šด Alpha๋Š” [์ •๊ธฐ์ ์œผ๋กœ `@alpha` ํƒœ๊ทธ๋ฅผ ํ†ตํ•ด npm์— ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค](https://github.com/reactwg/react-18/discussions/9). ์ด๋Ÿฌํ•œ ๋ฆด๋ฆฌ์ฆˆ๋Š” ๋ฉ”์ธ ์ €์žฅ์†Œ<sup>Main Repo</sup>์— ๋Œ€ํ•œ ๊ฐ€์žฅ ์ตœ๊ทผ ์ปค๋ฐ‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋นŒ๋“œ๋ฉ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ ํ˜น์€ ๋ฒ„๊ทธ ์ˆ˜์ •์ด ๋ณ‘ํ•ฉ๋˜๋ฉด ๊ทธ ๋‹ค์Œ์ฃผ์— Alpha๋กœ ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค. -์•ŒํŒŒ ๋ฆด๋ฆฌ์ฆˆ ์‚ฌ์ด์—๋Š” ์ค‘์š”ํ•œ ๋™์ž‘ ๋˜๋Š” API ๋ณ€๊ฒฝ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **์•ŒํŒŒ ๋ฆด๋ฆฌ์ฆˆ๋Š” ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ํ”„๋กœ๋•์…˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋Š” ๊ถŒ์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ **์„ ๊ธฐ์–ตํ•˜์„ธ์š”. +Alpha ๋ฆด๋ฆฌ์ฆˆ ์‚ฌ์ด์—๋Š” ์ค‘์š”ํ•œ ๋™์ž‘ ๋˜๋Š” API ๋ณ€๊ฒฝ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **Alpha ๋ฆด๋ฆฌ์ฆˆ๋Š” ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ํ”„๋กœ๋•์…˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๊ถŒ์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ **์„ ๊ธฐ์–ตํ•˜์„ธ์š”. ## ์˜ˆ์ƒ React 18 ๋ฆด๋ฆฌ์ฆˆ ์ผ์ • {/*projected-react-18-release-timeline*/} -๊ตฌ์ฒด์ ์ธ ๋ฆด๋ฆฌ์ฆˆ ๋‚ ์งœ๋Š” ์˜ˆ์ •๋˜์–ด ์žˆ์ง€ ์•Š์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๋•์…˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ React 18์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ ค๋ฉด ๋ช‡ ๋‹ฌ ๋™์•ˆ ํ”ผ๋“œ๋ฐฑ๊ณผ ๋ฐ˜๋ณต ์ž‘์—…์„ ๊ฑฐ์ณ์•ผ ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. +๊ตฌ์ฒด์ ์ธ ๋ฆด๋ฆฌ์ฆˆ ๋‚ ์งœ๋Š” ์˜ˆ์ •๋˜์–ด ์žˆ์ง€ ์•Š์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๋•์…˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ React 18์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ ค๋ฉด ๋ช‡ ๋‹ฌ ๋™์•ˆ ํ”ผ๋“œ๋ฐฑ๊ณผ ๋ฐ˜๋ณต ์ž‘์—…์„ ๊ฑฐ์ณ์•ผ ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. -* ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์•ŒํŒŒ: ์˜ค๋Š˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ +* ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ Alpha: ์˜ค๋Š˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ * ๊ณต๊ฐœ ๋ฒ ํƒ€: ์ตœ์†Œ ๋ช‡ ๊ฐœ์›” -* ๋ฆด๋ฆฌ์ฆˆ ํ›„๋ณด (RC): ๋ฒ ํƒ€ ์ถœ์‹œ ํ›„ ์ตœ์†Œ ๋ช‡ ์ฃผ ํ›„ +* ๋ฆด๋ฆฌ์ฆˆ ํ›„๋ณด (RC): Beta ์ถœ์‹œ ํ›„ ์ตœ์†Œ ๋ช‡ ์ฃผ ํ›„ * ์ผ๋ฐ˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ: RC ์ดํ›„ ์ตœ์†Œ ๋ช‡ ์ฃผ ํ›„ ์˜ˆ์ƒ ๋ฆด๋ฆฌ์ฆˆ ์ผ์ •์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ [์›Œํ‚น ๊ทธ๋ฃน์—์„œ ํ™•์ธ](https://github.com/reactwg/react-18/discussions/9)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณต๊ฐœ ๋ฆด๋ฆฌ์ฆˆ์— ๊ฐ€๊นŒ์›Œ์ง€๋ฉด ์ด ๋ธ”๋กœ๊ทธ์— ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฒŒ์‹œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. diff --git a/src/content/blog/index.md b/src/content/blog/index.md index f412442b6..9c61f1d8e 100644 --- a/src/content/blog/index.md +++ b/src/content/blog/index.md @@ -72,12 +72,12 @@ React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ, ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋” ์ง€๋‚œ์ฃผ, ์šฐ๋ฆฌ๋Š” 6๋ฒˆ์งธ React Conf๋ฅผ ๊ฐœ์ตœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ ์šฐ๋ฆฌ๋Š” React Conf ๋ฌด๋Œ€๋ฅผ ํ†ตํ•ด React Native, React Hooks์™€ ๊ฐ™์€ ์—…๊ณ„ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฌ๋Š” ๋ฐœํ‘œ๋ฅผ ํ•ด์™”์Šต๋‹ˆ๋‹ค. ์˜ฌํ•ด๋Š” React 18์˜ ์ถœ์‹œ์™€ ๋™์‹œ ๊ธฐ๋Šฅ์˜ ์ ์ง„์ ์ธ ๋„์ž…์„ ์‹œ์ž‘์œผ๋กœ React์˜ ๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ ๋น„์ „์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. </BlogCard> -<BlogCard title="React 18 ๊ณ„ํš" date="2021๋…„ 6์›” 8์ผ" url="/blog/2021/06/08/the-plan-for-react-18"> +<BlogCard title="React 18์— ๋Œ€ํ•œ ๊ณ„ํš" date="2021๋…„ 6์›” 8์ผ" url="/blog/2021/06/08/the-plan-for-react-18"> React ํŒ€์€ ๋ช‡ ๊ฐ€์ง€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. - ๋‹ค์Œ ์ฃผ์š” ๋ฒ„์ „์ด ๋  React 18 ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•œ ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. - ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ ์ง„์ ์œผ๋กœ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด ์›Œํ‚น ๊ทธ๋ฃน์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. -- ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๊ฐ€ ์‚ฌ์šฉํ•ด ๋ณด๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก React 18 ์•ŒํŒŒ๋ฅผ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. +- ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๊ฐ€ ์‚ฌ์šฉํ•ด ๋ณด๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก React 18 Alpha๋ฅผ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. </BlogCard> <BlogCard title="์ œ๋กœ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค" date="2020๋…„ 12์›” 21์ผ" url="/blog/2020/12/21/data-fetching-with-react-server-components"> diff --git a/src/content/community/versioning-policy.md b/src/content/community/versioning-policy.md index 5f376ff4c..241619139 100644 --- a/src/content/community/versioning-policy.md +++ b/src/content/community/versioning-policy.md @@ -44,7 +44,7 @@ React์˜ ๊ฐœ๋ฐœ ๋นŒ๋“œ์—๋Š” ์œ ์šฉํ•œ ๊ฒฝ๊ณ ๊ฐ€ ๋งŽ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ ์ผ๋ฐ˜์ ์œผ๋กœ, ๋‹ค์Œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋“ค์€ ๋ฉ”์ด์ € ๋ฒ„์ „ ๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ *์•Š์Šต๋‹ˆ๋‹ค*. * **๊ฐœ๋ฐœ ๋นŒ๋“œ ๊ฒฝ๊ณ .** ํ”„๋กœ๋•์…˜ ๋™์ž‘์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์šฐ๋ฆฌ๋Š” ๋ฉ”์ด์ € ๋ฒ„์ „ ์‚ฌ์ด์— ์ƒˆ๋กœ์šด ๊ฒฝ๊ณ ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ๊ฒฝ๊ณ ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์•ž์œผ๋กœ ๋‹ค๊ฐ€์˜ฌ breaking changes์— ๋Œ€ํ•ด ์•ˆ์ •์ ์œผ๋กœ ๊ฒฝ๊ณ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **`unstable_`๋กœ ์‹œ์ž‘ํ•˜๋Š” API.** ์ด API๋“ค์€ ์•„์ง ํ™•์ •๋˜์ง€ ์•Š์€ ์‹คํ—˜์  ๊ธฐ๋Šฅ๋“ค๋กœ์„œ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. `unstable_` ์ ‘๋‘์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋“ค์„ ๋ฆด๋ฆฌ์ฆˆํ•จ์œผ๋กœ์จ, ๋” ๋น ๋ฅด๊ฒŒ ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ๋ฐ˜๋ณตํ•˜๊ณ  ์•ˆ์ •์ ์ธ API์— ๋” ๋น ๋ฅด๊ฒŒ ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -* **์•ŒํŒŒ ๋ฒ„์ „๊ณผ ์นด๋‚˜๋ฆฌ ๋ฒ„์ „์˜ React.** ์ด๋ฅธ ์‹œ์ผ ๋‚ด์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด ์•ŒํŒŒ ๋ฒ„์ „์˜ React๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, ์•ŒํŒŒ ๊ธฐ๊ฐ„ ๋™์•ˆ ๋ฐฐ์šด ๊ฒƒ์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์ฆˆ ์ด์ „์— API๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Œ์„ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +* **Alpha ๋ฒ„์ „๊ณผ ์นด๋‚˜๋ฆฌ ๋ฒ„์ „์˜ React.** ์ด๋ฅธ ์‹œ์ผ ๋‚ด์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด Alpha ๋ฒ„์ „์˜ React๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, Alpha ๊ธฐ๊ฐ„ ๋™์•ˆ ๋ฐฐ์šด ๊ฒƒ์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์ฆˆ ์ด์ „์— API๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Œ์„ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. * **๋ฌธ์„œํ™”๋˜์ง€ ์•Š์€ API์™€ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ.** `__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`๋‚˜ `__reactInternalInstance$uk43rzhitjg`์™€ ๊ฐ™์€ ๋‚ด๋ถ€ ์†์„ฑ ์ด๋ฆ„์— ์ ‘๊ทผํ•˜๋Š” ๊ฒฝ์šฐ, ์ด์— ๋Œ€ํ•œ ๋ณด์žฅ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋‹น์‹  ์Šค์Šค๋กœ ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ๊ณจ๋จธ๋ฆฌ๋ฅผ ์•“๋Š” ๊ฒƒ์„ ๋ฐ”๋ผ์ง€ ์•Š๊ธฐ์—, ์ด ์ •์ฑ…์€ ์‹ค์šฉ์ ์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ด๋Ÿฌํ•œ ๋ณ€ํ™”๋ฅผ ๋ชจ๋‘ ๋ฉ”์ด์ € ๋ฒ„์ „์œผ๋กœ ๋ฆด๋ฆฌ์ฆˆํ•œ๋‹ค๋ฉด, ๋” ๋งŽ์€ ๋ฉ”์ด์ € ๋ฒ„์ „์„ ๋ฆด๋ฆฌ์ฆˆํ•˜๊ฒŒ ๋˜๊ณ , ๊ถ๊ทน์ ์œผ๋กœ ๋ฒ„์ „ ๊ด€๋ฆฌ์— ๋Œ€ํ•ด ์ปค๋ฎค๋‹ˆํ‹ฐ์— ๋” ๋งŽ์€ ๊ณ ํ†ต์„ ์•ผ๊ธฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋งŒํผ React๋ฅผ ๋น ๋ฅด๊ฒŒ ๊ฐœ์„ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. From 9682773149fab4201a85102d7e9e4f46888eb260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Mon, 30 Dec 2024 19:23:28 +0900 Subject: [PATCH 0351/1059] docs: update `react-conf-2021-recap.md` --- .../blog/2021/12/17/react-conf-2021-recap.md | 56 +++++++++---------- src/content/blog/index.md | 2 +- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/content/blog/2021/12/17/react-conf-2021-recap.md b/src/content/blog/2021/12/17/react-conf-2021-recap.md index d512b6dbf..7caddb827 100644 --- a/src/content/blog/2021/12/17/react-conf-2021-recap.md +++ b/src/content/blog/2021/12/17/react-conf-2021-recap.md @@ -2,7 +2,7 @@ title: "React Conf 2021 ์š”์•ฝ" author: Jesslyn Tannady and Rick Hanlon date: 2021/12/17 -description: ์ง€๋‚œ์ฃผ, ์šฐ๋ฆฌ๋Š” 6๋ฒˆ์งธ React Conf๋ฅผ ๊ฐœ์ตœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ ์šฐ๋ฆฌ๋Š” React Conf ๋ฌด๋Œ€๋ฅผ ํ†ตํ•ด React Native, React Hooks ์™€ ๊ฐ™์€ ์—…๊ณ„ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฌ๋Š” ๋ฐœํ‘œ๋ฅผ ํ•ด์™”์Šต๋‹ˆ๋‹ค. ์˜ฌํ•ด๋Š” React 18์˜ ์ถœ์‹œ์™€ ๋™์‹œ ๊ธฐ๋Šฅ์˜ ์ ์ง„์ ์ธ ๋„์ž…์„ ์‹œ์ž‘์œผ๋กœ React์˜ ๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ ๋น„์ „์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. +description: ์ง€๋‚œ์ฃผ, 6๋ฒˆ์งธ React Conf๋ฅผ ๊ฐœ์ตœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ React Conf ๋ฌด๋Œ€๋ฅผ ํ†ตํ•ด React Native, React Hook๊ณผ ๊ฐ™์€ ์—…๊ณ„ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฌ๋Š” ๋ฐœํ‘œ๋ฅผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ฌํ•ด๋Š” React 18์˜ ์ถœ์‹œ ๋ฐ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์˜ ์ ์ง„์  ๋„์ž…์„ ์‹œ์ž‘์œผ๋กœ React์˜ ๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ ๋น„์ „์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. --- 2021๋…„ 12์›” 17์ผ, [Jesslyn Tannady](https://twitter.com/jtannady), [Rick Hanlon](https://twitter.com/rickhanlonii) @@ -11,29 +11,29 @@ description: ์ง€๋‚œ์ฃผ, ์šฐ๋ฆฌ๋Š” 6๋ฒˆ์งธ React Conf๋ฅผ ๊ฐœ์ตœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€ <Intro> -์ง€๋‚œ์ฃผ, ์šฐ๋ฆฌ๋Š” 6๋ฒˆ์งธ React Conf๋ฅผ ๊ฐœ์ตœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ ์šฐ๋ฆฌ๋Š” React Conf ๋ฌด๋Œ€๋ฅผ ํ†ตํ•ด [_React Native_](https://engineering.fb.com/2015/03/26/android/react-native-bringing-modern-web-techniques-to-mobile/), [_React Hooks_](https://reactjs.org/docs/hooks-intro.html)์™€ ๊ฐ™์€ ์—…๊ณ„ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฌ๋Š” ๋ฐœํ‘œ๋ฅผ ํ•ด์™”์Šต๋‹ˆ๋‹ค. ์˜ฌํ•ด๋Š” React 18์˜ ์ถœ์‹œ์™€ ๋™์‹œ ๊ธฐ๋Šฅ์˜ ์ ์ง„์ ์ธ ๋„์ž…์„ ์‹œ์ž‘์œผ๋กœ React์˜ ๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ ๋น„์ „์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. +์ง€๋‚œ์ฃผ, 6๋ฒˆ์งธ React Conf๋ฅผ ๊ฐœ์ตœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ React Conf ๋ฌด๋Œ€๋ฅผ ํ†ตํ•ด [_React Native_](https://engineering.fb.com/2015/03/26/android/react-native-bringing-modern-web-techniques-to-mobile/), [_React Hook_](https://reactjs.org/docs/hooks-intro.html)๊ณผ ๊ฐ™์€ ์—…๊ณ„ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฌ๋Š” ๋ฐœํ‘œ๋ฅผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ฌํ•ด๋Š” React 18์˜ ์ถœ์‹œ ๋ฐ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์˜ ์ ์ง„์  ๋„์ž…์„ ์‹œ์ž‘์œผ๋กœ React์˜ ๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ ๋น„์ „์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. </Intro> --- -React Conf๊ฐ€ ์˜จ๋ผ์ธ์œผ๋กœ ๊ฐœ์ตœ๋œ ๊ฒƒ์€ ์ด๋ฒˆ์ด ์ฒ˜์Œ์ด๋ฉฐ, 8๊ฐœ ์–ธ์–ด๋กœ ๋ฒˆ์—ญ๋˜์–ด ๋ฌด๋ฃŒ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ „ ์„ธ๊ณ„์˜ ์ฐธ๊ฐ€์ž๋“ค์€ ๋ชจ๋“  ์‹œ๊ฐ„๋Œ€์—์„œ ์ ‘๊ทผ์„ฑ์„ ์œ„ํ•ด ์ปจํผ๋Ÿฐ์Šค Discord์™€ ๋ฆฌํ”Œ๋ ˆ์ด ์ด๋ฒคํŠธ์— ์ฐธ์—ฌํ–ˆ์Šต๋‹ˆ๋‹ค. 50,000๋ช… ์ด์ƒ์ด ๋“ฑ๋กํ–ˆ์œผ๋ฉฐ, 19๊ฐœ ๊ฐ•์—ฐ์˜ ์กฐํšŒ์ˆ˜๋Š” 60,000ํšŒ๋ฅผ ๋„˜์—ˆ๊ณ , ๋‘ ์ด๋ฒคํŠธ์— ๊ฑธ์ณ 5,000๋ช…์ด Discord์— ์ฐธ์—ฌํ–ˆ์Šต๋‹ˆ๋‹ค. +React Conf๊ฐ€ ์˜จ๋ผ์ธ์œผ๋กœ ๊ฐœ์ตœ๋œ ๊ฒƒ์€ ์ด๋ฒˆ์ด ์ฒ˜์Œ์ด๋ฉฐ, 8๊ฐœ ์–ธ์–ด๋กœ ๋ฒˆ์—ญ๋˜์–ด ๋ฌด๋ฃŒ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ „ ์„ธ๊ณ„์˜ ์ฐธ๊ฐ€์ž๋“ค์€ ๋‹ค์–‘ํ•œ ์‹œ๊ฐ„๋Œ€์—์„œ์˜ ์ฐธ์—ฌ๋ฅผ ์œ„ํ•ด ์ปจํผ๋Ÿฐ์Šค Discord์™€ ๋ฆฌํ”Œ๋ ˆ์ด ์ด๋ฒคํŠธ๋ฅผ ์ด์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. 50,000๋ช… ์ด์ƒ์ด ๋“ฑ๋กํ–ˆ์œผ๋ฉฐ, 19๊ฐœ ๊ฐ•์—ฐ์˜ ์กฐํšŒ์ˆ˜๋Š” 60,000ํšŒ๋ฅผ ๋„˜์—ˆ๊ณ , ๋‘ ์ด๋ฒคํŠธ์— ๊ฑธ์ณ 5,000๋ช…์ด Discord์— ์ฐธ์—ฌํ–ˆ์Šต๋‹ˆ๋‹ค. -๋ชจ๋“  ๊ฐ•์—ฐ์€ [์˜จ๋ผ์ธ์œผ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ ๊ฐ€๋Šฅ](https://www.youtube.com/watch?v=FZ0cG47msEk&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa)ํ•ฉ๋‹ˆ๋‹ค. +๋ชจ๋“  ๊ฐ•์—ฐ์€ [์˜จ๋ผ์ธ ์ŠคํŠธ๋ฆฌ๋ฐ์ด ๊ฐ€๋Šฅ](https://www.youtube.com/watch?v=FZ0cG47msEk&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa)ํ•ฉ๋‹ˆ๋‹ค. -๋ฌด๋Œ€์—์„œ ๊ณต์œ ๋œ ๋‚ด์šฉ์„ ์š”์•ฝํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค: +๋ฌด๋Œ€์—์„œ ๊ณต์œ ๋œ ๋‚ด์šฉ์„ ์š”์•ฝํ•˜์˜€์Šต๋‹ˆ๋‹ค. -## React 18 ๋ฐ ๋™์‹œ ๊ธฐ๋Šฅ {/*react-18-and-concurrent-features*/} +## React 18 ๋ฐ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ {/*react-18-and-concurrent-features*/} -๊ธฐ์กฐ์—ฐ์„ค์—์„œ ์ €ํฌ๋Š” React 18์„ ์‹œ์ž‘์œผ๋กœ React์˜ ๋ฏธ๋ž˜์— ๋Œ€ํ•œ ๋น„์ „์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. +๊ธฐ์กฐ์—ฐ์„ค์—์„œ React 18์„ ์‹œ์ž‘์œผ๋กœ React์˜ ๋ฏธ๋ž˜์— ๋Œ€ํ•œ ๋น„์ „์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. -React 18์€ ์˜ค๋žซ๋™์•ˆ ๊ธฐ๋‹ค๋ ค์˜จ ๋™์‹œ renderer๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  Suspense๋ฅผ ํฐ ๋ณ€๊ฒฝ ์—†์ด ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์€ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์—ฌ ๋‹ค๋ฅธ ์ฃผ์š” ์ถœ์‹œ์™€ ๋™๋“ฑํ•œ ์ˆ˜์ค€์˜ ๋…ธ๋ ฅ์œผ๋กœ ๋™์‹œ ๊ธฐ๋Šฅ์„ ์ ์ง„์ ์œผ๋กœ ๋„์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +React 18์€ ์˜ค๋žซ๋™์•ˆ ๊ธฐ๋‹ค๋ ค์˜จ ๋™์‹œ ๋ Œ๋”๋Ÿฌ<sup>Concurrent Renderer</sup>๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  Suspense๋ฅผ ์ฃผ<sup>Major, ไธป</sup><sub>(์—ญ์ž. Breaking Change๋ฅผ ์ผ์œผํ‚ค๋Š”)</sub> ๋ณ€๊ฒฝ ์—†์ด ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์€ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์—ฌ ๋‹ค๋ฅธ ์ฃผ<sup>Major, ไธป</sup> ๋ฆด๋ฆฌ์ฆˆ์™€ ๋™๋“ฑํ•œ ์ˆ˜์ค€์˜ ๋…ธ๋ ฅ์œผ๋กœ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ์ ์ง„์ ์œผ๋กœ ๋„์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -**์ด๋Š” ๋™์‹œ ๋ชจ๋“œ๊ฐ€ ์—†๊ณ  ๋™์‹œ ๊ธฐ๋Šฅ๋งŒ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.** +**์ด๋Š” ๋™์‹œ ๋ชจ๋“œ๊ฐ€ ์—†๊ณ  ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ๋งŒ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.** ๊ธฐ์กฐ์—ฐ์„ค์—์„œ๋Š” Suspense, ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ, ์ƒˆ๋กœ์šด React ์›Œํ‚น ๊ทธ๋ฃน์— ๋Œ€ํ•œ ๋น„์ „๊ณผ React Native์— ๋Œ€ํ•œ ์žฅ๊ธฐ์ ์ธ ๋ฉ€ํ‹ฐํ”Œ๋žซํผ ๋น„์ „๋„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. -[Andrew Clark](https://twitter.com/acdlite), [Juan Tejada](https://twitter.com/_jstejada), [Lauren Tan](https://twitter.com/potetotes), [Rick Hanlon](https://twitter.com/rickhanlonii)์˜ ๊ธฐ์กฐ์—ฐ์„ค ์ „๋ฌธ์„ ์—ฌ๊ธฐ์—์„œ ์‹œ์ฒญํ•˜์„ธ์š”: +[Andrew Clark](https://twitter.com/acdlite), [Juan Tejada](https://twitter.com/_jstejada), [Lauren Tan](https://twitter.com/potetotes), [Rick Hanlon](https://twitter.com/rickhanlonii)์˜ ๊ธฐ์กฐ์—ฐ์„ค ์ „๋ฌธ์„ ์•„๋ž˜์—์„œ ์‹œ์ฒญํ•˜์„ธ์š”. <YouTubeIframe src="https://www.youtube.com/embed/FZ0cG47msEk" /> @@ -41,13 +41,13 @@ React 18์€ ์˜ค๋žซ๋™์•ˆ ๊ธฐ๋‹ค๋ ค์˜จ ๋™์‹œ renderer๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  Suspense ๊ธฐ์กฐ์—ฐ์„ค์—์„œ๋Š” React 18 RC๋ฅผ ์ง€๊ธˆ ๋ฐ”๋กœ ์‚ฌ์šฉํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค๋„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ํ”ผ๋“œ๋ฐฑ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์ค‘์ด๋ฉฐ, ๋‚ด๋…„ ์ดˆ์— ์ •์‹ ๋ฒ„์ „์œผ๋กœ ์ถœ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -React 18 RC๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด๋ ค๋ฉด ์˜์กด์„ฑ์„ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”: +React 18 RC๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด๋ ค๋ฉด ์˜์กด์„ฑ<sup>Dependencies</sup>์„ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”. ```bash npm install react@rc react-dom@rc ``` -๋ฅผ ํด๋ฆญํ•˜๊ณ  ์ƒˆ๋กœ์šด `createRoot` API๋กœ ์ „ํ™˜ํ•˜์„ธ์š”: +๊ทธ๋ฆฌ๊ณ  ์ƒˆ๋กœ์šด `createRoot` API๋กœ ์ „ํ™˜ํ•˜์„ธ์š”. ```js // before @@ -60,15 +60,15 @@ const root = ReactDOM.createRoot(container); root.render(<App/>); ``` -React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐ๋ชจ๋Š” ์—ฌ๊ธฐ์—์„œ [Shruti Kapoor](https://twitter.com/shrutikapoor08)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”: +React 18 ์—…๊ทธ๋ ˆ์ด๋“œ ๋ฐ๋ชจ๋Š” ์•„๋ž˜์˜ [Shruti Kapoor](https://twitter.com/shrutikapoor08)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”. <YouTubeIframe src="https://www.youtube.com/embed/ytudH8je5ko" /> ## Suspense๊ฐ€ ์žˆ๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง {/*streaming-server-rendering-with-suspense*/} -React 18์—๋Š” Suspense๋ฅผ ์‚ฌ์šฉํ•œ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง ์„ฑ๋Šฅ ๊ฐœ์„  ์‚ฌํ•ญ๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. +React 18์—๋Š” Suspense๋ฅผ ์‚ฌ์šฉํ•œ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง<sup>SSR, Server Side Rendering</sup> ์„ฑ๋Šฅ ๊ฐœ์„  ์‚ฌํ•ญ๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. -์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„์˜ React ์ปดํฌ๋„ŒํŠธ์—์„œ HTML์„ ์ƒ์„ฑํ•˜๊ณ  ํ•ด๋‹น HTML์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ŠคํŠธ๋ฆฌ๋ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React 18์—์„œ๋Š” 'Suspense'๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•ฑ์„ ๋” ์ž‘์€ ๋…๋ฆฝ ๋‹จ์œ„๋กœ ๋ถ„ํ•ดํ•˜์—ฌ ๋‚˜๋จธ์ง€ ์•ฑ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ˜ํ…์ธ ๋ฅผ ๋” ๋นจ๋ฆฌ ๋ณด๊ณ  ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์ƒํ˜ธ์ž‘์šฉ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. +์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์‚ฌ์šฉํ•˜๋ฉด, ์„œ๋ฒ„์˜ React ์ปดํฌ๋„ŒํŠธ์—์„œ HTML์„ ์ƒ์„ฑํ•˜๊ณ  ํ•ด๋‹น HTML์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ŠคํŠธ๋ฆฌ๋ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React 18์—์„œ๋Š” `Suspense`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•ฑ์„ ๋” ์ž‘์€ ๋…๋ฆฝ ๋‹จ์œ„๋กœ ๋ถ„ํ•ดํ•˜์—ฌ, ๋‚˜๋จธ์ง€ ์•ฑ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ˜ํ…์ธ ๋ฅผ ๋” ๋นจ๋ฆฌ ๋ณด๊ณ  ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด [Shaundai Person](https://twitter.com/shaundai)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”: @@ -76,48 +76,48 @@ React 18์—๋Š” Suspense๋ฅผ ์‚ฌ์šฉํ•œ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง ์„ฑ๋Šฅ ๊ฐœ์„  ์‚ฌํ•ญ ## ์ฒซ ๋ฒˆ์งธ React ์›Œํ‚น ๊ทธ๋ฃน {/*the-first-react-working-group*/} -React 18์—์„œ๋Š” ์ „๋ฌธ๊ฐ€, ๊ฐœ๋ฐœ์ž, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ์ž, ๊ต์œก์ž๋“ค๋กœ ๊ตฌ์„ฑ๋œ ํŒจ๋„๊ณผ ํ˜‘๋ ฅํ•˜๊ธฐ ์œ„ํ•ด ์ฒซ ๋ฒˆ์งธ ์›Œํ‚น ๊ทธ๋ฃน์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ•จ๊ป˜ ์ ์ง„์ ์ธ ์ฑ„ํƒ ์ „๋žต์„ ์„ธ์šฐ๊ณ  `useId`, `useSyncExternalStore`, `useInsertionEffect`์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด API๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค. +React 18์—์„œ๋Š” ์ „๋ฌธ๊ฐ€, ๊ฐœ๋ฐœ์ž, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ์ž, ๊ต์œก์ž๋“ค๋กœ ๊ตฌ์„ฑ๋œ ํŒจ๋„๊ณผ ํ˜‘๋ ฅํ•˜๊ธฐ ์œ„ํ•œ ์ฒซ ๋ฒˆ์งธ ์›Œํ‚น ๊ทธ๋ฃน์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ €ํฌ๋Š” ํ•จ๊ป˜ ์ ์ง„์ ์ธ ์ฑ„ํƒ ์ „๋žต์„ ์„ธ์šฐ๊ณ  `useId`, `useSyncExternalStore`, `useInsertionEffect`์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด API๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค. -์ด ์ž‘์—…์— ๋Œ€ํ•œ ๊ฐœ์š”๋Š” [Aakansha' Doshi](https://twitter.com/aakansha1216)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”: +ํ•ด๋‹น ์ž‘์—…์— ๋Œ€ํ•œ ๊ฐœ์š”๋Š” [Aakansha' Doshi](https://twitter.com/aakansha1216)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”. <YouTubeIframe src="https://www.youtube.com/embed/qn7gRClrC9U" /> ## React ๊ฐœ๋ฐœ์ž ๋„๊ตฌ {/*react-developer-tooling*/} -์ด๋ฒˆ ๋ฆด๋ฆฌ์ฆˆ์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ ๊ตฌ์„ฑ๋œ React ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ํŒ€๊ณผ ๊ฐœ๋ฐœ์ž๊ฐ€ React ์•ฑ์„ ๋””๋ฒ„๊น…ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ์ƒˆ๋กœ์šด ํƒ€์ž„๋ผ์ธ ํ”„๋กœํŒŒ์ผ๋Ÿฌ๋„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. +์ด๋ฒˆ ๋ฆด๋ฆฌ์ฆˆ์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ ๊ตฌ์„ฑ๋œ React ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ํŒ€๊ณผ ๊ฐœ๋ฐœ์ž๊ฐ€ React ์•ฑ ๋””๋ฒ„๊น…์— ๋„์›€์ด ๋˜๋Š” ์ƒˆ๋กœ์šด ํƒ€์ž„๋ผ์ธ ํ”„๋กœํŒŒ์ผ๋Ÿฌ<sup>Timeline Profiler</sup>๋„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. -์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ๊ณผ ๋ฐ๋ชจ๋Š” [Brian Vaughn](https://twitter.com/brian_d_vaughn)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”: +์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ๊ณผ ๋ฐ๋ชจ๋Š” [Brian Vaughn](https://twitter.com/brian_d_vaughn)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”. <YouTubeIframe src="https://www.youtube.com/embed/oxDfrke8rZg" /> ## memo ์—†๋Š” React {/*react-without-memo*/} -๋ฏธ๋ž˜๋ฅผ ๋‚ด๋‹ค๋ณด๋ฉฐ, [Xuan Huang(้ป„็Ž„)](https://twitter.com/Huxpro)์ด ์ž๋™ ๋ฉ”๋ชจํ™” ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ React Labs ์—ฐ๊ตฌ์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ•์—ฐ์—์„œ ์ž์„ธํ•œ ์ •๋ณด์™€ ์ปดํŒŒ์ผ๋Ÿฌ ํ”„๋กœํ† ํƒ€์ž… ๋ฐ๋ชจ๋ฅผ ํ™•์ธํ•˜์„ธ์š”: +๋ฏธ๋ž˜๋ฅผ ๋‚ด๋‹ค๋ณด๋ฉฐ, [Xuan Huang(้ป„็Ž„)](https://twitter.com/Huxpro)์ด ์ž๋™ ๋ฉ”๋ชจํ™” ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ React Labs ์—ฐ๊ตฌ์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ•์—ฐ์—์„œ ์ž์„ธํ•œ ์ •๋ณด์™€ ์ปดํŒŒ์ผ๋Ÿฌ ํ”„๋กœํ† ํƒ€์ž… ๋ฐ๋ชจ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. <YouTubeIframe src="https://www.youtube.com/embed/lGEMwh32soc" /> ## React ๋ฌธ์„œ ๊ธฐ์กฐ์—ฐ์„ค {/*react-docs-keynote*/} -[Rachel Nabors](https://twitter.com/rachelnabors)๊ฐ€ React์˜ ์ƒˆ๋กœ์šด ๋ฌธ์„œ์— ๋Œ€ํ•œ ํˆฌ์ž์— ๋Œ€ํ•œ ๊ธฐ์กฐ์—ฐ์„ค๋กœ React๋กœ ํ•™์Šตํ•˜๊ณ  ๋””์ž์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ•์—ฐ์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค([ํ˜„์žฌ react.dev๋กœ ์ œ๊ณต๋จ](/blog/2023/03/16/introducing-react-dev)): +[Rachel Nabors](https://twitter.com/rachelnabors)๊ฐ€ React์˜ ์ƒˆ๋กœ์šด ๋ฌธ์„œ์— ๋Œ€ํ•œ ํˆฌ์ž์™€ ๊ด€๋ จํ•œ ๊ธฐ์กฐ์—ฐ์„ค๋กœ, React๋กœ ํ•™์Šตํ•˜๊ณ  ๋””์ž์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ•์—ฐ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ([ํ˜„์žฌ react.dev๋กœ ๋ฐฐํฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.](/blog/2023/03/16/introducing-react-dev)) <YouTubeIframe src="https://www.youtube.com/embed/mneDaMYOKP8" /> ## ๊ทธ๋ฆฌ๊ณ ... {/*and-more*/} -**React๋กœ ํ•™์Šตํ•˜๊ณ  ๋””์ž์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ•์—ฐ:** +**React๋กœ ํ•™์Šตํ•˜๊ณ  ๋””์ž์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ•์—ฐ** * Debbie O'Brien: [์ƒˆ๋กœ์šด React ๋ฌธ์„œ์—์„œ ๋ฐฐ์šด ๊ฒƒ๋“ค](https://youtu.be/-7odLW_hG7s). * Sarah Rainsberger: [๋ธŒ๋ผ์šฐ์ €์—์„œ ํ•™์Šตํ•˜๊ธฐ](https://youtu.be/5X-WEQflCL0). -* Linton Ye: [React๋กœ ๋””์ž์ธํ•จ์—์„œ์˜ ROI](https://youtu.be/7cPWmID5XAk). -* Delba de Oliveira: [React๋ฅผ ์ด์šฉํ•œ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ๋†€์ดํ„ฐ](https://youtu.be/zL8cz2W0z34). +* Linton Ye: [React ๋””์ž์ธ์—์„œ์˜ ROI](https://youtu.be/7cPWmID5XAk). +* Delba de Oliveira: [React๋ฅผ ์ด์šฉํ•œ ์ƒํ˜ธ์ž‘์šฉ ๋†€์ดํ„ฐ](https://youtu.be/zL8cz2W0z34). -**Relay, React Native, PyTorch ํŒ€์˜ ๊ฐ•์—ฐ:** +**Relay, React Native, PyTorch ํŒ€์˜ ๊ฐ•์—ฐ** -* Robert Balicki: [Relay ๋‹ค์‹œ ์†Œ๊ฐœ](https://youtu.be/lhVGdErZuN4). +* Robert Balicki: [Relay ์žฌ์†Œ๊ฐœ](https://youtu.be/lhVGdErZuN4). * Eric Rozell๊ณผ Steven Moyes: [React Native ๋ฐ์Šคํฌํ†ฑ](https://youtu.be/9L4FFrvwJwY). -* Roman Rรคdle: [React Native๋ฅผ ์œ„ํ•œ ์˜จ๋””๋ฐ”์ด์Šค ๋จธ์‹ ๋Ÿฌ๋‹](https://youtu.be/NLj73vrc2I8) +* Roman Rรคdle: [React Native๋ฅผ ์œ„ํ•œ ์˜จ๋””๋ฐ”์ด์Šค ๋จธ์‹ ๋Ÿฌ๋‹](https://youtu.be/NLj73vrc2I8). -**์ ‘๊ทผ์„ฑ, ํˆด๋ง ๋ฐ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฐ•์—ฐ:** +**์ ‘๊ทผ์„ฑ, ํˆด๋ง ๋ฐ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฐ•์—ฐ** * Daishi Kato: [์™ธ๋ถ€ ์Šคํ† ์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์œ„ํ•œ React 18](https://youtu.be/oPfSC5bQPR8). * Diego Haz: [React 18์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์ถ•ํ•˜๊ธฐ](https://youtu.be/dcm8fjBfro8). diff --git a/src/content/blog/index.md b/src/content/blog/index.md index 9c61f1d8e..8b9f06d6d 100644 --- a/src/content/blog/index.md +++ b/src/content/blog/index.md @@ -69,7 +69,7 @@ React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ, ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋” </BlogCard> <BlogCard title="React Conf 2021 ์š”์•ฝ" date="2021๋…„ 12์›” 17์ผ" url="/blog/2021/12/17/react-conf-2021-recap"> -์ง€๋‚œ์ฃผ, ์šฐ๋ฆฌ๋Š” 6๋ฒˆ์งธ React Conf๋ฅผ ๊ฐœ์ตœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ ์šฐ๋ฆฌ๋Š” React Conf ๋ฌด๋Œ€๋ฅผ ํ†ตํ•ด React Native, React Hooks์™€ ๊ฐ™์€ ์—…๊ณ„ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฌ๋Š” ๋ฐœํ‘œ๋ฅผ ํ•ด์™”์Šต๋‹ˆ๋‹ค. ์˜ฌํ•ด๋Š” React 18์˜ ์ถœ์‹œ์™€ ๋™์‹œ ๊ธฐ๋Šฅ์˜ ์ ์ง„์ ์ธ ๋„์ž…์„ ์‹œ์ž‘์œผ๋กœ React์˜ ๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ ๋น„์ „์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. +์ง€๋‚œ์ฃผ, 6๋ฒˆ์งธ React Conf๋ฅผ ๊ฐœ์ตœํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ React Conf ๋ฌด๋Œ€๋ฅผ ํ†ตํ•ด React Native, React Hook๊ณผ ๊ฐ™์€ ์—…๊ณ„ ๋ณ€ํ™”๋ฅผ ์•Œ๋ฆฌ๋Š” ๋ฐœํ‘œ๋ฅผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ฌํ•ด๋Š” React 18์˜ ์ถœ์‹œ ๋ฐ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์˜ ์ ์ง„์  ๋„์ž…์„ ์‹œ์ž‘์œผ๋กœ React์˜ ๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ ๋น„์ „์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. </BlogCard> <BlogCard title="React 18์— ๋Œ€ํ•œ ๊ณ„ํš" date="2021๋…„ 6์›” 8์ผ" url="/blog/2021/06/08/the-plan-for-react-18"> From b5021f98220fe298d1da2ff44103332ac7466329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 00:12:36 +0900 Subject: [PATCH 0352/1059] docs: update `react-18-upgrade-guide` --- .../blog/2022/03/08/react-18-upgrade-guide.md | 114 +++++++++--------- src/content/blog/index.md | 2 +- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/content/blog/2022/03/08/react-18-upgrade-guide.md b/src/content/blog/2022/03/08/react-18-upgrade-guide.md index a1733f0df..06c41bc50 100644 --- a/src/content/blog/2022/03/08/react-18-upgrade-guide.md +++ b/src/content/blog/2022/03/08/react-18-upgrade-guide.md @@ -2,7 +2,7 @@ title: "React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•" author: Rick Hanlon date: 2022/03/08 -description: React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +description: React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๋™์‹œ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. --- 2022๋…„ 3์›” 8์ผ, [Rick Hanlon](https://twitter.com/rickhanlonii) @@ -11,7 +11,7 @@ description: React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๋™ <Intro> -React 18์€ [๋ฆด๋ฆฌ์Šค ๋…ธํŠธ](/blog/2022/03/29/react-v18)์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +React 18์€ [๋ฆด๋ฆฌ์Šค ๋…ธํŠธ](/blog/2022/03/29/react-v18)์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๋™์‹œ ๋ Œ๋”๋Ÿฌ<sup>Concurrent Renderer</sup>๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” [๋ฌธ์ œ๋ฅผ ์•Œ๋ ค์ฃผ์„ธ์š”](https://github.com/facebook/react/issues/new/choose). @@ -19,7 +19,7 @@ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” [๋ฌธ์ œ๋ฅผ ์•Œ๋ ค์ฃผ <Note> -React Native ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ, React 18์€ React Native์˜ ํ–ฅํ›„ ๋ฒ„์ „์— ํƒ‘์žฌ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด React 18์ด ์ด ๊ธ€์—์„œ ์†Œ๊ฐœ๋˜๋Š” ์ƒˆ๋กœ์šด React Native ์•„ํ‚คํ…์ฒ˜์— ์˜์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ •๋ณด๋Š” [React Conf ํ‚ค๋…ธํŠธ](https://www.youtube.com/watch?v=FZ0cG47msEk&t=1530s)๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”. +React Native ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ, React 18์€ React Native์˜ ํ–ฅํ›„ ๋ฒ„์ „์— ํƒ‘์žฌ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด React 18์ด ์ด ๊ธ€์—์„œ ์†Œ๊ฐœ๋˜๋Š” ์ƒˆ๋กœ์šด React Native ์•„ํ‚คํ…์ฒ˜์— ์˜์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ •๋ณด๋Š” [React Conf ๊ธฐ์กฐ์—ฐ์„ค](https://www.youtube.com/watch?v=FZ0cG47msEk&t=1530s)์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”. </Note> @@ -33,13 +33,13 @@ React Native ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ, React 18์€ React Native์˜ ํ–ฅํ›„ ๋ฒ„์ „์— npm install react react-dom ``` -ํ˜น์€ yarn์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”. +`yarn`์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”. ```bash yarn add react react-dom ``` -## ํด๋ผ์ด์–ธํŠธ ๋ Œ๋”๋ง API ๊ด€๋ จ ์—…๋ฐ์ดํŠธ {/*updates-to-client-rendering-apis*/} +## ํด๋ผ์ด์–ธํŠธ ๋ Œ๋”๋ง API ์—…๋ฐ์ดํŠธ {/*updates-to-client-rendering-apis*/} React 18์„ ์ฒ˜์Œ ์„ค์น˜ํ•˜๋ฉด ์ฝ˜์†” ์ฐฝ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. @@ -49,7 +49,7 @@ ReactDOM.render is no longer supported in React 18. Use createRoot instead. Unti </ConsoleBlock> -React 18์€ ์‚ฌ์šฉ์ž๋“ค์ด ๋” ํŽธ๋ฆฌํ•˜๊ฒŒ root ์š”์†Œ๋“ค์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ์‹  root API๋ฅผ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋”๋ถˆ์–ด ์ตœ์‹  root API๋Š” ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋™์ž‘์‹œ์ผœ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. +React 18์€ ์‚ฌ์šฉ์ž๋“ค์ด ๋” ํŽธ๋ฆฌํ•˜๊ฒŒ Root ์š”์†Œ๋“ค์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ์‹  Root API๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋”๋ถˆ์–ด ์ตœ์‹  Root API๋Š” ์ƒˆ๋กœ์šด ๋™์‹œ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋™์ž‘์‹œ์ผœ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ<sup>Concurrent Features</sup>์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ```js // ๋ณ€๊ฒฝ ์ „ @@ -74,7 +74,7 @@ unmountComponentAtNode(container); root.unmount(); ``` -๋˜ํ•œ Suspense๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ๋Œ€ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋ Œ๋”๋ง ๋ฉ”์„œ๋“œ์—์„œ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค. +Suspense๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ๋Œ€ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋ Œ๋”๋ง ๋ฉ”์„œ๋“œ์—์„œ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค. ```js // ๋ณ€๊ฒฝ ์ „ @@ -99,11 +99,11 @@ root.render(<AppWithCallbackAfterRender />); <Note> -๊ตฌํ˜• ๋ Œ๋”๋ง ์ฝœ๋ฐฑ API์— ์ •ํ™•ํžˆ ๋Œ€์‘ํ•˜๋Š” ๋Œ€์•ˆ์€ ์—†์œผ๋ฉฐ, ์‚ฌ์šฉ์ž์˜ ์‚ฌ์šฉ ๋ฐฉ์‹์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ •๋ณด๋Š” ํ˜„์žฌ ์ง„ํ–‰ ์ค‘์ธ ๊ทธ๋ฃน ํฌ์ŠคํŠธ์ธ [Replacing render with createRoot](https://github.com/reactwg/react-18/discussions/5)๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์˜› ๋ Œ๋”๋ง ์ฝœ๋ฐฑ API์— ์ •ํ™•ํžˆ ๋Œ€์‘ํ•˜๋Š” ๋Œ€์•ˆ์€ ์—†์œผ๋ฉฐ, ์‚ฌ์šฉ์ž์˜ ์‚ฌ์šฉ ๋ฐฉ์‹์— ๋”ฐ๋ผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ •๋ณด๋Š” ํ˜„์žฌ ์ง„ํ–‰ ์ค‘์ธ ๊ทธ๋ฃน ํฌ์ŠคํŠธ์ธ [Replacing render with `createRoot`](https://github.com/reactwg/react-18/discussions/5)๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Note> -๋งˆ์ง€๋ง‰์œผ๋กœ, hydration์œผ๋กœ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง(SSR)์„ ์ด์šฉํ•  ๊ฒฝ์šฐ์—๋Š” `hydrate`๋ฅผ `hydrateRoot`๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”. +๋งˆ์ง€๋ง‰์œผ๋กœ, Hydration์œผ๋กœ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง<sup>SSR, Server Side Rendering</sup>์„ ์ด์šฉํ•  ๊ฒฝ์šฐ์—๋Š” `hydrate`๋ฅผ `hydrateRoot`๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์„ธ์š”. ```js // ๋ณ€๊ฒฝ ์ „ @@ -118,17 +118,17 @@ const root = hydrateRoot(container, <App tab="home" />); // createRoot์™€๋Š” ๋‹ฌ๋ฆฌ, root.render()๋ฅผ ๋ณ„๋„๋กœ ํ˜ธ์ถœํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ``` -์ž์„ธํ•œ ์ •๋ณด๋Š” [์ง„ํ–‰ ์ค‘์ธ ๋””์Šค์ปค์…˜](https://github.com/reactwg/react-18/discussions/5)์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ž์„ธํ•œ ์ •๋ณด๋Š” [์ง„ํ–‰ ์ค‘์ธ ํ† ๋ก ](https://github.com/reactwg/react-18/discussions/5)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <Note> -**์—…๊ทธ๋ ˆ์ด๋“œ ์ดํ›„์—๋„ ์•ฑ์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด `<StrictMode>`๋กœ ๊ฐ์‹ธ์—ฌ ์žˆ์ง€ ์•Š์€์ง€ ํ™•์ธํ•ด ๋ณด์„ธ์š”.** [React 18์—์„œ๋Š” Strict ๋ชจ๋“œ๊ฐ€ ๋” ์—„๊ฒฉํ•ด์ ธ์„œ](#updates-to-strict-mode), ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐœ๋ฐœ ๋ชจ๋“œ์˜ ์ถ”๊ฐ€๋œ ๊ฒ€์‚ฌ ํ•ญ๋ชฉ์„ ๋งŒ์กฑ์‹œํ‚ค์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Strict ๋ชจ๋“œ๋ฅผ ์ œ๊ฑฐํ•จ์œผ๋กœ์จ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ์—…๊ทธ๋ ˆ์ด๋“œ ์ค‘์— ์ œ๊ฑฐํ•œ ๋‹ค์Œ, ํ†ตํ•ฉ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์ด๋‚˜ ์ฝ”๋“œ ํŽธ์ง‘๊ธฐ๊ฐ€ ํ‘œ์‹œํ•˜๋Š” ์˜ค๋ฅ˜๋“ค์„ ํ•ด๊ฒฐ๋œ ํ›„์— ๋‹ค์‹œ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (ํŠธ๋ฆฌ์˜ ์ƒ๋‹จ ๋˜๋Š” ์ผ๋ถ€๋ถ„์—). +**์—…๊ทธ๋ ˆ์ด๋“œ ์ดํ›„์—๋„ ์•ฑ์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด `<StrictMode>`๋กœ ๊ฐ์‹ธ์—ฌ ์žˆ์ง€ ์•Š์€์ง€ ํ™•์ธํ•ด ๋ณด์„ธ์š”.** [React 18์—์„œ๋Š” Strict ๋ชจ๋“œ๊ฐ€ ๋” ์—„๊ฒฉํ•ด์ ธ์„œ](#updates-to-strict-mode), ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐœ๋ฐœ ๋ชจ๋“œ์˜ ์ถ”๊ฐ€๋œ ๊ฒ€์‚ฌ ํ•ญ๋ชฉ์„ ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Strict ๋ชจ๋“œ๋ฅผ ์ œ๊ฑฐํ•จ์œผ๋กœ์จ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ์—…๊ทธ๋ ˆ์ด๋“œ ์ค‘์— ์ œ๊ฑฐํ•œ ๋‹ค์Œ, ํ†ตํ•ฉ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์ด๋‚˜ ์ฝ”๋“œ ํŽธ์ง‘๊ธฐ๊ฐ€ ํ‘œ์‹œํ•˜๋Š” ์˜ค๋ฅ˜๋“ค์„ ํ•ด๊ฒฐํ•œ ํ›„์— (ํŠธ๋ฆฌ์˜ ์ƒ๋‹จ ๋˜๋Š” ์ผ๋ถ€๋ถ„์—) ๋‹ค์‹œ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Note> ## Updates to Server Rendering APIs {/*updates-to-server-rendering-apis*/} -์ด๋ฒˆ ๋ฐฐํฌ์—์„œ๋Š” ์„œ๋ฒ„์™€ ์ŠคํŠธ๋ฆฌ๋ฐ SSR์—์„œ Suspense๋ฅผ ์ตœ๋Œ€ํ•œ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด `react-dom/server` API๋ฅผ ๊ฐœํŽธํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐœํŽธ์„ ํ†ตํ•ด, ์„œ๋ฒ„์—์„œ ์ ์ง„์ ์ธ Suspense ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ตฌํ˜• Node ์ŠคํŠธ๋ฆฌ๋ฐ API๋ฅผ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +์ด๋ฒˆ ๋ฆด๋ฆฌ์ฆˆ์—์„œ๋Š” ์„œ๋ฒ„์™€ ์ŠคํŠธ๋ฆฌ๋ฐ SSR์—์„œ Suspense๋ฅผ ์ตœ๋Œ€ํ•œ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด `react-dom/server` API๋ฅผ ๊ฐœํŽธํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ฐœํŽธ์„ ํ†ตํ•ด, ์„œ๋ฒ„์—์„œ ์ ์ง„์ ์ธ Suspense ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ตฌํ˜• Node ์ŠคํŠธ๋ฆฌ๋ฐ API๋ฅผ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. @@ -140,7 +140,7 @@ const root = hydrateRoot(container, <App tab="home" />); ๋”๋ถˆ์–ด Deno๋‚˜ Cloudflare workers์™€ ๊ฐ™์€ ์ตœ์‹  ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์—์„œ Suspense๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ŠคํŠธ๋ฆฌ๋ฐ SSR๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ์šด API๋ฅผ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. * `renderToReadableStream`: **์ƒˆ๋กœ ์ถ”๊ฐ€๋จ โœจ** -๋‹ค์Œ API๋“ค์€ ๊ณ„์† ์ž‘๋™๋˜๊ธด ํ•˜์ง€๋งŒ, Suspense ์ง€์›์ด ์ œํ•œ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +๋‹ค์Œ API๋“ค์€ ๊ณ„์† ๋™์ž‘ํ•˜๊ธด ํ•˜์ง€๋งŒ, Suspense ์ง€์›์ด ์ œํ•œ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. * `renderToString`: **์ œํ•œ๋จ** โš ๏ธ * `renderToStaticMarkup`: **์ œํ•œ๋จ** โš ๏ธ @@ -151,7 +151,7 @@ const root = hydrateRoot(container, <App tab="home" />); ## TypeScript ์‚ฌ์šฉ ์‹œ ํƒ€์ž… ์ž‘์„ฑ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ {/*updates-to-typescript-definitions*/} -ํ”„๋กœ์ ํŠธ์— TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, `@types/react`์™€ `@types/react-dom` ์˜์กด์„ฑ์„ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํƒ€์ž…๋“ค์„ ์‚ฌ์šฉํ•˜๋ฉด ๋” ์•ˆ์ „ํ•˜๊ฒŒ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ์กด์˜ ํƒ€์ž… ์ฒด์ปค๊ฐ€ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ–ˆ๋˜ ์ด์Šˆ๋“ค์„ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๋ˆˆ์— ๋„๋Š” ๋ณ€ํ™”๋Š” `children` ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ช…ํ™•ํ•œ ๋ฆฌ์ŠคํŠธ๋กœ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜์˜ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•ด๋ณด์„ธ์š”. +ํ”„๋กœ์ ํŠธ์— TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, `@types/react`์™€ `@types/react-dom` ์˜์กด์„ฑ์„ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํƒ€์ž…๋“ค์„ ์‚ฌ์šฉํ•˜๋ฉด ๋” ์•ˆ์ „ํ•˜๊ฒŒ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ์กด์˜ ํƒ€์ž… ๊ฒ€์‚ฌ๊ฐ€ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ–ˆ๋˜ ์ด์Šˆ๋“ค์„ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๋ˆˆ์— ๋„๋Š” ๋ณ€ํ™”๋Š” `children` ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ช…ํ™•ํ•œ ๋ฆฌ์ŠคํŠธ๋กœ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•ด๋ณด์„ธ์š”. ```typescript{3} interface MyButtonProps { @@ -162,49 +162,49 @@ interface MyButtonProps { [React 18 typings pull request](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210)์—์„œ ํƒ€์ž… ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ์ „์ฒด์ ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋งํฌ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํƒ€์ž… ์ˆ˜์ • ๋‚ด์šฉ์„ ๋‹ด๊ณ  ์žˆ์–ด ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [automated migration script](https://github.com/eps1lon/types-react-codemod)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ์— ์ตœ์‹ ์ด๊ณ  ๋” ์•ˆ์ „ํ•œ ํƒ€์ž…์„ ๋น ๋ฅด๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -ํƒ€์ดํ•‘์— ๋ฒ„๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋ฉด DefinitelyTyped ์ €์žฅ์†Œ์— [์ด์Šˆ๋ฅผ ์ œ๊ธฐํ•ด ์ฃผ์„ธ์š”](https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/new?category=issues-with-a-types-package). +ํƒ€์ดํ•‘์— ๋ฒ„๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋ฉด DefinitelyTyped ์ €์žฅ์†Œ์— [์ด์Šˆ๋ฅผ ๋ณด๋‚ด์ฃผ์„ธ์š”](https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/new?category=issues-with-a-types-package). ## ์ž๋™ Batching {/*automatic-batching*/} -React 18์€ ์ž๋™์œผ๋กœ ๋” ๋งŽ์€ batching์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋†€๋ผ์šด ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์ด๋ค˜์Šต๋‹ˆ๋‹ค. Batching์ด๋ž€ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ๋‹จ ํ•œ ๋ฒˆ์˜ ๋ฆฌ๋ Œ๋”๋ง์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. React 18 ์ด์ „์—๋Š” React ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด์—์„œ์˜ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋งŒ batching์„ ์ˆ˜ํ–‰ํ•ด ์™”์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ”„๋กœ๋ฏธ์Šค, setTimeout, ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋“ค์€ React์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ batching์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์•˜์ฃ . ๋‹ค์Œ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. +React 18์€ ์ž๋™์œผ๋กœ ๋” ๋งŽ์€ Batching์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋†€๋ผ์šด ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์ด๋ค˜์Šต๋‹ˆ๋‹ค. Batching์ด๋ž€ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ๋‹จ ํ•œ ๋ฒˆ์˜ ๋ฆฌ๋ Œ๋”๋ง์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. React 18 ์ด์ „์—๋Š” React ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด์—์„œ์˜ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋งŒ Batching์„ ์ˆ˜ํ–‰ํ•ด ์™”์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ”„๋กœ๋ฏธ์Šค, `setTimeout`, ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋“ค์€ React์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ Batching์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์•˜์ฃ . ๋‹ค์Œ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. ```js -// React 18 ์ด์ „์—๋Š” ์˜ค์ง React ์ด๋ฒคํŠธ๋“ค๋งŒ batch๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +// React 18 ์ด์ „์—๋Š” ์˜ค์ง React ์ด๋ฒคํŠธ๋“ค๋งŒ Batch๋˜์—ˆ์Šต๋‹ˆ๋‹ค. function handleClick() { setCount(c => c + 1); setFlag(f => !f); - // React๋Š” ๋งˆ์ง€๋ง‰์— ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. (๊ทธ๊ฒŒ batching์ด์ฃ !) + // React๋Š” ๋งˆ์ง€๋ง‰์— ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. (๊ทธ๊ฒŒ Batching์ด์ฃ !) } setTimeout(() => { setCount(c => c + 1); setFlag(f => !f); - // React๋Š” ๊ฐ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋งˆ๋‹ค ํ•œ ๋ฒˆ์”ฉ, ์ด ๋‘ ๋ฒˆ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. (batching ์—†์Œ) + // React๋Š” ๊ฐ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋งˆ๋‹ค ํ•œ ๋ฒˆ์”ฉ, ์ด ๋‘ ๋ฒˆ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. (Batching ์—†์Œ) }, 1000); ``` +React 18๋ฅผ ์‹œ์ž‘์œผ๋กœ `createRoot`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ๊ฐ€ ์ž๋™์œผ๋กœ Batch๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” `setTimeout`, ํ”„๋กœ๋ฏธ์Šค, ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ๋‚ด์˜ ์—…๋ฐ์ดํŠธ๋„ React ์ด๋ฒคํŠธ ๋‚ด์˜ ์—…๋ฐ์ดํŠธ์™€ ๊ฐ™์ด Batch ๋  ๊ฒƒ์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -React 18๋ฅผ ์‹œ์ž‘์œผ๋กœ `createRoot`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ๋ฐฐ์น˜๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” timeout, ํ”„๋กœ๋ฏธ์Šค, ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ๋‚ด์˜ ์—…๋ฐ์ดํŠธ๋„ React ์ด๋ฒคํŠธ ๋‚ด์˜ ์—…๋ฐ์ดํŠธ์™€ ๊ฐ™์ด batch ๋  ๊ฒƒ์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ```js -// React 18 ์ดํ›„๋กœ timeout, ํ”„๋กœ๋ฏธ์Šค, -// ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ๋‚ด์˜ ์—…๋ฐ์ดํŠธ๋„ batch ๋ฉ๋‹ˆ๋‹ค. +// React 18 ์ดํ›„๋กœ setTimeout, ํ”„๋กœ๋ฏธ์Šค, +// ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฒคํŠธ ๋‚ด์˜ ์—…๋ฐ์ดํŠธ๋„ Batch ๋ฉ๋‹ˆ๋‹ค. function handleClick() { setCount(c => c + 1); setFlag(f => !f); - // React๋Š” ๋งˆ์ง€๋ง‰์— ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. (๊ทธ๊ฒŒ batching์ด์ฃ !) + // React๋Š” ๋งˆ์ง€๋ง‰์— ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. (๊ทธ๊ฒŒ Batching์ด์ฃ !) } setTimeout(() => { setCount(c => c + 1); setFlag(f => !f); - // React๋Š” ๋งˆ์ง€๋ง‰์— ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. (๊ทธ๊ฒŒ batching์ด์ฃ !) + // React๋Š” ๋งˆ์ง€๋ง‰์— ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. (๊ทธ๊ฒŒ Batching์ด์ฃ !) }, 1000); ``` -์ด๋Š” ์—„์ฒญ๋‚œ ๋ณ€ํ™”์ด์ง€๋งŒ, ์ด๋ฅผ ํ†ตํ•ด ๋ Œ๋”๋ง ์ž‘์—…์— ์ˆ˜๊ณ ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ๋„ ํ–ฅ์ƒ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ž๋™ batching์„ ์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, `flushSync`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋Š” ์—„์ฒญ๋‚œ ๋ณ€ํ™”์ด์ง€๋งŒ, ์ด๋ฅผ ํ†ตํ•ด ๋ Œ๋”๋ง ์ž‘์—…์— ์ˆ˜๊ณ ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ๋„ ํ–ฅ์ƒ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ž๋™ Batching์„ ์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, `flushSync`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ```js import { flushSync } from 'react-dom'; @@ -225,41 +225,41 @@ function handleClick() { ## ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์œ„ํ•œ ์ƒˆ๋กœ์šด API {/*new-apis-for-libraries*/} -React 18 ์›Œํ‚น ๊ทธ๋ฃน์€ ์Šคํƒ€์ผ์ด๋‚˜ ์™ธ๋ถ€ ์ €์žฅ ์žฅ์น˜์™€ ๊ฐ™์€ ํŠน์ • ๋ชฉ์ ์„ ์œ„ํ•œ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ์ž๋“ค๊ณผ ํ˜‘๋ ฅํ•˜์—ฌ ์ƒˆ๋กœ์šด API๋ฅผ ๊ฐœ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค. React 18์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ผ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์€ ๋‹ค์Œ API ์ค‘ ํ•˜๋‚˜๋กœ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +React 18 ์›Œํ‚น ๊ทธ๋ฃน์€ ์Šคํƒ€์ผ์ด๋‚˜ ์™ธ๋ถ€ ์ €์žฅ ์žฅ์น˜์™€ ๊ฐ™์€ ํŠน์ • ๋ชฉ์ ์„ ์œ„ํ•œ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ์ž๋“ค๊ณผ ํ˜‘๋ ฅํ•˜์—ฌ ์ƒˆ๋กœ์šด API๋ฅผ ๊ฐœ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค. React 18์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์ผ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์€ ๋‹ค์Œ API ์ค‘ ํ•˜๋‚˜๋กœ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -* `useSyncExternalStore`๋Š” ์™ธ๋ถ€ ์ €์žฅ ์žฅ์น˜์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ˜์˜ํ•˜์—ฌ ์™ธ๋ถ€ ์ €์žฅ ์žฅ์น˜๊ฐ€ ๋™์‹œ์„ฑ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ด API๋Š” React ์™ธ๋ถ€์˜ ์ƒํƒœ๋ฅผ ํฌํ•จํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ •๋ณด๋Š” [useSyncExternalStore overview post](https://github.com/reactwg/react-18/discussions/70)์™€ [useSyncExternalStore API details](https://github.com/reactwg/react-18/discussions/86)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* `useSyncExternalStore`๋Š” ์™ธ๋ถ€ ์ €์žฅ ์žฅ์น˜์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ˜์˜ํ•˜์—ฌ ์™ธ๋ถ€ ์ €์žฅ ์žฅ์น˜๊ฐ€ ๋™์‹œ์„ฑ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ<sup>Concurrent Read</sup>๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ด API๋Š” React ์™ธ๋ถ€์˜ ์ƒํƒœ๋ฅผ ํฌํ•จํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ •๋ณด๋Š” [`useSyncExternalStore` overview post](https://github.com/reactwg/react-18/discussions/70)์™€ [`useSyncExternalStore` API details](https://github.com/reactwg/react-18/discussions/86)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -* `useInsertionEffect`๋Š” CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ Œ๋”๋ง ์‹œ ์Šคํƒ€์ผ ์ฃผ์ž…๊ณผ ๊ฐ™์€ ์„ฑ๋Šฅ ์ด์Šˆ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“  ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์ด hook์„ ์‚ฌ์šฉํ•  ํ•„์š”๋Š” ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด hook์€ DOM์ด ๋ณ€๊ฒฝ๋œ ํ›„ ์‹คํ–‰๋˜์ง€๋งŒ, ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์ƒˆ๋กœ์šด ๋ ˆ์ด์•„์›ƒ์„ ์ฝ์–ด ๋“ค์ด๊ธฐ ์ „์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ •๋ณด๋Š” [Library Upgrade Guide for `<style>`](https://github.com/reactwg/react-18/discussions/110)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* `useInsertionEffect`๋Š” CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ Œ๋”๋ง ์‹œ ์Šคํƒ€์ผ ์ฃผ์ž…๊ณผ ๊ฐ™์€ ์„ฑ๋Šฅ ์ด์Šˆ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“  ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์ด Hook์„ ์‚ฌ์šฉํ•  ํ•„์š”๋Š” ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด Hook์€ DOM์ด ๋ณ€๊ฒฝ๋œ ํ›„ ์‹คํ–‰๋˜์ง€๋งŒ, ๋ ˆ์ด์•„์›ƒ ์ดํŽ™ํŠธ๊ฐ€ ์ƒˆ๋กœ์šด ๋ ˆ์ด์•„์›ƒ์„ ์ฝ์–ด ๋“ค์ด๊ธฐ ์ „์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ •๋ณด๋Š” [Library Upgrade Guide for `<style>`](https://github.com/reactwg/react-18/discussions/110)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋˜, React 18์€ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง์„ ์œ„ํ•ด startTransition, useDeferredValue, ๊ทธ๋ฆฌ๊ณ  useId์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด API๋ฅผ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ [release post](/blog/2022/03/29/react-v18)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋˜, React 18์€ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง์„ ์œ„ํ•ด `startTransition`, `useDeferredValue`, ๊ทธ๋ฆฌ๊ณ  `useId`์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด API๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ [๋ฆด๋ฆฌ์ฆˆ ๊ฒŒ์‹œ๋ฌผ](/blog/2022/03/29/react-v18)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## Strict ๋ชจ๋“œ ์—…๋ฐ์ดํŠธ {/*updates-to-strict-mode*/} ์ฐจํ›„์—๋Š” React์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์—ฌ UI์˜ ์„น์…˜์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด, ์‚ฌ์šฉ์ž๊ฐ€ ๋’ค๋กœ ๊ฐ€๊ธฐ๋ฅผ ๋ˆ„๋ฅด๋ฉด React๊ฐ€ ์ฆ‰์‹œ ์ด์ „ ํ™”๋ฉด์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฑฐ์ฃ . ์ด๋ฅผ ์œ„ํ•ด React๋Š” ์ด์ „๊ณผ ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋ฆฌ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. -์ด ๊ธฐ๋Šฅ์€ React์˜ ์„ฑ๋Šฅ์„ ๋Œ€ํญ ํ–ฅ์ƒํ•  ๊ฒƒ์ด์ง€๋งŒ, ์ปดํฌ๋„ŒํŠธ๋“ค์ด effect๋“ค์ด ์—ฌ๋Ÿฌ ๋ฒˆ ๋งˆ์šดํŠธ๋˜์—ˆ๋‹ค๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ๊ฒƒ์— ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ effect๋“ค์€ ๋ณ€ํ•จ์—†์ด ๊ณ„์† ์ž‘๋™ํ•˜๊ฒ ์ง€๋งŒ, ์–ด๋–ค ๊ฒƒ๋“ค์€ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋งˆ์šดํŠธ๋˜๊ณ  ์‚ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. +์ด ๊ธฐ๋Šฅ์€ React์˜ ์„ฑ๋Šฅ์„ ๋Œ€ํญ ํ–ฅ์ƒํ•  ๊ฒƒ์ด์ง€๋งŒ, ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์ดํŽ™ํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ ๋งˆ์šดํŠธ๋˜์—ˆ๋‹ค๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ๊ฒƒ์— ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ดํŽ™ํŠธ๋“ค์€ ๋ณ€ํ•จ์—†์ด ๊ณ„์† ์ž‘๋™ํ•˜๊ฒ ์ง€๋งŒ, ์–ด๋–ค ๊ฒƒ๋“ค์€ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋งˆ์šดํŠธ๋˜๊ณ  ์‚ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. -React 18์€ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด Strict ๋ชจ๋“œ์— ๊ฐœ๋ฐœ ์ „์šฉ ๊ฒ€์‚ฌ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒ€์‚ฌ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ๋  ๋•Œ ์ž๋™์œผ๋กœ ๋งˆ์šดํŠธ ํ•ด์ œํ•œ ๋‹ค์Œ, ์ด์ „ ์ƒํƒœ๋ฅผ ๋ณต์›ํ•˜๋ฉด์„œ ๋‹ค์‹œ ๋งˆ์šดํŠธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +React 18์€ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด Strict ๋ชจ๋“œ์— ๊ฐœ๋ฐœ ์ „์šฉ ๊ฒ€์‚ฌ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒ€์‚ฌ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ๋  ๋•Œ ์ž๋™์œผ๋กœ ๋งˆ์šดํŠธ ํ•ด์ œํ•œ ๋‹ค์Œ, ์ด์ „ ์ƒํƒœ๋ฅผ ๋ณต์›ํ•˜๋ฉด์„œ ๋‹ค์‹œ ๋งˆ์šดํŠธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. -์ด ์—…๋ฐ์ดํŠธ ์ด์ „์—๋Š” React๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•˜๊ณ  effect๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. +์ด๋ฒˆ ์—…๋ฐ์ดํŠธ ์ด์ „์—๋Š” React๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•˜๊ณ  ์ดํŽ™ํŠธ๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ``` * React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค. - * ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. - * ์ดํŽ™ํŠธ effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. + * ๋ ˆ์ด์•„์›ƒ ์ดํŽ™ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. + * Effect ์ดํŽ™ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ``` -React 18์˜ Strict ๋ชจ๋“œ์—์„œ๋Š” ๊ฐœ๋ฐœ ์ „์šฉ ๋ชจ๋“œ์—์„œ React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•˜๋Š” ๊ฒƒ์„ ์‹คํ—˜ํ•ฉ๋‹ˆ๋‹ค. +React 18์˜ Strict ๋ชจ๋“œ์—์„œ๋Š” ๊ฐœ๋ฐœ ์ „์šฉ ๋ชจ๋“œ์—์„œ React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. ``` * React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค. - * ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. - * ์ดํŽ™ํŠธ effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. + * ๋ ˆ์ด์•„์›ƒ ์ดํŽ™ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. + * Effect ์ดํŽ™ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. * React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. - * ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. - * Effect๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. + * ๋ ˆ์ด์•„์›ƒ ์ดํŽ™ํŠธ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. + * ์ดํŽ™ํŠธ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. * React๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์ „ ์ƒํƒœ๋กœ ๋‹ค์‹œ ๋งˆ์šดํŠธํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. - * ๋ ˆ์ด์•„์›ƒ effect ์…‹์—… ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. + * ๋ ˆ์ด์•„์›ƒ ์ดํŽ™ํŠธ ์…‹์—… ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. * Effect ์…‹์—… ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ``` @@ -267,7 +267,7 @@ React 18์˜ Strict ๋ชจ๋“œ์—์„œ๋Š” ๊ฐœ๋ฐœ ์ „์šฉ ๋ชจ๋“œ์—์„œ React๊ฐ€ ์ปดํฌ๋„Œ ## ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๊ตฌ์ถ•ํ•˜๊ธฐ {/*configuring-your-testing-environment*/} -`createRoot`๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ฒ˜์Œ์œผ๋กœ ํ…Œ์ŠคํŠธ๋“ค์„ ์—…๋ฐ์ดํŠธํ•˜๋ฉด ํ…Œ์ŠคํŠธ ์ฝ˜์†” ์ฐฝ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`createRoot`๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ฒ˜์Œ์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ฉด ํ…Œ์ŠคํŠธ ์ฝ˜์†” ์ฐฝ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <ConsoleBlock level="error"> @@ -284,11 +284,11 @@ globalThis.IS_REACT_ACT_ENVIRONMENT = true; ์ด ๋ณ€์ˆ˜๋Š” React์— ์œ ๋‹› ํ…Œ์ŠคํŠธ์™€ ์œ ์‚ฌํ•œ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ ์ค‘์ž„์„ ์•Œ๋ฆฌ๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๋œ ์‚ฌํ•ญ์„ `act`๋กœ ๊ฐ์‹ธ์ง€ ์•Š์œผ๋ฉด React๊ฐ€ ์œ ์šฉํ•œ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋“ค์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. -React์— `act`๊ฐ€ ํ•„์š” ์—†๋‹ค๊ณ  ์•Œ๋ฆฌ๋ ค๋ฉด ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ `false`๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ „์ฒด ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๋Š” ์ข…๋‹จ ๊ฐ„ ํ…Œ์ŠคํŠธ์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +React์— `act`๊ฐ€ ํ•„์š” ์—†๋‹ค๊ณ  ์•Œ๋ฆฌ๋ ค๋ฉด ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ `false`๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ „์ฒด ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๋Š” E2E<sup>End-to-End</sup> ํ…Œ์ŠคํŠธ์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ์—๋Š” ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ด๋ฅผ ์ž๋™์œผ๋กœ ์„ค์ •ํ•ด์ค„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, [React Testing Library์˜ ๋‹ค์Œ ๋ฒ„์ „์€ ์ถ”๊ฐ€์ ์ธ ์„ค์ • ์—†์ด๋„ React 18์„ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค](https://github.com/testing-library/react-testing-library/issues/509#issuecomment-917989936). -[`act` ํ…Œ์ŠคํŠธ API์™€ ์œ ๊ด€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด](https://github.com/reactwg/react-18/discussions/102)๋Š” ์›Œํ‚น ๊ทธ๋ฃน์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +[`act` ํ…Œ์ŠคํŠธ API์™€ ๊ด€๋ จ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด](https://github.com/reactwg/react-18/discussions/102)๋Š” ์›Œํ‚น ๊ทธ๋ฃน์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## Internet Explorer ์ง€์› ์ค‘๋‹จ {/*dropping-support-for-internet-explorer*/} @@ -297,7 +297,7 @@ React์— `act`๊ฐ€ ํ•„์š” ์—†๋‹ค๊ณ  ์•Œ๋ฆฌ๋ ค๋ฉด ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ `false`๋กœ ์„ค Internet Explorer๋ฅผ ์ง€์›ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ React 17์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. -## ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒƒ๋“ค {/*deprecations*/} +## ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค {/*deprecations*/} * `react-dom`: `ReactDOM.render`๊ฐ€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  ์•ฑ์ด React 17 ๋ชจ๋“œ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. * `react-dom`: `ReactDOM.hydrate`๊ฐ€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  ์•ฑ์ด React 17 ๋ชจ๋“œ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. @@ -305,29 +305,29 @@ Internet Explorer๋ฅผ ์ง€์›ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ React 17์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ * `react-dom`: `ReactDOM.renderSubtreeIntoContainer`๊ฐ€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. * `react-dom/server`: `ReactDOMServer.renderToNodeStream`์ด ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -## ์ด ๋ฐ–์˜ ํš๊ธฐ์ ์ธ ๋ณ€ํ™” {/*other-breaking-changes*/} +## ์ด ๋ฐ–์˜ ์ฃผ์š”ํ•œ ๋ณ€ํ™”<sup>Breaking Changes</sup> {/*other-breaking-changes*/} -* **์ผ๊ด€๋œ useEffect ํƒ€์ด๋ฐ**: click์ด๋‚˜ keydown ์ด๋ฒคํŠธ์™€ ๊ฐ™์€ ๊ฐœ๋ณ„์ ์ธ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ด๋ฒคํŠธ ์ค‘์— ์—…๋ฐ์ดํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋œ ๊ฒฝ์šฐ React๋Š” ํ•ญ์ƒ ๋™๊ธฐ์ ์œผ๋กœ ์ดํŽ™ํŠธ ํ•จ์ˆ˜๋ฅผ ํ”Œ๋Ÿฌ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด์ „์—๋Š” ๋™์ž‘์ด ์–ธ์ œ๋‚˜ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ฑฐ๋‚˜ ์ผ๊ด€์ ์ด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. -* **Hydration ์˜ค๋ฅ˜ ๊ฐ•ํ™”**: ํ…์ŠคํŠธ ์ฝ˜ํ…์ธ ๊ฐ€ ๋ˆ„๋ฝ๋˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€๋˜์–ด Hydration ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ์ด์ œ ๊ฒฝ๊ณ ๊ฐ€ ์•„๋‹Œ ์˜ค๋ฅ˜๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. React๋Š” ๋” ์ด์ƒ ์„œ๋ฒ„ ๋งˆํฌ์—…๊ณผ ์ผ์น˜์‹œํ‚ค๊ธฐ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ์—์„œ ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜์—ฌ ๊ฐœ๋ณ„ ๋…ธ๋“œ๋ฅผ "ํŒจ์น˜ ์—…" ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<Suspense>` ๋ฐ”์šด๋”๋ฆฌ๊นŒ์ง€ ํด๋ผ์ด์–ธํŠธ ๋ Œ๋”๋ง์œผ๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Hydration ํŠธ๋ฆฌ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  Hydration ๋ถˆ์ผ์น˜๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ž ์žฌ์ ์ธ ๊ฐœ์ธ์ •๋ณด ๋ณดํ˜ธ ๋ฐ ๋ณด์•ˆ ํ—ˆ์ ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* **์ผ๊ด€๋œ `useEffect` ํƒ€์ด๋ฐ**: ํด๋ฆญ์ด๋‚˜ Keydown ์ด๋ฒคํŠธ์™€ ๊ฐ™์€ ๊ฐœ๋ณ„์ ์ธ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ด๋ฒคํŠธ ์ค‘์— ์—…๋ฐ์ดํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋œ ๊ฒฝ์šฐ React๋Š” ํ•ญ์ƒ ๋™๊ธฐ์ ์œผ๋กœ ์ดํŽ™ํŠธ ํ•จ์ˆ˜๋ฅผ ํ”Œ๋Ÿฌ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด์ „์—๋Š” ๋™์ž‘์ด ์–ธ์ œ๋‚˜ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ฑฐ๋‚˜ ์ผ๊ด€์ ์ด์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. +* **Hydration ์˜ค๋ฅ˜ ๊ฐ•ํ™”**: ํ…์ŠคํŠธ ์ฝ˜ํ…์ธ ๊ฐ€ ๋ˆ„๋ฝ๋˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€๋˜์–ด Hydration ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ, ์ด์ œ ๊ฒฝ๊ณ ๊ฐ€ ์•„๋‹Œ ์˜ค๋ฅ˜๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. React๋Š” ๋” ์ด์ƒ ์„œ๋ฒ„ ๋งˆํฌ์—…๊ณผ ์ผ์น˜์‹œํ‚ค๊ธฐ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ์—์„œ ๋…ธ๋“œ๋ฅผ ์‚ฝ์ž…ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜์—ฌ ๊ฐœ๋ณ„ ๋…ธ๋“œ๋ฅผ "ํŒจ์น˜ ์—…" ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<Suspense>` ๋ฐ”์šด๋”๋ฆฌ๊นŒ์ง€ ํด๋ผ์ด์–ธํŠธ ๋ Œ๋”๋ง์œผ๋กœ ๋˜๋Œ๋ฆฝ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Hydration ํŠธ๋ฆฌ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  Hydration ๋ถˆ์ผ์น˜๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ž ์žฌ์ ์ธ ๊ฐœ์ธ์ •๋ณด ๋ณดํ˜ธ ๋ฐ ๋ณด์•ˆ ํ—ˆ์ ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **ํ•ญ์ƒ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋Š” Suspense ํŠธ๋ฆฌ**: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํŠธ๋ฆฌ์— ์™„์ „ํžˆ ์ถ”๊ฐ€๋˜๊ธฐ ์ „์— ์ผ์‹œ ์ค‘๋‹จ๋˜๋ฉด React๋Š” ๋ถˆ์™„์ „ํ•œ ์ƒํƒœ๋กœ ํŠธ๋ฆฌ์— ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ทธ ์ดํŽ™ํŠธ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  React๋Š” ์ƒˆ ํŠธ๋ฆฌ๋ฅผ ์™„์ „ํžˆ ๋ฒ„๋ฆฌ๊ณ  ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ๋‹ค์Œ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋ Œ๋”๋ง์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. React๋Š” ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋ธ”๋กœํ‚นํ•˜์ง€ ์•Š๊ณ  ๋‹ค์‹œ ์‹œ๋„ํ•ด ๋™์‹œ์— ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. -* **Suspense๊ฐ€ ์žˆ๋Š” ๋ ˆ์ด์•„์›ƒ ํšจ๊ณผ**: ํŠธ๋ฆฌ๊ฐ€ ๋‹ค์‹œ ์ผ์‹œ ์ค‘๋‹จ๋˜๊ณ  fallback์œผ๋กœ ๋˜๋Œ์•„๊ฐˆ ๋•Œ, React๋Š” ๋ ˆ์ด์•„์›ƒ ํšจ๊ณผ๋ฅผ ์ •๋ฆฌ(clean-up)ํ•œ ํ›„ ๊ฒฝ๊ณ„ ์•ˆ์˜ ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ค์‹œ ํ‘œ์‹œ๋  ๋•Œ ๋ ˆ์ด์•„์›ƒ ํšจ๊ณผ๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” Suspense์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ ˆ์ด์•„์›ƒ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ธก์ •ํ•˜์ง€ ๋ชปํ•˜๋˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. +* **Suspense๊ฐ€ ์žˆ๋Š” ๋ ˆ์ด์•„์›ƒ ํšจ๊ณผ**: ํŠธ๋ฆฌ๊ฐ€ ๋‹ค์‹œ ์ผ์‹œ ์ค‘๋‹จ๋˜๊ณ  Fallback์œผ๋กœ ๋˜๋Œ์•„๊ฐˆ ๋•Œ, React๋Š” ๋ ˆ์ด์•„์›ƒ ํšจ๊ณผ๋ฅผ ์ •๋ฆฌ<sup>Clean Up</sup>ํ•œ ํ›„ ๊ฒฝ๊ณ„ ์•ˆ์˜ ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ค์‹œ ํ‘œ์‹œ๋  ๋•Œ ๋ ˆ์ด์•„์›ƒ ํšจ๊ณผ๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” Suspense์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ ˆ์ด์•„์›ƒ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ธก์ •ํ•˜์ง€ ๋ชปํ•˜๋˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. * **์ƒˆ๋กœ์šด JS ํ™˜๊ฒฝ ์š”๊ตฌ ์‚ฌํ•ญ**: React๋Š” ์ด์ œ `Promise`, `Symbol`, `Object.assign`์„ ํฌํ•จํ•œ ์ตœ์‹  ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋Šฅ์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ์ตœ์‹  ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋Šฅ์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๊ตฌํ˜„์ด ์žˆ๋Š” Internet Explorer์™€ ๊ฐ™์€ ๊ตฌํ˜• ๋ธŒ๋ผ์šฐ์ € ๋ฐ ๊ธฐ๊ธฐ๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ ๋ฒˆ๋“ค๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ „์—ญ ํด๋ฆฌํ•„์„ ํฌํ•จํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜์„ธ์š”. ## ์ด ๋ฐ–์˜ ์ฃผ๋ชฉํ•  ๋งŒํ•œ ๋ณ€ํ™” {/*other-notable-changes*/} ### React {/*react*/} -* **์ด์ œ ์ปดํฌ๋„ŒํŠธ๋“ค์ด `undefined`๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** React๋Š” ๋” ์ด์ƒ ์ปดํฌ๋„ŒํŠธ์—์„œ `undefined`๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ๊ฒฝ๊ณ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ์ปดํฌ๋„ŒํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์˜ ์ค‘๊ฐ„์— ํ—ˆ์šฉ๋œ ๊ฐ’๊ณผ ์ผ๊ด€๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. JSX ์•ž์— `return` ๋ฌธ์„ ๋นผ๋จน๋Š” ์‹ค์ˆ˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฐํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. -* **ํ…Œ์ŠคํŠธ์—์„œ `act` ๊ฒฝ๊ณ ๋Š” ์ด์ œ ์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.** ์ข…๋‹จ ๊ฐ„ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ `act` ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋Š” ๋ถˆํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ์“ธ๋ชจ ์žˆ๋Š” [์œ ๋‹› ํ…Œ์ŠคํŠธ์—์„œ๋งŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก](https://github.com/reactwg/react-18/discussions/102) ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. -* **์ด์ œ ๋งˆ์šดํŠธ๊ฐ€ ํ•ด์ œ๋œ ์ปดํฌ๋„ŒํŠธ์—์„œ `setState` ๊ด€๋ จ ๊ฒฝ๊ณ ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** ์ด์ „์—๋Š” `setState`๋ฅผ ๋งˆ์šดํŠธ๊ฐ€ ํ•ด์ œ๋œ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ˜ธ์ถœํ•  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์— ๋Œ€ํ•œ ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ๊ณ ๋Š” ๊ตฌ๋…์„ ์œ„ํ•ด ์ถ”๊ฐ€๋˜์—ˆ์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ƒํƒœ ์„ค์ •์— ๋ฌธ์ œ๊ฐ€ ์—†์„ ๋•Œ ์ด ๊ฒฝ๊ณ ๋ฅผ ๋งˆ์ฃผ์น˜๊ฒŒ ๋˜์–ด ์ฝ”๋“œ๋ฅผ ๋” ๋‚˜๋น ์ง€๊ฒŒ ๋งŒ๋“œ๋Š” ๋Œ€์•ˆ์„ ์ฐพ์•„์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. React 18์—์„œ๋Š” ์ด ๊ฒฝ๊ณ ๋ฅผ [์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค](https://github.com/facebook/react/pull/22114). -* **๋” ์ด์ƒ ์ฝ˜์†” ๋กœ๊ทธ๋ฅผ ์–ต์ œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** Strict ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ React๋Š” ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ถ€์ž‘์šฉ์„ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‘ ๋ฒˆ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. React 17์—์„œ๋Š” ๋‘ ๋ฒˆ์งธ ๋ Œ๋”๋ง์˜ ์ฝ˜์†” ๋กœ๊ทธ๋ฅผ ์–ต์ œํ•˜์—ฌ ๋กœ๊ทธ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ [์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ํ”ผ๋“œ๋ฐฑ](https://github.com/facebook/react/issues/21783)์— ๋”ฐ๋ผ ์ด ์–ต์ œ๋ฅผ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ React DevTools๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๋‹ค๋ฉด ๋‘ ๋ฒˆ์งธ ๋กœ๊ทธ์˜ ๋ Œ๋”๋ง์ด ํšŒ์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋˜๋ฉฐ ์™„์ „ํžˆ ์–ต์ œํ•˜๋Š” ์˜ต์…˜๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (๊ธฐ๋ณธ์ ์œผ๋กœ ๊บผ์ ธ ์žˆ์Œ) -* **๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.** React๋Š” ์ด์ œ ๋งˆ์šดํŠธ๊ฐ€ ํ•ด์ œ๋  ๋•Œ ๋” ๋งŽ์€ ๋‚ด๋ถ€ ํ•„๋“œ๋ฅผ ์ •๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ์— ์กด์žฌํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ •๋˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์˜ ์˜ํ–ฅ์„ ๋œ ์‹ฌํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. +* **์ด์ œ ์ปดํฌ๋„ŒํŠธ๋“ค์ด `undefined`๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** React๋Š” ๋” ์ด์ƒ ์ปดํฌ๋„ŒํŠธ์—์„œ `undefined`๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ ๊ฒฝ๊ณ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ์ปดํฌ๋„ŒํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์˜ ์ค‘๊ฐ„์— ํ—ˆ์šฉ๋œ ๊ฐ’๊ณผ ์ผ๊ด€๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. JSX ์•ž์— `return` ๋ฌธ์„ ๋นผ๋จน๋Š” ์‹ค์ˆ˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฐํ„ฐ<sup>Linter</sup>๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. +* **ํ…Œ์ŠคํŠธ์—์„œ `act` ๊ฒฝ๊ณ ๋Š” ์ด์ œ ์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.** E2E<sup>End-to-End</sup> ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ `act` ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋Š” ๋ถˆํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๊ฐ€ ์“ธ๋ชจ ์žˆ๋Š” [์œ ๋‹› ํ…Œ์ŠคํŠธ์—์„œ๋งŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก](https://github.com/reactwg/react-18/discussions/102) ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. +* **์ด์ œ ๋งˆ์šดํŠธ๊ฐ€ ํ•ด์ œ๋œ ์ปดํฌ๋„ŒํŠธ์—์„œ `setState` ๊ด€๋ จ ๊ฒฝ๊ณ ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** ์ด์ „์—๋Š” `setState`๋ฅผ ๋งˆ์šดํŠธ๊ฐ€ ํ•ด์ œ๋œ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ˜ธ์ถœํ•  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์— ๋Œ€ํ•œ ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ๊ณ ๋Š” ๊ตฌ๋…์„ ์œ„ํ•ด ์ถ”๊ฐ€๋˜์—ˆ์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์ƒํƒœ ์„ค์ •์— ๋ฌธ์ œ๊ฐ€ ์—†์„ ๋•Œ ์ด ๊ฒฝ๊ณ ๋ฅผ ๋งˆ์ฃผํ•˜๊ฒŒ ๋˜์–ด ์ฝ”๋“œ๋ฅผ ๋” ๋‚˜์˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋Œ€์•ˆ์„ ์ฐพ์•„์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. React 18์—์„œ๋Š” ์ด ๊ฒฝ๊ณ ๋ฅผ [์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค](https://github.com/facebook/react/pull/22114). +* **๋” ์ด์ƒ ์ฝ˜์†” ๋กœ๊ทธ๋ฅผ ์–ต์ œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** Strict ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ React๋Š” ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ถ€์ž‘์šฉ์„ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‘ ๋ฒˆ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. React 17์—์„œ๋Š” ๋‘ ๋ฒˆ์งธ ๋ Œ๋”๋ง์˜ ์ฝ˜์†” ๋กœ๊ทธ๋ฅผ ์–ต์ œํ•˜์—ฌ ๋กœ๊ทธ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ [์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ํ”ผ๋“œ๋ฐฑ](https://github.com/facebook/react/issues/21783)์— ๋”ฐ๋ผ ์ด ์–ต์ œ๋ฅผ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ React DevTools๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๋‹ค๋ฉด ๋‘ ๋ฒˆ์งธ ๋กœ๊ทธ์˜ ๋ Œ๋”๋ง์ด ํšŒ์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋˜๋ฉฐ ์™„์ „ํžˆ ์–ต์ œํ•˜๋Š” ์˜ต์…˜๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (๊ธฐ๋ณธ์ ์œผ๋กœ ๊บผ์ ธ ์žˆ์Œ.) +* **๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.** React๋Š” ์ด์ œ ๋งˆ์šดํŠธ๊ฐ€ ํ•ด์ œ๋  ๋•Œ ๋” ๋งŽ์€ ๋‚ด๋ถ€ ํ•„๋“œ๋ฅผ ์ •๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ์— ์กด์žฌํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ •๋˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์˜ ์˜ํ–ฅ์„ ์ค„์ž…๋‹ˆ๋‹ค. ### React DOM ์„œ๋ฒ„ {/*react-dom-server*/} -* **`renderToString`** ์€ ์ด์ œ ์„œ๋ฒ„์—์„œ ์„œ์ŠคํŽœ๋”ฉํ•  ๋•Œ ๋” ์ด์ƒ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<Suspense>` ๊ฒฝ๊ณ„์— fallback HTML์„ ์ถœ๋ ฅํ•˜๊ณ , ๊ทธ๋Ÿฐ ๋‹ค์Œ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋™์ผํ•œ ์ฝ˜ํ…์ธ ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋„๋ก ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ `renderToPipeableStream` ๋˜๋Š” `renderToReadableStream`๊ณผ ๊ฐ™์€ ์ŠคํŠธ๋ฆฌ๋ฐ API๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. -* **`renderToStaticMarkup`** ์€ ์ด์ œ ์„œ๋ฒ„์—์„œ ์„œ์ŠคํŽœ๋”ฉํ•  ๋•Œ ๋” ์ด์ƒ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<Suspense>` ๊ฒฝ๊ณ„์— fallback HTML์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. +* <strong>`renderToString`</strong>์€ ์ด์ œ ์„œ๋ฒ„์—์„œ Suspendํ•  ๋•Œ ๋” ์ด์ƒ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<Suspense>` ๊ฒฝ๊ณ„์— Fallback HTML์„ ์ถœ๋ ฅํ•˜๊ณ , ๊ทธ๋Ÿฐ ๋‹ค์Œ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋™์ผํ•œ ์ฝ˜ํ…์ธ ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋„๋ก ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ `renderToPipeableStream` ๋˜๋Š” `renderToReadableStream`๊ณผ ๊ฐ™์€ ์ŠคํŠธ๋ฆฌ๋ฐ API๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. +* <strong>`renderToStaticMarkup`</strong>์€ ์ด์ œ ์„œ๋ฒ„์—์„œ Suspendํ•  ๋•Œ ๋” ์ด์ƒ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<Suspense>` ๊ฒฝ๊ณ„์— Fallback HTML์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. -## ๋ณ€๊ฒฝ ๋ช…์„ธ {/*changelog*/} +## ๋ณ€๊ฒฝ ๋‚ด์—ญ {/*changelog*/} -[์—ฌ๊ธฐ์—์„œ ์ „์ฒด ๋ณ€๊ฒฝ ๋ช…์„ธ](https://github.com/facebook/react/blob/main/CHANGELOG.md)๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +[์—ฌ๊ธฐ์„œ ์ „์ฒด ๋ณ€๊ฒฝ ๋‚ด์—ญ](https://github.com/facebook/react/blob/main/CHANGELOG.md)์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/src/content/blog/index.md b/src/content/blog/index.md index 8b9f06d6d..8e0787649 100644 --- a/src/content/blog/index.md +++ b/src/content/blog/index.md @@ -65,7 +65,7 @@ React 18์€ ์ˆ˜๋…„๊ฐ„์˜ ์ค€๋น„ ๋์— ํƒ„์ƒํ•œ ๋ฒ„์ „์œผ๋กœ React ํŒ€์—๊ฒŒ </BlogCard> <BlogCard title="React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•" date="2022๋…„ 3์›” 8์ผ" url="/blog/2022/03/08/react-18-upgrade-guide"> -React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ, ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ, ์ƒˆ๋กœ์šด ๋™์‹œ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. </BlogCard> <BlogCard title="React Conf 2021 ์š”์•ฝ" date="2021๋…„ 12์›” 17์ผ" url="/blog/2021/12/17/react-conf-2021-recap"> From 1a371141382a44f14f3885d0acf09029ef8a5a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 01:52:28 +0900 Subject: [PATCH 0353/1059] docs: update `learn/index.md` --- src/content/learn/index.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/content/learn/index.md b/src/content/learn/index.md index 509268fc5..dfe86ba5e 100644 --- a/src/content/learn/index.md +++ b/src/content/learn/index.md @@ -4,11 +4,7 @@ title: ๋น ๋ฅด๊ฒŒ ์‹œ์ž‘ํ•˜๊ธฐ <Intro> -<<<<<<< HEAD React ๋ฌธ์„œ์— ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! ์ด ํŽ˜์ด์ง€์—์„œ๋Š” ์—ฌ๋Ÿฌ๋ถ„์ด ๋งค์ผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋  React ๊ฐœ๋…์˜ 80%๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. -======= -Welcome to the React documentation! This page will give you an introduction to 80% of the React concepts that you will use on a daily basis. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc </Intro> From 3ca7d66fff7a9e846ec7870a5a2e88346a781d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 14:28:37 +0900 Subject: [PATCH 0354/1059] docs: update `useDeferredValue.md` --- .../reference/react/useDeferredValue.md | 174 +++--------------- 1 file changed, 29 insertions(+), 145 deletions(-) diff --git a/src/content/reference/react/useDeferredValue.md b/src/content/reference/react/useDeferredValue.md index f810701c3..2de21b873 100644 --- a/src/content/reference/react/useDeferredValue.md +++ b/src/content/reference/react/useDeferredValue.md @@ -4,7 +4,7 @@ title: useDeferredValue <Intro> -`useDeferredValue`๋Š” UI ์ผ๋ถ€ ์—…๋ฐ์ดํŠธ๋ฅผ ์ง€์—ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” React Hook์ž…๋‹ˆ๋‹ค. +`useDeferredValue`๋Š” ์ผ๋ถ€ UI ์—…๋ฐ์ดํŠธ๋ฅผ ์ง€์—ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” React Hook์ž…๋‹ˆ๋‹ค. ```js const deferredValue = useDeferredValue(value) @@ -32,47 +32,32 @@ function SearchPage() { } ``` -[์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.](#usage) +[์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”](#usage). #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} -<<<<<<< HEAD * `value`: ์ง€์—ฐ์‹œํ‚ค๋ ค๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ํƒ€์ž…์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -* <CanaryBadge title="This feature is only available in the Canary channel" /> **optional** `initialValue`: A value to use during the initial render of a component. If this option is omitted, `useDeferredValue` will not defer during the initial render, because there's no previous version of `value` that it can render instead. -======= -* `value`: The value you want to defer. It can have any type. * **optional** `initialValue`: A value to use during the initial render of a component. If this option is omitted, `useDeferredValue` will not defer during the initial render, because there's no previous version of `value` that it can render instead. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc - #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} -<<<<<<< HEAD - -- `currentValue`: ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์ค‘์—๋Š” ๋ฐ˜ํ™˜๋œ '์ง€์—ฐ๋œ ๊ฐ’'์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ œ๊ณตํ•œ ๊ฐ’๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด React๋Š” ๋จผ์ € ์ด์ „ ๊ฐ’์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง์„ ์‹œ๋„(๋ฐ˜ํ™˜๊ฐ’์ด ์ด์ „ ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋„๋ก)ํ•˜๊ณ , ๊ทธ๋‹ค์Œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋‹ค์‹œ ์ƒˆ ๊ฐ’์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง์„ ์‹œ๋„(๋ฐ˜ํ™˜๊ฐ’์ด ์—…๋ฐ์ดํŠธ๋œ ์ƒˆ ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋„๋ก)ํ•ฉ๋‹ˆ๋‹ค. - -<Canary> - -In the latest React Canary versions, `useDeferredValue` returns the `initialValue` on initial render, and schedules a re-render in the background with the `value` returned. - -</Canary> -======= -- `currentValue`: During the initial render, the returned deferred value will be the `initialValue`, or the same as the value you provided. During updates, React will first attempt a re-render with the old value (so it will return the old value), and then try another re-render in the background with the new value (so it will return the updated value). ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +- `currentValue`: ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์ค‘ ๋ฐ˜ํ™˜๋œ '์ง€์—ฐ๋œ ๊ฐ’'์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ œ๊ณตํ•œ ๊ฐ’๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด React๋Š” ๋จผ์ € ์ด์ „ ๊ฐ’์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง์„ ์‹œ๋„(๋ฐ˜ํ™˜๊ฐ’์ด ์ด์ „ ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋„๋ก)ํ•˜๊ณ , ๊ทธ ๋‹ค์Œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋‹ค์‹œ ์ƒˆ ๊ฐ’์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง์„ ์‹œ๋„(๋ฐ˜ํ™˜๊ฐ’์ด ์—…๋ฐ์ดํŠธ๋œ ์ƒˆ ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋„๋ก)ํ•ฉ๋‹ˆ๋‹ค. #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} +- When an update is inside a Transition, `useDeferredValue` always returns the new `value` and does not spawn a deferred render, since the update is already deferred. + - `useDeferredValue`์— ์ „๋‹ฌํ•˜๋Š” ๊ฐ’์€ ๋ฌธ์ž์—ด ๋ฐ ์ˆซ์ž์™€ ๊ฐ™์€ ์›์‹œ๊ฐ’์ด๊ฑฐ๋‚˜, ์ปดํฌ๋„ŒํŠธ์˜ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋œ ๊ฐ์ฒด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ์ค‘์— ์ƒˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ฆ‰์‹œ `useDeferredValue`์— ์ „๋‹ฌํ•˜๋ฉด ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ’์ด ๋‹ฌ๋ผ์ ธ ๋ถˆํ•„์š”ํ•œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- `useDeferredValue`๊ฐ€ ํ˜„์žฌ ๋ Œ๋”๋ง(์—ฌ์ „ํžˆ ์ด์ „ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ) ์™ธ์— ๋‹ค๋ฅธ ๊ฐ’([`Object.is`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/is)๋กœ ๋น„๊ต)์„ ๋ฐ›์œผ๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ƒˆ ๊ฐ’์œผ๋กœ ๋ฆฌ๋ Œ๋”๋งํ•˜๋„๋ก ์˜ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค. `๊ฐ’`์— ๋Œ€ํ•œ ๋˜ ๋‹ค๋ฅธ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์œผ๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง์€ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ฐจํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๊ฐ€๋Šฅํ•œ ์ง€์—ฐ๋œ ๊ฐ’์„ ๋ฐ›๋Š” ์†๋„๋ณด๋‹ค ์‚ฌ์šฉ์ž๊ฐ€ input์— ๊ฐ’์„ ์ž…๋ ฅํ•˜๋Š” ์†๋„๊ฐ€ ๋” ๋น ๋ฅธ ๊ฒฝ์šฐ, ์ฐจํŠธ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ์„ ๋ฉˆ์ถ˜ ํ›„์—๋งŒ ๋ฆฌ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. +- `useDeferredValue`๊ฐ€ ํ˜„์žฌ ๋ Œ๋”๋ง(์—ฌ์ „ํžˆ ์ด์ „ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ) ์™ธ์— ๋‹ค๋ฅธ ๊ฐ’([`Object.is`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/is)๋กœ ๋น„๊ต)์„ ๋ฐ›์œผ๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ƒˆ ๊ฐ’์œผ๋กœ ๋ฆฌ๋ Œ๋”๋งํ•˜๋„๋ก ์˜ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค. `value`์— ๋Œ€ํ•œ ๋˜ ๋‹ค๋ฅธ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์œผ๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง์€ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ฐจํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๊ฐ€๋Šฅํ•œ ์ง€์—ฐ๋œ ๊ฐ’์„ ๋ฐ›๋Š” ์†๋„๋ณด๋‹ค ์‚ฌ์šฉ์ž๊ฐ€ Input์— ๊ฐ’์„ ์ž…๋ ฅํ•˜๋Š” ์†๋„๊ฐ€ ๋” ๋น ๋ฅธ ๊ฒฝ์šฐ, ์ฐจํŠธ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅ์„ ๋ฉˆ์ถ˜ ํ›„์—๋งŒ ๋ฆฌ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. -- `useDeferredValue`๋Š” [`<Suspense>`](/reference/react/Suspense)์™€ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๊ฐ’์œผ๋กœ ์ธํ•œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•ด UI๊ฐ€ ์ผ์‹œ ์ค‘๋‹จ๋˜๋ฉด ์‚ฌ์šฉ์ž๋Š” ํด๋ฐฑ์„ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ๊นŒ์ง€ ์ด์ „ ์ง€์—ฐ๋œ ๊ฐ’์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. +- `useDeferredValue`๋Š” [`<Suspense>`](/reference/react/Suspense)์™€ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๊ฐ’์œผ๋กœ ์ธํ•œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•ด UI๊ฐ€ ์ผ์‹œ ์ค‘๋‹จ๋˜๋ฉด ์‚ฌ์šฉ์ž๋Š” Fallback์„ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ๊นŒ์ง€ ์ด์ „ ์ง€์—ฐ๋œ ๊ฐ’์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. - `useDeferredValue`๋Š” ๊ทธ ์ž์ฒด๋กœ ์ถ”๊ฐ€ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ฐฉ์ง€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. - `useDeferredValue` ์ž์ฒด๋กœ ์ธํ•œ ๊ณ ์ •๋œ ์ง€์—ฐ์€ ์—†์Šต๋‹ˆ๋‹ค. React๋Š” ์›๋ž˜์˜ ๋ฆฌ๋ Œ๋”๋ง์„ ์™„๋ฃŒํ•˜์ž๋งˆ์ž ์ฆ‰์‹œ ์ƒˆ๋กœ์šด ์ง€์—ฐ๋œ ๊ฐ’์œผ๋กœ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง ์ž‘์—…์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋ฒคํŠธ๋กœ ์ธํ•œ ์—…๋ฐ์ดํŠธ(์˜ˆ: ํƒ€์ดํ•‘)๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง์„ ์ค‘๋‹จํ•˜๊ณ  ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. -- `useDeferredValue`๋กœ ์ธํ•œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง์€ ํ™”๋ฉด์— ์ปค๋ฐ‹๋  ๋•Œ๊นŒ์ง€ Effects๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง์ด ์ผ์‹œ ์ค‘๋‹จ๋˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋”ฉ๋˜๊ณ  UI๊ฐ€ ์—…๋ฐ์ดํŠธ๋œ ํ›„์— ํ•ด๋‹น Effects๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +- `useDeferredValue`๋กœ ์ธํ•œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง์€ ํ™”๋ฉด์— ์ปค๋ฐ‹๋  ๋•Œ๊นŒ์ง€ Effect๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌ๋ Œ๋”๋ง์ด ์ผ์‹œ ์ค‘๋‹จ๋˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋”ฉ๋˜๊ณ  UI๊ฐ€ ์—…๋ฐ์ดํŠธ๋œ ํ›„์— ํ•ด๋‹น Effect๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. --- @@ -101,18 +86,18 @@ function SearchPage() { <Note> -์ด ์˜ˆ์‹œ์—์„œ๋Š” Suspense ์ง€์› ๋ฐ์ดํ„ฐ ์†Œ์Šค ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค +์ด ์˜ˆ์‹œ์—์„œ๋Š” Suspense ์ง€์› ๋ฐ์ดํ„ฐ ์†Œ์Šค ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. -- [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/)์™€ [Next.js](https://nextjs.org/docs/getting-started/react-essentials) ๊ฐ™์ด Suspense๊ฐ€ ๊ฐ€๋Šฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ -- [`lazy`](/reference/react/lazy)๋ฅผ ํ™œ์šฉํ•œ ์ง€์—ฐ ๋กœ๋”ฉ ์ปดํฌ๋„ŒํŠธ -- [`use`](/reference/react/use)๋ฅผ ์‚ฌ์šฉํ•ด์„œ Promise ๊ฐ’ ์ฝ๊ธฐ +- [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/)์™€ [Next.js](https://nextjs.org/docs/getting-started/react-essentials) ๊ฐ™์ด Suspense๊ฐ€ ๊ฐ€๋Šฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ. +- [`lazy`](/reference/react/lazy)๋ฅผ ํ™œ์šฉํ•œ ์ง€์—ฐ ๋กœ๋”ฉ ์ปดํฌ๋„ŒํŠธ. +- [`use`](/reference/react/use)๋ฅผ ์‚ฌ์šฉํ•ด์„œ Promise ๊ฐ’ ์ฝ๊ธฐ. -[Suspense์™€ ๊ทธ ํ•œ๊ณ„ ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ](/reference/react/Suspense) +[Suspense์™€ ๊ทธ ํ•œ๊ณ„์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ](/reference/react/Suspense). </Note> -์ด ์˜ˆ์‹œ์—์„œ๋Š” ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋™์•ˆ `SearchResults` ์ปดํฌ๋„ŒํŠธ๊ฐ€ [์ผ์‹œ ์ค‘์ง€](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading)๋ฉ๋‹ˆ๋‹ค. `"a"`๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ ๋‹ค์Œ `"ab"`๋กœ ์ˆ˜์ •ํ•ด ๋ณด์„ธ์š”. `"a"`์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋กœ๋”ฉ ํด๋ฐฑ์œผ๋กœ ๋Œ€์ฒด๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ๋Š” ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋™์•ˆ `SearchResults` ์ปดํฌ๋„ŒํŠธ๊ฐ€ [์ผ์‹œ ์ค‘์ง€<sup>Suspend</sup>](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading)๋ฉ๋‹ˆ๋‹ค. `"a"`๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ ๋‹ค์Œ `"ab"`๋กœ ์ˆ˜์ •ํ•ด ๋ณด์„ธ์š”. `"a"`์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋กœ๋”ฉ ํด๋ฐฑ์œผ๋กœ ๋Œ€์ฒด๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. <Sandpack> @@ -158,34 +143,6 @@ export default function SearchResults({ query }) { </ul> ); } -<<<<<<< HEAD - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ``` ```js src/data.js hidden @@ -307,28 +264,11 @@ export default function App() { } ``` -`query`๋Š” ์ฆ‰์‹œ ์—…๋ฐ์ดํŠธ๋˜๋ฏ€๋กœ input์— ์ƒˆ ๊ฐ’์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ `deferredQuery`๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ๊นŒ์ง€ ์ด์ „ ๊ฐ’์„ ์œ ์ง€ํ•˜๋ฏ€๋กœ `SearchResults`๋Š” ์ž ์‹œ ๋™์•ˆ ์˜ค๋ž˜๋œ ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. +`query`๋Š” ์ฆ‰์‹œ ์—…๋ฐ์ดํŠธ๋˜๋ฏ€๋กœ Input์— ์ƒˆ ๊ฐ’์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ `deferredQuery`๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ๊นŒ์ง€ ์ด์ „ ๊ฐ’์„ ์œ ์ง€ํ•˜๋ฏ€๋กœ `SearchResults`๋Š” ์ž ์‹œ ๋™์•ˆ ์˜ค๋ž˜๋œ ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `"a"`๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๊ฒฐ๊ณผ๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ๋‹ค์Œ, ์ž…๋ ฅ๊ฐ’์„ `"ab"`๋กœ ์ˆ˜์ •ํ•ด๋ณด์„ธ์š”. ์ด์ œ ์ƒˆ ๊ฒฐ๊ณผ๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ๊นŒ์ง€ Suspense ํด๋ฐฑ ๋Œ€์‹  ์˜ค๋ž˜๋œ ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `"a"`๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๊ฒฐ๊ณผ๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ๋‹ค์Œ, ์ž…๋ ฅ๊ฐ’์„ `"ab"`๋กœ ์ˆ˜์ •ํ•ด๋ณด์„ธ์š”. ์ด์ œ ์ƒˆ ๊ฒฐ๊ณผ๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ๊นŒ์ง€ Suspense ํด๋ฐฑ ๋Œ€์‹  ์˜ค๋ž˜๋œ ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <Sandpack> -<<<<<<< HEAD -```json package.json hidden -{ - "dependencies": { - "react": "experimental", - "react-dom": "experimental" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test --env=jsdom", - "eject": "react-scripts eject" - } -} -``` -======= ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ```js src/App.js import { Suspense, useState, useDeferredValue } from 'react'; @@ -373,34 +313,6 @@ export default function SearchResults({ query }) { </ul> ); } -<<<<<<< HEAD - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ``` ```js src/data.js hidden @@ -505,13 +417,14 @@ input { margin: 10px; } <DeepDive> #### ๊ฐ’์„ ์ง€์—ฐ์‹œํ‚ค๋Š” ๊ฒƒ์€ ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋‚˜์š”? {/*how-does-deferring-a-value-work-under-the-hood*/} -๋‘ ๋‹จ๊ณ„๋กœ ์ง„ํ–‰๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค + +๋‘ ๋‹จ๊ณ„๋กœ ์ง„ํ–‰๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. 1. **๋จผ์ €, React๋Š” ์ƒˆ๋กœ์šด `query`(`"ab"`)๋กœ ๋ฆฌ๋ Œ๋”๋งํ•˜์ง€๋งŒ ์ด์ „ `deferredQuery`(์—ฌ์ „ํžˆ `"a"`)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.** ๊ฒฐ๊ณผ ๋ชฉ๋ก์— ์ „๋‹ฌํ•˜๋Š” `deferredQuery` ๊ฐ’์€ "์ง€์—ฐ"๋œ `query` ๊ฐ’์ž…๋‹ˆ๋‹ค. 2. **๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ React๋Š” `query`์™€ `deferredQuery`๋ฅผ ๋ชจ๋‘ `"ab"`๋กœ ์—…๋ฐ์ดํŠธํ•œ ์ƒํƒœ๋กœ ๋ฆฌ๋ Œ๋”๋ง์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.** ์ด ๋ฆฌ๋ Œ๋”๋ง์ด ์™„๋ฃŒ๋˜๋ฉด React๋Š” ์ด๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ผ์‹œ ์ค‘๋‹จ๋˜๋Š” ๊ฒฝ์šฐ(`"ab"`์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ์•„์ง ๋กœ๋”ฉ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ) React๋Š” ์ด ๋ Œ๋”๋ง ์‹œ๋„๋ฅผ ํฌ๊ธฐํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋”ฉ๋œ ํ›„ ์ด ๋ฆฌ๋ Œ๋”๋ง์„ ๋‹ค์‹œ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ์˜ค๋ž˜๋œ ์ง€์—ฐ๋œ ๊ฐ’์„ ๊ณ„์† ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -์ง€์—ฐ๋œ "background" ๋ Œ๋”๋ง์€ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด input์„ ๋‹ค์‹œ ์ž…๋ ฅํ•˜๋ฉด React๋Š” ์ง€์—ฐ๋œ ๊ฐ’์„ ๋ฒ„๋ฆฌ๊ณ  ์ƒˆ ๊ฐ’์œผ๋กœ ๋‹ค์‹œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. React๋Š” ํ•ญ์ƒ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ œ๊ณต๋ฐ›์€ ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +์ง€์—ฐ๋œ "background" ๋ Œ๋”๋ง์€ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Input์„ ๋‹ค์‹œ ์ž…๋ ฅํ•˜๋ฉด React๋Š” ์ง€์—ฐ๋œ ๊ฐ’์„ ๋ฒ„๋ฆฌ๊ณ  ์ƒˆ ๊ฐ’์œผ๋กœ ๋‹ค์‹œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. React๋Š” ํ•ญ์ƒ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ œ๊ณต๋ฐ›์€ ๊ฐ’์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ ๊ฐ ํ‚ค ์ž…๋ ฅ๋งˆ๋‹ค ๋„คํŠธ์›Œํฌ ์š”์ฒญ์ด ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•˜์„ธ์š”. ์—ฌ๊ธฐ์„œ ์ง€์—ฐ๋˜๋Š” ๊ฒƒ์€ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์ž์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๊ณ„์† ์ž…๋ ฅํ•˜๋”๋ผ๋„ ๊ฐ ํ‚ค ์ž…๋ ฅ์— ๋Œ€ํ•œ ์‘๋‹ต์€ ์บ์‹œ ๋˜๋ฏ€๋กœ ๋ฐฑ์ŠคํŽ˜์ด์Šค๋ฅผ ๋ˆ„๋ฅด๋ฉด ์ฆ‰์‹œ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @@ -521,8 +434,7 @@ input { margin: 10px; } ### ์ฝ˜ํ…์ธ ๊ฐ€ ์˜ค๋ž˜๋˜์—ˆ์Œ์„ ํ‘œ์‹œํ•˜๊ธฐ {/*indicating-that-the-content-is-stale*/} -์œ„์˜ ์˜ˆ์—์„œ๋Š” ์ตœ์‹  ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ์•„์ง ๋กœ๋”ฉ ์ค‘์ด๋ผ๋Š” ํ‘œ์‹œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ƒˆ ๊ฒฐ๊ณผ๋ฅผ ๋กœ๋”ฉํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ˜ผ๋ž€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ์ตœ์‹  ์ฟผ๋ฆฌ์™€ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ๋ฆฌ๊ธฐ ์œ„ํ•ด, ์˜ค๋ž˜๋œ ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ํ‘œ์‹œ๋  ๋•Œ ์‹œ๊ฐ์  ํ‘œ์‹œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - +์œ„ ์˜ˆ์‹œ์—์„œ๋Š” ์ตœ์‹  ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ์•„์ง ๋กœ๋”ฉ ์ค‘์ด๋ผ๋Š” ํ‘œ์‹œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ƒˆ ๊ฒฐ๊ณผ๋ฅผ ๋กœ๋”ฉํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ˜ผ๋ž€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ์ตœ์‹  ์ฟผ๋ฆฌ์™€ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ๋ฆฌ๊ธฐ ์œ„ํ•ด, ์˜ค๋ž˜๋œ ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ํ‘œ์‹œ๋  ๋•Œ ์‹œ๊ฐ์  ํ‘œ์‹œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {2} <div style={{ @@ -532,7 +444,7 @@ input { margin: 10px; } </div> ``` -์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝํ•˜๋ฉด ์ž…๋ ฅ์„ ์‹œ์ž‘ํ•˜์ž๋งˆ์ž ์ƒˆ ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ๋กœ๋”ฉ๋  ๋•Œ๊นŒ์ง€ ์˜ค๋ž˜๋œ ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ์•ฝ๊ฐ„ ์–ด๋‘์›Œ์ง‘๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ์™€ ๊ฐ™์ด ์ ์ง„์ ์œผ๋กœ ์–ด๋‘์›Œ์ง„๋‹ค๊ณ  ๋А๊ปด์ง€๋„๋ก CSS transition์„ ์ถ”๊ฐ€ํ•˜์—ฌ ํ๋ฆฌ๊ฒŒ ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ์„ ์ง€์—ฐ์‹œํ‚ฌ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝํ•˜๋ฉด ์ž…๋ ฅ์„ ์‹œ์ž‘ํ•˜์ž๋งˆ์ž ์ƒˆ ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ๋กœ๋”ฉ๋  ๋•Œ๊นŒ์ง€ ์˜ค๋ž˜๋œ ๊ฒฐ๊ณผ ๋ชฉ๋ก์ด ์•ฝ๊ฐ„ ์–ด๋‘์›Œ์ง‘๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ์™€ ๊ฐ™์ด ์ ์ง„์ ์œผ๋กœ ์–ด๋‘์›Œ์ง„๋‹ค๊ณ  ๋А๊ปด์ง€๋„๋ก CSS Transition์„ ์ถ”๊ฐ€ํ•˜์—ฌ ํ๋ฆฌ๊ฒŒ ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ์„ ์ง€์—ฐ์‹œํ‚ฌ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. <Sandpack> @@ -585,34 +497,6 @@ export default function SearchResults({ query }) { </ul> ); } -<<<<<<< HEAD - -// This is a workaround for a bug to get the demo running. -// TODO: replace with real implementation when the bug is fixed. -function use(promise) { - if (promise.status === 'fulfilled') { - return promise.value; - } else if (promise.status === 'rejected') { - throw promise.reason; - } else if (promise.status === 'pending') { - throw promise; - } else { - promise.status = 'pending'; - promise.then( - result => { - promise.status = 'fulfilled'; - promise.value = result; - }, - reason => { - promise.status = 'rejected'; - promise.reason = reason; - }, - ); - throw promise; - } -} -======= ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ``` ```js src/data.js hidden @@ -718,9 +602,9 @@ input { margin: 10px; } ### UI ์ผ๋ถ€์— ๋Œ€ํ•ด ๋ฆฌ๋ Œ๋”๋ง ์ง€์—ฐํ•˜๊ธฐ {/*deferring-re-rendering-for-a-part-of-the-ui*/} -`useDeferredValue`๋ฅผ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋กœ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. UI ์ผ๋ถ€๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ์†๋„๊ฐ€ ๋А๋ฆฌ๊ณ , ์ด๋ฅผ ์ตœ์ ํ™”ํ•  ์‰ฌ์šด ๋ฐฉ๋ฒ•์ด ์—†์œผ๋ฉฐ, ๋‚˜๋จธ์ง€ UI๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. +`useDeferredValue`๋ฅผ ์„ฑ๋Šฅ ์ตœ์ ํ™” ์šฉ๋„๋กœ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. UI ์ผ๋ถ€์˜ ๋ฆฌ๋ Œ๋”๋ง ์†๋„๊ฐ€ ๋А๋ฆฌ๊ณ , ์ด๋ฅผ ์ตœ์ ํ™”ํ•  ์‰ฌ์šด ๋ฐฉ๋ฒ•์ด ์—†์œผ๋ฉฐ, ๋‚˜๋จธ์ง€ UI๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๋„๋ก ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -ํ‚ค ์ž…๋ ฅ ์‹œ๋งˆ๋‹ค ๋ฆฌ๋ Œ๋”๋ง๋˜๋Š” ํ…์ŠคํŠธ ํ•„๋“œ์™€ ์ปดํฌ๋„ŒํŠธ(์˜ˆ: ์ฐจํŠธ ๋˜๋Š” ๊ธด ๋ชฉ๋ก)๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ณด์„ธ์š” +ํ‚ค ์ž…๋ ฅ ์‹œ๋งˆ๋‹ค ๋ฆฌ๋ Œ๋”๋ง๋˜๋Š” ํ…์ŠคํŠธ ํ•„๋“œ์™€ ์ปดํฌ๋„ŒํŠธ(์˜ˆ: ์ฐจํŠธ ๋˜๋Š” ๊ธด ๋ชฉ๋ก)๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ณด์„ธ์š”. ```js function App() { @@ -734,7 +618,7 @@ function App() { } ``` -๋จผ์ €, props๊ฐ€ ๊ฐ™์€ ๊ฒฝ์šฐ ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ฐ๋„๋ก `SlowList`๋ฅผ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด, [`memo`](/reference/react/memo#skipping-re-rendering-when-props-are-unchanged)๋กœ ๊ฐ์‹ธ์ฃผ์„ธ์š”. +๋จผ์ €, Props๊ฐ€ ๊ฐ™์€ ๊ฒฝ์šฐ ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ฐ๋„๋ก `SlowList`๋ฅผ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด, [`memo`](/reference/react/memo#skipping-re-rendering-when-props-are-unchanged)๋กœ ๊ฐ์‹ธ์ฃผ์„ธ์š”. ```js {1,3} const SlowList = memo(function SlowList({ text }) { @@ -742,9 +626,9 @@ const SlowList = memo(function SlowList({ text }) { }); ``` -๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” `SlowList` props๊ฐ€ ์ด์ „ ๋ Œ๋”๋ง ๋•Œ์™€ *๋™์ผํ•œ* ๊ฒฝ์šฐ์—๋งŒ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ ์ง๋ฉดํ•˜๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋Š” props๊ฐ€ *๋‹ค๋ฅด๊ณ * ์‹ค์ œ๋กœ ๋‹ค๋ฅธ ์‹œ๊ฐ์  ์ถœ๋ ฅ์„ ๋ณด์—ฌ์ค˜์•ผ ํ•  ๋•Œ ์†๋„๊ฐ€ ๋А๋ฆฌ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. +๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” `SlowList` Props๊ฐ€ ์ด์ „ ๋ Œ๋”๋ง ๋•Œ์™€ *๋™์ผํ•œ* ๊ฒฝ์šฐ์—๋งŒ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ ์ง๋ฉดํ•˜๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋Š” Props๊ฐ€ *๋‹ค๋ฅด๊ณ * ์‹ค์ œ๋กœ ๋‹ค๋ฅธ ์‹œ๊ฐ์  ์ถœ๋ ฅ์„ ๋ณด์—ฌ์ค˜์•ผ ํ•  ๋•Œ ์†๋„๊ฐ€ ๋А๋ฆฌ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. -๊ตฌ์ฒด์ ์œผ๋กœ, ์ฃผ์š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋Š” input์— ํƒ€์ดํ•‘ํ•  ๋•Œ๋งˆ๋‹ค `SlowList`๊ฐ€ ์ƒˆ๋กœ์šด props๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ์ „์ฒด ํŠธ๋ฆฌ๋ฅผ ๋ฆฌ๋ Œ๋”๋งํ•˜๋ฉด ํƒ€์ดํ•‘์ด ๋Š๊ธฐ๋Š” ๋А๋‚Œ์ด ๋“ ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ `useDeferredValue`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž…๋ ฅ ์—…๋ฐ์ดํŠธ(๋นจ๋ผ์•ผ ํ•˜๋Š”)๋ฅผ ๊ฒฐ๊ณผ ๋ชฉ๋ก ์—…๋ฐ์ดํŠธ(๋А๋ ค๋„ ๋˜๋Š”)๋ณด๋‹ค ๋†’์€ ์šฐ์„ ์ˆœ์œ„์— ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ตฌ์ฒด์ ์œผ๋กœ, ์ฃผ์š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋Š” Input์— ํƒ€์ดํ•‘ํ•  ๋•Œ๋งˆ๋‹ค `SlowList`๊ฐ€ ์ƒˆ๋กœ์šด Props๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ์ „์ฒด ํŠธ๋ฆฌ๋ฅผ ๋ฆฌ๋ Œ๋”๋งํ•˜๋ฉด ํƒ€์ดํ•‘์ด ๋Š๊ธฐ๋Š” ๋А๋‚Œ์ด ๋“ ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ `useDeferredValue`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž…๋ ฅ ์—…๋ฐ์ดํŠธ(๋นจ๋ผ์•ผ ํ•˜๋Š”)๋ฅผ ๊ฒฐ๊ณผ ๋ชฉ๋ก ์—…๋ฐ์ดํŠธ(๋А๋ ค๋„ ๋˜๋Š”)๋ณด๋‹ค ๋†’์€ ์šฐ์„ ์ˆœ์œ„์— ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {3,7} function App() { @@ -918,7 +802,7 @@ export default SlowList; <Pitfall> -์ด ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด์„œ๋Š” `SlowList`๋ฅผ [`memo`](/reference/react/memo)๋กœ ๊ฐ์‹ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. `text`๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค React๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋ฆฌ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ฆฌ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ `deferredText`๋Š” ์—ฌ์ „ํžˆ ์ด์ „ ๊ฐ’์„ ๊ฐ€์ง€๋ฏ€๋กœ `SlowList`๋Š” ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(props๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค). [`memo`](/reference/react/memo)๊ฐ€ ์—†์œผ๋ฉด ์–ด์จŒ๋“  ๋ฆฌ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ตœ์ ํ™”์˜ ์ทจ์ง€๊ฐ€ ๋ฌด์ƒ‰ํ•ด์ง‘๋‹ˆ๋‹ค. +์ด ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด์„œ๋Š” `SlowList`๋ฅผ [`memo`](/reference/react/memo)๋กœ ๊ฐ์‹ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. `text`๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค React๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋ฆฌ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ฆฌ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ `deferredText`๋Š” ์—ฌ์ „ํžˆ ์ด์ „ ๊ฐ’์„ ๊ฐ€์ง€๋ฏ€๋กœ `SlowList`๋Š” ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (Props๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.) [`memo`](/reference/react/memo)๊ฐ€ ์—†์œผ๋ฉด ์–ด์จŒ๋“  ๋ฆฌ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ตœ์ ํ™”์˜ ์ทจ์ง€๊ฐ€ ๋ฌด์ƒ‰ํ•ด์ง‘๋‹ˆ๋‹ค. </Pitfall> @@ -926,14 +810,14 @@ export default SlowList; #### ๊ฐ’์„ ์ง€์—ฐํ•˜๋Š” ๊ฒƒ์€ ๋””๋ฐ”์šด์‹ฑ ๋ฐ ์Šค๋กœํ‹€๋ง๊ณผ ์–ด๋–ค ์ ์ด ๋‹ค๋ฅธ๊ฐ€์š”? {/*how-is-deferring-a-value-different-from-debouncing-and-throttling*/} -์ด ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์ด์ „์— ์‚ฌ์šฉํ–ˆ์„ ์ˆ˜ ์žˆ๋Š” ๋‘ ๊ฐ€์ง€ ์ผ๋ฐ˜์ ์ธ ์ตœ์ ํ™” ๊ธฐ์ˆ ์ด ์žˆ์Šต๋‹ˆ๋‹ค +์ด ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์ด์ „์— ์‚ฌ์šฉํ–ˆ์„ ์ˆ˜ ์žˆ๋Š” ๋‘ ๊ฐ€์ง€ ์ผ๋ฐ˜์ ์ธ ์ตœ์ ํ™” ๊ธฐ์ˆ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. - *๋””๋ฐ”์šด์‹ฑ*์€ ํƒ€์ดํ•‘์„ ๋ฉˆ์ถœ ๋•Œ๊นŒ์ง€(์˜ˆ: 1์ดˆ ๋™์•ˆ) ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋ชฉ๋ก์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. - *์Šค๋กœํ‹€๋ง*์€ ๊ฐ€๋”์”ฉ(์˜ˆ: ์ตœ๋Œ€ 1์ดˆ์— ํ•œ ๋ฒˆ) ๋ชฉ๋ก์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ๋ฒ•๋“ค์€ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ์œ ์šฉํ•˜์ง€๋งŒ, `useDeferredValue`๋Š” React ์ž์ฒด์™€ ๊นŠ๊ฒŒ ํ†ตํ•ฉ๋˜์–ด ์žˆ๊ณ  ์‚ฌ์šฉ์ž์˜ ๊ธฐ๊ธฐ์— ๋งž๊ฒŒ ์กฐ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ Œ๋”๋ง์„ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐ ๋” ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. -๋””๋ฐ”์šด์‹ฑ์ด๋‚˜ ์Šค๋กœํ‹€๋ง๊ณผ ๋‹ฌ๋ฆฌ ๊ณ ์ •๋œ ์ง€์—ฐ์„ ์„ ํƒํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ๋””๋ฐ”์ด์Šค๊ฐ€ ๋น ๋ฅธ ๊ฒฝ์šฐ(์˜ˆ: ๊ณ ์„ฑ๋Šฅ ๋…ธํŠธ๋ถ) ์ง€์—ฐ๋œ ๋ฆฌ๋ Œ๋”๋ง์€ ๊ฑฐ์˜ ์ฆ‰์‹œ ๋ฐœ์ƒํ•˜๋ฉฐ ๋ˆˆ์— ๋„์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ๋””๋ฐ”์ด์Šค๊ฐ€ ๋А๋ฆฐ ๊ฒฝ์šฐ, ๊ธฐ๊ธฐ ์†๋„์— ๋น„๋ก€ํ•˜์—ฌ ๋ชฉ๋ก์ด input์— '์ง€์—ฐ'๋ฉ๋‹ˆ๋‹ค. +๋””๋ฐ”์šด์‹ฑ์ด๋‚˜ ์Šค๋กœํ‹€๋ง๊ณผ ๋‹ฌ๋ฆฌ ๊ณ ์ •๋œ ์ง€์—ฐ์„ ์„ ํƒํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ๋””๋ฐ”์ด์Šค๊ฐ€ ๋น ๋ฅธ ๊ฒฝ์šฐ(์˜ˆ: ๊ณ ์„ฑ๋Šฅ ๋…ธํŠธ๋ถ) ์ง€์—ฐ๋œ ๋ฆฌ๋ Œ๋”๋ง์€ ๊ฑฐ์˜ ์ฆ‰์‹œ ๋ฐœ์ƒํ•˜๋ฉฐ ๋ˆˆ์— ๋„์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ๋””๋ฐ”์ด์Šค๊ฐ€ ๋А๋ฆฐ ๊ฒฝ์šฐ, ๊ธฐ๊ธฐ ์†๋„์— ๋น„๋ก€ํ•˜์—ฌ ๋ชฉ๋ก์ด Input์— '์ง€์—ฐ'๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋””๋ฐ”์šด์‹ฑ์ด๋‚˜ ์Šค๋กœํ‹€๋ง๊ณผ ๋‹ฌ๋ฆฌ, `useDeferredValue`์— ์˜ํ•ด ์ˆ˜ํ–‰๋˜๋Š” ์ง€์—ฐ๋œ ๋ฆฌ๋ Œ๋”๋ง์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, React๊ฐ€ ํฐ ๋ชฉ๋ก์„ ๋ฆฌ๋ Œ๋”๋งํ•˜๋Š” ๋„์ค‘์— ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค๋ฅธ ํ‚ค ์ž…๋ ฅ์„ ํ•˜๋ฉด React๋Š” ํ•ด๋‹น ๋ฆฌ๋ Œ๋”๋ง์„ ์ค‘๋‹จํ•˜๊ณ  ํ‚ค ์ž…๋ ฅ์„ ์ฒ˜๋ฆฌํ•œ ๋‹ค์Œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋ฆฌ๋ Œ๋”๋ง์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ๋””๋ฐ”์šด์‹ฑ๊ณผ ์Šค๋กœํ‹€๋ง์€ ๋ Œ๋”๋ง์ด ํ‚ค ์ž…๋ ฅ์„ ์ฐจ๋‹จํ•˜๋Š” ์ˆœ๊ฐ„์„ ์ง€์—ฐํ•  ๋ฟ์ด๋ฏ€๋กœ ์—ฌ์ „ํžˆ ๋ถˆ์•ˆ์ •ํ•œ ๊ฒฝํ—˜์„ ๋งŒ๋“ค์–ด ๋ƒ…๋‹ˆ๋‹ค. From f826c9d8a86748777f0d00e8d7d62bfd1eab5673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 14:32:48 +0900 Subject: [PATCH 0355/1059] docs: update `react-v18.md` --- .../blog/2021/06/08/the-plan-for-react-18.md | 4 +- .../blog/2021/12/17/react-conf-2021-recap.md | 4 +- .../blog/2022/03/08/react-18-upgrade-guide.md | 6 +- src/content/blog/2022/03/29/react-v18.md | 176 +++++++++--------- ...-what-we-have-been-working-on-june-2022.md | 4 +- src/content/blog/index.md | 2 +- 6 files changed, 98 insertions(+), 98 deletions(-) diff --git a/src/content/blog/2021/06/08/the-plan-for-react-18.md b/src/content/blog/2021/06/08/the-plan-for-react-18.md index 36f1d8e9b..c9719277e 100644 --- a/src/content/blog/2021/06/08/the-plan-for-react-18.md +++ b/src/content/blog/2021/06/08/the-plan-for-react-18.md @@ -27,9 +27,9 @@ React ํŒ€์€ ๋ช‡ ๊ฐ€์ง€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. React 18์ด ์ถœ์‹œ๋˜๋ฉด [์ž๋™ ์ผ๊ด„ ์ฒ˜๋ฆฌ<sup>Automatic Batching</sup>](https://github.com/reactwg/react-18/discussions/21)์™€ ๊ฐ™์€ ๊ธฐ๋ณธ ๊ฐœ์„  ์‚ฌํ•ญ ๋ฐ [`startTransition`](https://github.com/reactwg/react-18/discussions/41)๊ณผ ๊ฐ™์€ ์ƒˆ๋กœ์šด API, `React.lazy`๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” [์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ<sup>Streaming Server Renderer</sup>](https://github.com/reactwg/react-18/discussions/37)๊ฐ€ ํฌํ•จ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ๋“ค์€ React 18์— ์ถ”๊ฐ€๋  ์ƒˆ๋กœ์šด ์„ ํƒ์ <sup>Opt-In</sup> ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•๋ถ„์— ๊ฐ€๋Šฅํ•ด์กŒ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ "๋™์‹œ ๋ Œ๋”๋ง<sup>Concurrent Rendering</sup>"์ด๋ผ๊ณ  ํ•˜๋ฉฐ, ์ด ๊ธฐ๋Šฅ์„ ํ†ตํ•ด React๋Š” ๋™์‹œ์— ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ UI๋ฅผ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋“ค์€ ๋Œ€๋ถ€๋ถ„ ์ง์ ‘ ๋ณผ ์ˆ˜๋Š” ์—†์ง€๋งŒ, ์•ฑ์˜ ์‹ค์ œ ์„ฑ๋Šฅ๊ณผ ์ฒด๊ฐ ์„ฑ๋Šฅ์„ ๋ชจ๋‘ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๊ฐ€๋Šฅ์„ฑ์„ ์—ด์–ด์ค๋‹ˆ๋‹ค. +์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ๋“ค์€ React 18์— ์ถ”๊ฐ€๋  ์ƒˆ๋กœ์šด ์„ ํƒ์ <sup>Opt-In</sup> ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•๋ถ„์— ๊ฐ€๋Šฅํ•ด์กŒ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ "๋™์‹œ์„ฑ ๋ Œ๋”๋ง<sup>Concurrent Rendering</sup>"์ด๋ผ๊ณ  ํ•˜๋ฉฐ, ์ด ๊ธฐ๋Šฅ์„ ํ†ตํ•ด React๋Š” ๋™์‹œ์— ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ UI๋ฅผ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋“ค์€ ๋Œ€๋ถ€๋ถ„ ์ง์ ‘ ๋ณผ ์ˆ˜๋Š” ์—†์ง€๋งŒ, ์•ฑ์˜ ์‹ค์ œ ์„ฑ๋Šฅ๊ณผ ์ฒด๊ฐ ์„ฑ๋Šฅ์„ ๋ชจ๋‘ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๊ฐ€๋Šฅ์„ฑ์„ ์—ด์–ด์ค๋‹ˆ๋‹ค. -React์˜ ๋ฏธ๋ž˜์— ๋Œ€ํ•œ ์ €ํฌ๋“ค์˜ ์—ฐ๊ตฌ๋ฅผ ๊ณ„์† ์ง€์ผœ๋ณด์…จ๋‹ค๋ฉด(๋ฌผ๋ก , ๊ทธ๋Ÿด ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค!), "๋™์‹œ ๋ชจ๋“œ<sup>Concurrent Mode</sup>"๋ผ๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋“ค์–ด๋ณด์…จ๊ฑฐ๋‚˜, ๊ทธ๊ฒƒ์ด ์—ฌ๋Ÿฌ๋ถ„๋“ค์˜ ์•ฑ์„ ๋ง์น  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ๋ฅผ ๋“ค์œผ์…จ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜์˜ํ•˜์—ฌ ์ ์ง„์ ์ธ ๋„์ž…์„ ์œ„ํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ ์ „๋žต์„ ์žฌ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค. "๋ชจ๋“œ"๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋Œ€์‹ , ๋™์‹œ ๋ Œ๋”๋ง<sup>Concurrent Rendering</sup>์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์— ์˜ํ•ด ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•ด์„œ๋งŒ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, **์žฌ์ž‘์„ฑ ์—†์ด React 18์„ ๋„์ž…ํ•˜๊ณ  ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค**. +React์˜ ๋ฏธ๋ž˜์— ๋Œ€ํ•œ ์ €ํฌ๋“ค์˜ ์—ฐ๊ตฌ๋ฅผ ๊ณ„์† ์ง€์ผœ๋ณด์…จ๋‹ค๋ฉด(๋ฌผ๋ก , ๊ทธ๋Ÿด ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค!), "๋™์‹œ์„ฑ ๋ชจ๋“œ<sup>Concurrent Mode</sup>"๋ผ๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋“ค์–ด๋ณด์…จ๊ฑฐ๋‚˜, ๊ทธ๊ฒƒ์ด ์—ฌ๋Ÿฌ๋ถ„๋“ค์˜ ์•ฑ์„ ๋ง์น  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ๋ฅผ ๋“ค์œผ์…จ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ˜์˜ํ•˜์—ฌ ์ ์ง„์ ์ธ ๋„์ž…์„ ์œ„ํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ ์ „๋žต์„ ์žฌ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค. "๋ชจ๋“œ"๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋Œ€์‹ , ๋™์‹œ์„ฑ ๋ Œ๋”๋ง<sup>Concurrent Rendering</sup>์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์— ์˜ํ•ด ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•ด์„œ๋งŒ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, **์žฌ์ž‘์„ฑ ์—†์ด React 18์„ ๋„์ž…ํ•˜๊ณ  ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค**. ## ์ ์ง„์ ์ธ ๋„์ž… ์ „๋žต {/*a-gradual-adoption-strategy*/} diff --git a/src/content/blog/2021/12/17/react-conf-2021-recap.md b/src/content/blog/2021/12/17/react-conf-2021-recap.md index 7caddb827..70ae528ea 100644 --- a/src/content/blog/2021/12/17/react-conf-2021-recap.md +++ b/src/content/blog/2021/12/17/react-conf-2021-recap.md @@ -27,9 +27,9 @@ React Conf๊ฐ€ ์˜จ๋ผ์ธ์œผ๋กœ ๊ฐœ์ตœ๋œ ๊ฒƒ์€ ์ด๋ฒˆ์ด ์ฒ˜์Œ์ด๋ฉฐ, 8๊ฐœ ์–ธ ๊ธฐ์กฐ์—ฐ์„ค์—์„œ React 18์„ ์‹œ์ž‘์œผ๋กœ React์˜ ๋ฏธ๋ž˜์— ๋Œ€ํ•œ ๋น„์ „์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. -React 18์€ ์˜ค๋žซ๋™์•ˆ ๊ธฐ๋‹ค๋ ค์˜จ ๋™์‹œ ๋ Œ๋”๋Ÿฌ<sup>Concurrent Renderer</sup>๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  Suspense๋ฅผ ์ฃผ<sup>Major, ไธป</sup><sub>(์—ญ์ž. Breaking Change๋ฅผ ์ผ์œผํ‚ค๋Š”)</sub> ๋ณ€๊ฒฝ ์—†์ด ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์€ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์—ฌ ๋‹ค๋ฅธ ์ฃผ<sup>Major, ไธป</sup> ๋ฆด๋ฆฌ์ฆˆ์™€ ๋™๋“ฑํ•œ ์ˆ˜์ค€์˜ ๋…ธ๋ ฅ์œผ๋กœ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ์ ์ง„์ ์œผ๋กœ ๋„์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +React 18์€ ์˜ค๋žซ๋™์•ˆ ๊ธฐ๋‹ค๋ ค์˜จ ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ<sup>Concurrent Renderer</sup>๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  Suspense๋ฅผ ์ฃผ<sup>Major, ไธป</sup><sub>(์—ญ์ž. Breaking Change๋ฅผ ์ผ์œผํ‚ค๋Š”)</sub> ๋ณ€๊ฒฝ ์—†์ด ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์€ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜์—ฌ ๋‹ค๋ฅธ ์ฃผ<sup>Major, ไธป</sup> ๋ฆด๋ฆฌ์ฆˆ์™€ ๋™๋“ฑํ•œ ์ˆ˜์ค€์˜ ๋…ธ๋ ฅ์œผ๋กœ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ์ ์ง„์ ์œผ๋กœ ๋„์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -**์ด๋Š” ๋™์‹œ ๋ชจ๋“œ๊ฐ€ ์—†๊ณ  ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ๋งŒ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.** +**์ด๋Š” ๋™์‹œ์„ฑ ๋ชจ๋“œ๊ฐ€ ์—†๊ณ  ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ๋งŒ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.** ๊ธฐ์กฐ์—ฐ์„ค์—์„œ๋Š” Suspense, ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ, ์ƒˆ๋กœ์šด React ์›Œํ‚น ๊ทธ๋ฃน์— ๋Œ€ํ•œ ๋น„์ „๊ณผ React Native์— ๋Œ€ํ•œ ์žฅ๊ธฐ์ ์ธ ๋ฉ€ํ‹ฐํ”Œ๋žซํผ ๋น„์ „๋„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. diff --git a/src/content/blog/2022/03/08/react-18-upgrade-guide.md b/src/content/blog/2022/03/08/react-18-upgrade-guide.md index 06c41bc50..a08353f1d 100644 --- a/src/content/blog/2022/03/08/react-18-upgrade-guide.md +++ b/src/content/blog/2022/03/08/react-18-upgrade-guide.md @@ -2,7 +2,7 @@ title: "React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•" author: Rick Hanlon date: 2022/03/08 -description: React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๋™์‹œ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +description: React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. --- 2022๋…„ 3์›” 8์ผ, [Rick Hanlon](https://twitter.com/rickhanlonii) @@ -11,7 +11,7 @@ description: React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๋™ <Intro> -React 18์€ [๋ฆด๋ฆฌ์Šค ๋…ธํŠธ](/blog/2022/03/29/react-v18)์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๋™์‹œ ๋ Œ๋”๋Ÿฌ<sup>Concurrent Renderer</sup>๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +React 18์€ [๋ฆด๋ฆฌ์Šค ๋…ธํŠธ](/blog/2022/03/29/react-v18)์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ<sup>Concurrent Renderer</sup>๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” [๋ฌธ์ œ๋ฅผ ์•Œ๋ ค์ฃผ์„ธ์š”](https://github.com/facebook/react/issues/new/choose). @@ -49,7 +49,7 @@ ReactDOM.render is no longer supported in React 18. Use createRoot instead. Unti </ConsoleBlock> -React 18์€ ์‚ฌ์šฉ์ž๋“ค์ด ๋” ํŽธ๋ฆฌํ•˜๊ฒŒ Root ์š”์†Œ๋“ค์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ์‹  Root API๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋”๋ถˆ์–ด ์ตœ์‹  Root API๋Š” ์ƒˆ๋กœ์šด ๋™์‹œ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋™์ž‘์‹œ์ผœ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ<sup>Concurrent Features</sup>์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. +React 18์€ ์‚ฌ์šฉ์ž๋“ค์ด ๋” ํŽธ๋ฆฌํ•˜๊ฒŒ Root ์š”์†Œ๋“ค์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ์‹  Root API๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋”๋ถˆ์–ด ์ตœ์‹  Root API๋Š” ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋™์ž‘์‹œ์ผœ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ<sup>Concurrent Features</sup>์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ```js // ๋ณ€๊ฒฝ ์ „ diff --git a/src/content/blog/2022/03/29/react-v18.md b/src/content/blog/2022/03/29/react-v18.md index 1c1de1a8e..f7c9225b1 100644 --- a/src/content/blog/2022/03/29/react-v18.md +++ b/src/content/blog/2022/03/29/react-v18.md @@ -11,101 +11,101 @@ description: React 18 is now available on npm! In our last post, we shared step- <Intro> -์ด์ œ npm์—์„œ React 18์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ๋Š” ์•ฑ์„ [React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•](/blog/2022/03/08/react-18-upgrade-guide)์„ ๋‹จ๊ณ„๋ณ„๋กœ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๊ณผ ๋ฏธ๋ž˜์— ์–ด๋–ค ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š”์ง€์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +์ด์ œ npm์—์„œ React 18์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ๋Š” ์•ฑ์„ [React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•](/blog/2022/03/08/react-18-upgrade-guide)์„ ๋‹จ๊ณ„๋ณ„๋กœ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๊ณผ ์ด๊ฒƒ์ด ๋ฏธ๋ž˜์— ์–ด๋–ค ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š”์ง€์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. </Intro> --- -์ตœ์‹  ๋ฉ”์ด์ € ๋ฒ„์ „์—๋Š” ์ž๋™ batching, startTransition๊ณผ ๊ฐ™์€ ์ƒˆ๋กœ์šด API, Suspense๋ฅผ ์ง€์›ํ•˜๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง๊ณผ ๊ฐ™์€ ์ฆ‰๊ฐ์ ์ธ ๊ฐœ์„  ์‚ฌํ•ญ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. +์ตœ์‹  ์ฃผ<sup>Major, ไธป</sup> ๋ฒ„์ „์—๋Š” ์ž๋™ Batching, `startTransition`๊ณผ ๊ฐ™์€ ์ƒˆ๋กœ์šด API, Suspense๋ฅผ ์ง€์›ํ•˜๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง<sup>SSR, Server Side Rendering</sup>๊ณผ ๊ฐ™์€ ์ฆ‰๊ฐ์ ์ธ ๊ฐœ์„  ์‚ฌํ•ญ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. -React 18์˜ ๋งŽ์€ ๊ธฐ๋Šฅ์€ ๊ฐ•๋ ฅํ•œ ์ƒˆ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•˜๋Š” ๋ฐฐํ›„์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ธ concurrent ๋ Œ๋”๋Ÿฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค. concurrent ๋ Œ๋”๋Ÿฌ๋Š” ์„ ํƒ ์‚ฌํ•ญ์œผ๋กœ, concurrent ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ๋งŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์‚ฌ๋žŒ๋“ค์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ์‹์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์น  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. +React 18์˜ ๋งŽ์€ ๊ธฐ๋Šฅ์€ ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ<sup>Concurrent Renderer</sup>๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ๋Š” ์„ ํƒ ์‚ฌํ•ญ์œผ๋กœ, ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ๋งŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์‚ฌ๋žŒ๋“ค์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ์‹์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์น  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. -์šฐ๋ฆฌ๋Š” ์ˆ˜๋…„๊ฐ„ React์˜ ๋™์‹œ์„ฑ(concurrency) ์ง€์›์„ ์—ฐ๊ตฌํ•˜๊ณ  ๊ฐœ๋ฐœํ•ด ์™”์œผ๋ฉฐ, ๊ธฐ์กด ์‚ฌ์šฉ์ž๊ฐ€ ์ ์ง„์ ์œผ๋กœ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ๋ณ„ํžˆ ์‹ ๊ฒฝ์„ ์ผ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ์—ฌ๋ฆ„์—๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ „๋ฌธ๊ฐ€๋“ค๋กœ๋ถ€ํ„ฐ ํ”ผ๋“œ๋ฐฑ์„ ์ˆ˜์ง‘ํ•˜๊ณ  ์ „์ฒด React ์ƒํƒœ๊ณ„๋ฅผ ์œ„ํ•œ ์›ํ™œํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ ํ™˜๊ฒฝ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด [React 18 Working Group](/blog/2021/06/08/the-plan-for-react-18)์„ ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. +์ €ํฌ๋Š” ์ˆ˜๋…„๊ฐ„ React์˜ ๋™์‹œ์„ฑ<sup>concurrency</sup> ์ง€์›์„ ์—ฐ๊ตฌํ•˜๊ณ  ๊ฐœ๋ฐœํ•ด ์™”์œผ๋ฉฐ, ๊ธฐ์กด ์‚ฌ์šฉ์ž๊ฐ€ ์ ์ง„์ ์œผ๋กœ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ๋ณ„ํžˆ ์‹ ๊ฒฝ์„ ์ผ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ์—ฌ๋ฆ„์—๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ „๋ฌธ๊ฐ€๋“ค๋กœ๋ถ€ํ„ฐ ํ”ผ๋“œ๋ฐฑ์„ ์ˆ˜์ง‘ํ•˜๊ณ  ์ „์ฒด React ์ƒํƒœ๊ณ„๋ฅผ ์œ„ํ•œ ์›ํ™œํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ ํ™˜๊ฒฝ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด [React 18 ์›Œํ‚น ๊ทธ๋ฃน](/blog/2021/06/08/the-plan-for-react-18)์„ ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. -๋†“์น˜์‹  ๋ถ„๋“ค์„ ์œ„ํ•ด React Conf 2021์—์„œ ๋งŽ์€ ๋ถ€๋ถ„์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. +ํ˜น์‹œ ๋†“์น˜์…จ๋‹ค๋ฉด, React Conf 2021์—์„œ ์ด ๋น„์ „์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๊ณต์œ ํ–ˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•ด ๋ณด์„ธ์š”. * [์ด ์—ฐ์„ค](https://www.youtube.com/watch?v=FZ0cG47msEk&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa)์—์„œ๋Š” ๊ฐœ๋ฐœ์ž๋“ค์ด ํ›Œ๋ฅญํ•œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์‰ฝ๊ฒŒ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ์šฐ๋ฆฌ์˜ ์ž„๋ฌด์— React 18์ด ์–ด๋–ป๊ฒŒ ๋ถ€ํ•ฉํ•˜๋Š”์ง€ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. * [Shruti Kapoor](https://twitter.com/shrutikapoor08)๊ฐ€ [React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‹œ์—ฐ](https://www.youtube.com/watch?v=ytudH8je5ko&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa&index=2)ํ–ˆ์Šต๋‹ˆ๋‹ค. * [Shaundai Person](https://twitter.com/shaundai)์ด [Suspense๋ฅผ ์‚ฌ์šฉํ•œ ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง](https://www.youtube.com/watch?v=pj5N-Khihgc&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa&index=3)์— ๋Œ€ํ•œ ๊ฐœ์š”๋ฅผ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. -๋‹ค์Œ์€ Concurrent ๋ Œ๋”๋ง๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ์ด๋ฒˆ ๋ฆด๋ฆฌ์Šค์—์„œ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ „์ฒด ๊ฐœ์š”์ž…๋‹ˆ๋‹ค. +๋‹ค์Œ์€ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง<sup>Concurrent Rendering</sup>๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ์ด๋ฒˆ ๋ฆด๋ฆฌ์Šค์—์„œ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ „์ฒด ๊ฐœ์š”์ž…๋‹ˆ๋‹ค. <Note> -React Native ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ด React 18์€ ์ƒˆ๋กœ์šด React Native ์•„ํ‚คํ…์ฒ˜์™€ ํ•จ๊ป˜ React Native๋กœ ์ œ๊ณต๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ [React Conf ํ‚ค๋…ธํŠธ](https://www.youtube.com/watch?v=FZ0cG47msEk&t=1530s)๋ฅผ ํ™•์ธํ•˜์„ธ์š”. +React Native ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ด React 18์€ ์ƒˆ๋กœ์šด React Native ์•„ํ‚คํ…์ฒ˜์™€ ํ•จ๊ป˜ React Native๋กœ ์ œ๊ณต๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ [React Conf ๊ธฐ์กฐ์—ฐ์„ค](https://www.youtube.com/watch?v=FZ0cG47msEk&t=1530s)๋ฅผ ํ™•์ธํ•˜์„ธ์š”. </Note> -## React์˜ Concurrent์ด๋ž€? {/*what-is-concurrent-react*/} +## React์˜ ๋™์‹œ์„ฑ<sup>Concurrency</sup>์ด๋ž€? {/*what-is-concurrent-react*/} -React 18์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ถ”๊ฐ€ ์‚ฌํ•ญ์€ ์—ฌ๋Ÿฌ๋ถ„์ด ๊ฒฐ์ฝ” ์ƒ๊ฐํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ๋ฅผ ๋ฐ”๋ผ๋Š” ๊ฒƒ, ๋ฐ”๋กœ ๋™์‹œ์„ฑ(concurrency)์ž…๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ์ž์—๊ฒŒ๋Š” ์กฐ๊ธˆ ๋” ๋ณต์žกํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ๋Œ€์ฒด๋กœ ํ•ด๋‹นํ•˜๋Š” ์ด์•ผ๊ธฐ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. +React 18์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ถ”๊ฐ€ ์‚ฌํ•ญ์€ ์—ฌ๋Ÿฌ๋ถ„์ด ๊ฒฐ์ฝ” ์ƒ๊ฐํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ๋ฅผ ๋ฐ”๋ผ๋Š” ๊ฒƒ, ๋ฐ”๋กœ ๋™์‹œ์„ฑ<sup>concurrency</sup>์ž…๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ์ž์—๊ฒŒ๋Š” ์กฐ๊ธˆ ๋” ๋ณต์žกํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ๋Œ€๋ถ€๋ถ„ ํ•ด๋‹นํ•˜๋Š” ์ด์•ผ๊ธฐ๋ผ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. -Concurrency ์ž์ฒด๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹™๋‹ˆ๋‹ค. React๊ฐ€ ๋™์‹œ์— ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ UI๋ฅผ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ƒˆ๋กœ์šด ๋น„ํ•˜์ธ๋“œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. Concurrency๋Š” ๊ตฌํ˜„์˜ ์„ธ๋ถ€ ์‚ฌํ•ญ์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, concurrency๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ ๋•Œ๋ฌธ์— ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ๋‚ด๋ถ€ ๊ตฌํ˜„์—์„œ ์šฐ์„ ์ˆœ์œ„ ํ์™€ ๋‹ค์ค‘ ๋ฒ„ํผ๋ง๊ณผ ๊ฐ™์€ ์ •๊ตํ•œ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ์˜ ๊ณต๊ฐœ API์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๊ฐœ๋…์„ ์ฐพ์•„๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +๋™์‹œ์„ฑ ์ž์ฒด๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹™๋‹ˆ๋‹ค. React๊ฐ€ ๋™์‹œ์— ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ UI๋ฅผ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ƒˆ๋กœ์šด ๋‚ด๋ถ€ ๋™์ž‘ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๋™์‹œ์„ฑ์€ ๊ตฌํ˜„์˜ ์„ธ๋ถ€ ์‚ฌํ•ญ์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋™์‹œ์„ฑ์ด ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ๋“ค ๋•Œ๋ฌธ์— ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ๋‚ด๋ถ€ ๊ตฌํ˜„์—์„œ ์šฐ์„ ์ˆœ์œ„ ํ ๋ฐ ๋‹ค์ค‘ ๋ฒ„ํผ๋ง๊ณผ ๊ฐ™์€ ์ •๊ตํ•œ ๊ธฐ์ˆ ๋“ค์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ์˜ ๊ณต๊ฐœ API์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๊ฐœ๋…์„ ์ฐพ์•„๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -API๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์ˆจ๊ธฐ๋ ค๊ณ  ๋…ธ๋ ฅํ•ฉ๋‹ˆ๋‹ค. React ๊ฐœ๋ฐœ์ž๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ *์–ด๋–ค ๋ชจ์Šต(what)* ์œผ๋กœ ๋งŒ๋“ค ๊ฒƒ์ธ์ง€์— ์ง‘์ค‘ํ•˜๊ณ , React๋Š” ๊ทธ ๊ฒฝํ—˜์„ *์–ด๋–ป๊ฒŒ(how)* ์ „๋‹ฌํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ React ๊ฐœ๋ฐœ์ž๊ฐ€ ๋‚ด๋ถ€์—์„œ concurrency๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +API๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์ˆจ๊ธฐ๋ ค๊ณ  ๋…ธ๋ ฅํ•ฉ๋‹ˆ๋‹ค. React ๊ฐœ๋ฐœ์ž๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ *์–ด๋–ค ๋ชจ์Šต*<sup>*What*</sup> ์œผ๋กœ ๋งŒ๋“ค ๊ฒƒ์ธ์ง€์— ์ง‘์ค‘ํ•˜๊ณ , React๋Š” ๊ทธ ๊ฒฝํ—˜์„ *์–ด๋–ป๊ฒŒ*<sup>*How*</sup> ์ „๋‹ฌํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ React ๊ฐœ๋ฐœ์ž๊ฐ€ ๋‚ด๋ถ€์—์„œ ๋™์‹œ์„ฑ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -๊ทธ๋Ÿฌ๋‚˜ Concurrent React๋Š” ์ผ๋ฐ˜์ ์ธ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ๋ณด๋‹ค ๋” ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด React์˜ ํ•ต์‹ฌ ๋ Œ๋”๋ง ๋ชจ๋ธ์— ๋Œ€ํ•œ ๊ทผ๋ณธ์ ์ธ ์—…๋ฐ์ดํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ concurrency๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์•„๋Š” ๊ฒƒ์ด ์—„์ฒญ๋‚˜๊ฒŒ ์ค‘์š”ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ๋†’์€ ์ˆ˜์ค€์—์„œ concurrency๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•„๋Š” ๊ฒƒ์€ ๊ฐ€์น˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ทธ๋Ÿฌ๋‚˜ React์˜ ๋™์‹œ์„ฑ์€ ์ผ๋ฐ˜์ ์ธ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ๋ณด๋‹ค ๋” ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ React์˜ ํ•ต์‹ฌ ๋ Œ๋”๋ง ๋ชจ๋ธ์— ๋Œ€ํ•œ ๊ทผ๋ณธ์ ์ธ ์—…๋ฐ์ดํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋™์‹œ์„ฑ์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์•„๋Š” ๊ฒƒ์ด ์—„์ฒญ ์ค‘์š”ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ๊ณ ์ˆ˜์ค€<sup>High Level</sup>์—์„œ ๋™์‹œ์„ฑ์ด ๋ฌด์—‡์ธ์ง€ ์•„๋Š” ๊ฒƒ์€ ๊ฐ€์น˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Concurrent React์˜ ํ•ต์‹ฌ์€ ๋ Œ๋”๋ง์„ ์ค‘๋‹จ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. React 18๋กœ ์ฒ˜์Œ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ๋•Œ concurrent ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „ ์—…๋ฐ์ดํŠธ๋Š” ์ด์ „ ๋ฒ„์ „์˜ React์™€ ๋™์ผํ•˜๊ฒŒ ์ค‘๋‹จ๋˜์ง€ ์•Š๋Š” ๋‹จ์ผ ๋™๊ธฐ์‹ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. ๋™๊ธฐ์‹ ๋ Œ๋”๋ง์˜ ๊ฒฝ์šฐ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ Œ๋”๋ง์„ ์‹œ์ž‘ํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์„ ๋•Œ๊นŒ์ง€ ๊ทธ ์–ด๋–ค ๊ฒƒ๋„ ๋ Œ๋”๋ง์„ ๋ฐฉํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +React์˜ ๋™์‹œ์„ฑ์—์„œ ํ•ต์‹ฌ์€ ๋ Œ๋”๋ง์ด ์ค‘๋‹จ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. React 18๋กœ ์ฒ˜์Œ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ๋•Œ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์ „ ์—…๋ฐ์ดํŠธ๋Š” ์ด์ „ ๋ฒ„์ „์˜ React์™€ ๋™์ผํ•˜๊ฒŒ ์ค‘๋‹จ๋˜์ง€ ์•Š๋Š” ๋‹จ์ผ ๋™๊ธฐ์‹ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. ๋™๊ธฐ์‹ ๋ Œ๋”๋ง์˜ ๊ฒฝ์šฐ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ Œ๋”๋ง์„ ์‹œ์ž‘ํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์„ ๋•Œ๊นŒ์ง€ ๊ทธ ์–ด๋–ค ๊ฒƒ๋„ ๋ Œ๋”๋ง์„ ๋ฐฉํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -Concurrent ๋ Œ๋”๋ง์—์„œ๋Š” ํ•ญ์ƒ ๊ทธ๋ ‡์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. React๋Š” ์—…๋ฐ์ดํŠธ๋œ ๋ Œ๋”๋ง์„ ์‹œ์ž‘ํ•˜๊ณ  ์ค‘๊ฐ„์— ์ผ์‹œ ์ค‘์ง€ํ–ˆ๋‹ค๊ฐ€ ๋‚˜์ค‘์— ๊ณ„์†ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ์ง„ํ–‰ ์ค‘์ธ ๋ Œ๋”๋ง์„ ์™„์ „ํžˆ ์ค‘๋‹จํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ๋ Œ๋”๋ง์ด ์ค‘๋‹จ๋˜๋”๋ผ๋„ UI๊ฐ€ ์ผ๊ด€๋˜๊ฒŒ ํ‘œ์‹œ๋˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ํŠธ๋ฆฌ ์ „์ฒด๊ฐ€ ํ‰๊ฐ€๋œ ํ›„ DOM ๋ณ€ํ˜•์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์„ ํ†ตํ•ด React๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ƒˆ ํ™”๋ฉด์„ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, UI๊ฐ€ ๋Œ€๊ทœ๋ชจ ๋ Œ๋”๋ง ์ž‘์—… ์ค‘์—๋„ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ์ฆ‰์‹œ ๋ฐ˜์‘ํ•˜์—ฌ ์œ ๋™์ ์ธ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋™์‹œ์„ฑ ๋ Œ๋”๋ง์—์„œ๋Š” ํ•ญ์ƒ ๊ทธ๋ ‡์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. React๋Š” ์—…๋ฐ์ดํŠธ๋œ ๋ Œ๋”๋ง์„ ์‹œ์ž‘ํ•˜๊ณ  ์ค‘๊ฐ„์— ์ผ์‹œ ์ค‘์ง€ํ–ˆ๋‹ค๊ฐ€ ๋‚˜์ค‘์— ๊ณ„์†ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ์ง„ํ–‰ ์ค‘์ธ ๋ Œ๋”๋ง์„ ์™„์ „ํžˆ ์ค‘๋‹จํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ๋ Œ๋”๋ง์ด ์ค‘๋‹จ๋˜๋”๋ผ๋„ UI๊ฐ€ ์ผ๊ด€๋˜๊ฒŒ ํ‘œ์‹œ๋˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ํŠธ๋ฆฌ ์ „์ฒด๊ฐ€ ํ‰๊ฐ€๋œ ํ›„ DOM ๋ณ€ํ˜•์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์„ ํ†ตํ•ด React๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ƒˆ ํ™”๋ฉด์„ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, UI๊ฐ€ ๋Œ€๊ทœ๋ชจ ๋ Œ๋”๋ง ์ž‘์—… ์ค‘์—๋„ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ์ฆ‰์‹œ ๋ฐ˜์‘ํ•˜์—ฌ ์œ ๋™์ ์ธ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋˜ ๋‹ค๋ฅธ ์˜ˆ๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. Concurrent React๋Š” ํ™”๋ฉด์—์„œ UI์˜ ์„น์…˜์„ ์ œ๊ฑฐํ–ˆ๋‹ค๊ฐ€ ๋‚˜์ค‘์— ๋‹ค์‹œ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ ์ด์ „ ์ƒํƒœ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ ๋ฒ—์–ด๋‚˜ ๋’ค๋กœ ํƒญ ํ•  ๋•Œ, React๋Š” ํ™”๋ฉด์„ ์ด์ „๊ณผ ๋™์ผํ•œ ์ƒํƒœ๋กœ ๋ณต์›ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ณง ์ถœ์‹œ๋  ๋งˆ์ด๋„ˆ ๋ฒ„์ „์—์„œ๋Š” ์ด ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๋Š” `<Offscreen>`์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Offscreen์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๊ธฐ ์ „์— ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ƒˆ UI๋ฅผ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +๋˜ ๋‹ค๋ฅธ ์˜ˆ์‹œ๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ State์ž…๋‹ˆ๋‹ค. React์˜ ๋™์‹œ์„ฑ์€ ํ™”๋ฉด์—์„œ UI์˜ ์„น์…˜์„ ์ œ๊ฑฐํ–ˆ๋‹ค๊ฐ€ ๋‚˜์ค‘์— ๋‹ค์‹œ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ ์ด์ „ State๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ ๋ฒ—์–ด๋‚˜ ๋’ค๋กœ๊ฐ€๊ธฐ๋ฅผ ํƒญ ํ•  ๋•Œ, React๋Š” ํ™”๋ฉด์„ ์ด์ „๊ณผ ๋™์ผํ•œ ์ƒํƒœ๋กœ ๋ณต์›ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ณง ์ถœ์‹œ๋  ๋งˆ์ด๋„ˆ ๋ฒ„์ „์—์„œ๋Š” ์ด ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๋Š” `<Offscreen>`์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ `<Offscreen>`์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๊ธฐ ์ „์— ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ƒˆ UI๋ฅผ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. -Concurrent ๋ Œ๋”๋ง์€ React์˜ ๊ฐ•๋ ฅํ•œ ์ƒˆ ๋„๊ตฌ์ด๋ฉฐ Suspense, Transitions, ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง ๋“ฑ ๋Œ€๋ถ€๋ถ„์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ด๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ React 18์€ ์šฐ๋ฆฌ๊ฐ€ ์ด ์ƒˆ๋กœ์šด ๊ธฐ๋ฐ˜ ์œ„์— ๊ตฌ์ถ•ํ•˜๊ณ ์ž ํ•˜๋Š” ๋ชฉํ‘œ์˜ ์‹œ์ž‘์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. +๋™์‹œ์„ฑ ๋ Œ๋”๋ง์€ React์˜ ๊ฐ•๋ ฅํ•œ ์ƒˆ ๋„๊ตฌ์ด๋ฉฐ Suspense, Transitions, ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง ๋“ฑ ๋Œ€๋ถ€๋ถ„์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์ด ์ด๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ React 18์€ ์ด ์ƒˆ๋กœ์šด ๊ธฐ๋ฐ˜ ์œ„์— ๊ตฌ์ถ•ํ•˜๊ณ ์ž ํ•˜๋Š” ๋ชฉํ‘œ์˜ ์‹œ์ž‘์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. -## ์ ์ง„์ ์œผ๋กœ Concurrent ๊ธฐ๋Šฅ ์ ์šฉํ•˜๊ธฐ {/*gradually-adopting-concurrent-features*/} +## ์ ์ง„์ ์œผ๋กœ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ ์ ์šฉํ•˜๊ธฐ {/*gradually-adopting-concurrent-features*/} -๊ธฐ์ˆ ์ ์œผ๋กœ concurrent ๋ Œ๋”๋ง์€ ํš๊ธฐ์ ์ธ ๋ณ€ํ™”์ž…๋‹ˆ๋‹ค. Concurrent ๋ Œ๋”๋ง์€ ์ค‘๋‹จ์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•ฝ๊ฐ„ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. +๊ธฐ์ˆ ์ ์œผ๋กœ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง์€ ํš๊ธฐ์ ์ธ ๋ณ€ํ™”์ž…๋‹ˆ๋‹ค. ๋™์‹œ์„ฑ ๋ Œ๋”๋ง์€ ์ค‘๋‹จ์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•ฝ๊ฐ„ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -์ €ํฌ๋Š” ํ…Œ์ŠคํŠธ์—์„œ ์ˆ˜์ฒœ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ ๊ฑฐ์˜ ๋ชจ๋“  ๊ธฐ์กด ์ปดํฌ๋„ŒํŠธ๊ฐ€ concurrent ๋ Œ๋”๋ง๊ณผ ํ•จ๊ป˜ ๋ณ€๊ฒฝ ์—†์ด "๊ทธ๋ƒฅ ์ž‘๋™"ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋Š” ์ถ”๊ฐ€์ ์ธ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ž‘์—…์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ํฌ์ง€ ์•Š์ง€๋งŒ, ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์†๋„์— ๋งž์ถฐ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React 18์˜ ์ƒˆ๋กœ์šด ๋ Œ๋”๋ง ๋™์ž‘์€ **์—ฌ๋Ÿฌ๋ถ„์˜ ์•ฑ์—์„œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„์—์„œ๋งŒ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค**. +์ €ํฌ๋Š” ํ…Œ์ŠคํŠธ์—์„œ ์ˆ˜์ฒœ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ์กด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง๊ณผ ํ•จ๊ป˜ ๋ณ€๊ฒฝ ์—†์ด "๊ทธ๋ƒฅ ์ž‘๋™"ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋Š” ์ถ”๊ฐ€์ ์ธ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ž‘์—…์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ํฌ์ง€ ์•Š์ง€๋งŒ, ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์†๋„์— ๋งž์ถฐ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React 18์˜ ์ƒˆ๋กœ์šด ๋ Œ๋”๋ง ๋™์ž‘์€ **์—ฌ๋Ÿฌ๋ถ„์˜ ์•ฑ์—์„œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„์—์„œ๋งŒ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค**. -์ „๋ฐ˜์ ์ธ ์—…๊ทธ๋ ˆ์ด๋“œ ์ „๋žต์€ ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ํ›ผ์†ํ•˜์ง€ ์•Š๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ React 18์—์„œ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ์ ์ง„์ ์œผ๋กœ concurrent ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ์ค‘์— concurrency ๊ด€๋ จ ๋ฒ„๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” [`<StrictMode>`](/reference/react/StrictMode)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Strict ๋ชจ๋“œ๋Š” ํ”„๋กœ๋•์…˜ ๋™์ž‘์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์ง€๋งŒ, ๊ฐœ๋ฐœ ์ค‘์— ์ถ”๊ฐ€ ๊ฒฝ๊ณ ๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ๋น„ํ™œ์„ฑํ™”๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ด์ค‘ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์„ ์žก์•„๋‚ด์ง€๋Š” ๋ชปํ•˜์ง€๋งŒ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์œ ํ˜•์˜ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค. +์ „๋ฐ˜์ ์ธ ์—…๊ทธ๋ ˆ์ด๋“œ ์ „๋žต์€ ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ํ›ผ์†ํ•˜์ง€ ์•Š๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ React 18์—์„œ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ์ ์ง„์ ์œผ๋กœ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ์ค‘์— ๋™์‹œ์„ฑ ๊ด€๋ จ ๋ฒ„๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” [`<StrictMode>`](/reference/react/StrictMode)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Strict ๋ชจ๋“œ๋Š” ํ”„๋กœ๋•์…˜ ๋™์ž‘์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์ง€๋งŒ, ๊ฐœ๋ฐœ ์ค‘์— ์ถ”๊ฐ€ ๊ฒฝ๊ณ ๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ๋น„ํ™œ์„ฑํ™”๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ด์ค‘ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์„ ์žก์•„๋‚ด์ง€๋Š” ๋ชปํ•˜์ง€๋งŒ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์œ ํ˜•์˜ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค. -React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋ฉด ์ฆ‰์‹œ concurrent ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด startTransition์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ํ™”๋ฉด ์‚ฌ์ด๋ฅผ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๋ฆฌ๋ Œ๋”๋ง์„ ์Šค๋กœํ‹€๋งํ•˜๊ธฐ ์œ„ํ•ด useDeferredValue๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋ฉด ์ฆ‰์‹œ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `startTransition`์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ํ™”๋ฉด ์‚ฌ์ด๋ฅผ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๋ฆฌ๋ Œ๋”๋ง์„ ์Šค๋กœํ‹€๋งํ•˜๊ธฐ ์œ„ํ•ด `useDeferredValue`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ ์žฅ๊ธฐ์ ์œผ๋กœ๋Š” ์•ฑ์— concurrency๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ฃผ๋œ ๋ฐฉ๋ฒ•์€ concurrency ์ง€์› ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ concurrent API์™€ ์ง์ ‘ ์ƒํ˜ธ ์ž‘์šฉํ•˜์ง€๋Š” ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ƒˆ ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค startTransition์„ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹ , ๋ผ์šฐํ„ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ž๋™์œผ๋กœ startTransition์— ๋‚ด๋น„๊ฒŒ์ด์…˜์„ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ ์žฅ๊ธฐ์ ์œผ๋กœ, ์•ฑ์— ๋™์‹œ์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ฃผ๋œ ๋ฐฉ๋ฒ•์€ ๋™์‹œ์„ฑ ์ง€์› ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋™์‹œ์„ฑ API์™€ ์ง์ ‘ ์ƒํ˜ธ ์ž‘์šฉํ•˜์ง€๋Š” ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ƒˆ ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค `startTransition`์„ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹ , ๋ผ์šฐํ„ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ž๋™์œผ๋กœ `startTransition`์— ๋‚ด๋น„๊ฒŒ์ด์…˜์„ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค. -๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ concurrent์™€ ํ˜ธํ™˜์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐ ๋‹ค์†Œ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ concurrent ๊ธฐ๋Šฅ์„ ๋” ์‰ฝ๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ƒˆ๋กœ์šด API๋ฅผ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”์ธํ…Œ์ด๋„ˆ๋“ค์ด React ์—์ฝ”์‹œ์Šคํ…œ์„ ์ ์ง„์ ์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๋Š” ๋™์•ˆ ์ธ๋‚ด์‹ฌ์„ ๊ฐ€์ ธ์ฃผ์„ธ์š”. +๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋™์‹œ์„ฑ๊ณผ ํ˜ธํ™˜์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐ ๋‹ค์†Œ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ๋” ์‰ฝ๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ƒˆ๋กœ์šด API๋ฅผ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”์ธํ…Œ์ด๋„ˆ๋“ค์ด React ์—์ฝ”์‹œ์Šคํ…œ์„ ์ ์ง„์ ์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๋Š” ๋™์•ˆ ์ธ๋‚ด์‹ฌ์„ ๊ฐ€์ ธ์ฃผ์„ธ์š”. ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด์ „ ๊ฒŒ์‹œ๋ฌผ์„ ์ฐธ์กฐํ•˜์„ธ์š”. [React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•](/blog/2022/03/08/react-18-upgrade-guide). ## ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„์›Œํฌ์˜ Suspense {/*suspense-in-data-frameworks*/} -React 18์—์„œ๋Š” Relay, Next.js, Hydrogen ๋˜๋Š” Remix์™€ ๊ฐ™์€ ๊ณ ์œ ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์œ„ํ•ด [Suspense](/reference/react/Suspense)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Suspense๋ฅผ ์‚ฌ์šฉํ•œ Ad hoc ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋Š” ๊ธฐ์ˆ ์ ์œผ๋กœ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ผ๋ฐ˜์ ์ธ ์ „๋žต์œผ๋กœ ๊ถŒ์žฅ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. +React 18์—์„œ๋Š” Relay, Next.js, Hydrogen ๋˜๋Š” Remix์™€ ๊ฐ™์€ ๊ณ ์œ ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ<sup>Fetching</sup> ์œ„ํ•ด [Suspense](/reference/react/Suspense)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Suspense๋ฅผ ์‚ฌ์šฉํ•œ Ad hoc ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ<sup>Fetching</sup>๋Š” ๊ธฐ์ˆ ์ ์œผ๋กœ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ผ๋ฐ˜์ ์ธ ์ „๋žต์œผ๋กœ ๊ถŒ์žฅ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ํ–ฅํ›„์—๋Š” ์ด๋Ÿฐ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ Suspense๋กœ ๋ฐ์ดํ„ฐ์— ๋” ์‰ฝ๊ฒŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ์ถ”๊ฐ€ ๊ธฐ๋ณธ ์š”์†Œ๋ฅผ ๋…ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Suspense๋Š” ๋ผ์šฐํ„ฐ, ๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด, ์„œ๋ฒ„ ๋ Œ๋”๋ง ํ™˜๊ฒฝ ๋“ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์•„ํ‚คํ…์ฒ˜์— ๊นŠ์ด ํ†ตํ•ฉ๋˜์–ด ์žˆ์„ ๋•Œ ๊ฐ€์žฅ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์žฅ๊ธฐ์ ์œผ๋กœ๋„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ React ์ƒํƒœ๊ณ„์—์„œ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. -์ด์ „ ๋ฒ„์ „์˜ React์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ํด๋ผ์ด์–ธํŠธ์—์„œ ์ฝ”๋“œ ๋ถ„ํ• ์„ ์œ„ํ•ด Suspense๋ฅผ React.lazy์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Suspense์— ๋Œ€ํ•œ ์šฐ๋ฆฌ์˜ ๋น„์ „์€ ํ•ญ์ƒ ์ฝ”๋“œ ๋กœ๋”ฉ ๊ทธ ์ด์ƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ์—๋Š” Suspense์— ๋Œ€ํ•œ ์ง€์›์„ ํ™•์žฅํ•˜์—ฌ, ๋™์ผํ•œ ์„ ์–ธ์  Suspense fallback์ด ๋ชจ๋“  ๋น„๋™๊ธฐ ์ž‘์—…(์ฝ”๋“œ, ๋ฐ์ดํ„ฐ, ์ด๋ฏธ์ง€ ๋“ฑ์˜ ๋กœ๋”ฉ)์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค. +์ด์ „ ๋ฒ„์ „์˜ React์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ํด๋ผ์ด์–ธํŠธ์—์„œ ์ฝ”๋“œ ๋ถ„ํ• <sup>Code Splitting</sup>์„ ์œ„ํ•ด Suspense๋ฅผ `React.lazy`์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Suspense์— ๋Œ€ํ•œ ๋น„์ „์€ ํ•ญ์ƒ ์ฝ”๋“œ ๋กœ๋”ฉ ๊ทธ ์ด์ƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ์—๋Š” Suspense์— ๋Œ€ํ•œ ์ง€์›์„ ํ™•์žฅํ•˜์—ฌ, ๋™์ผํ•œ ์„ ์–ธ์  Suspense Fallback์ด ๋ชจ๋“  ๋น„๋™๊ธฐ ์ž‘์—…(์ฝ”๋“œ, ๋ฐ์ดํ„ฐ, ์ด๋ฏธ์ง€ ๋“ฑ์˜ ๋กœ๋”ฉ)์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค. ## ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์•„์ง ๊ฐœ๋ฐœ ์ค‘์ž…๋‹ˆ๋‹ค. {/*server-components-is-still-in-development*/} -[**์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ**](/blog/2020/12/21/data-fetching-with-react-server-components)๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ธก ์•ฑ์˜ ํ’๋ถ€ํ•œ ์ƒํ˜ธ์ž‘์šฉ๊ณผ ๊ธฐ์กด ์„œ๋ฒ„ ๋ Œ๋”๋ง์˜ ํ–ฅ์ƒ๋œ ์„ฑ๋Šฅ์„ ๊ฒฐํ•ฉํ•˜์—ฌ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์•„์šฐ๋ฅด๋Š” ์•ฑ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ณง ์ถœ์‹œ๋  ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ณธ์งˆ์ ์œผ๋กœ Concurrent React์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ์žˆ์ง€๋Š” ์•Š์ง€๋งŒ, Suspense ๋ฐ ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง๊ณผ ๊ฐ™์€ concurrent ๊ธฐ๋Šฅ์— ๊ฐ€์žฅ ์ž˜ ์ž‘๋™ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +[**์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ**](/blog/2020/12/21/data-fetching-with-react-server-components)๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ธก ์•ฑ์˜ ํ’๋ถ€ํ•œ ์ƒํ˜ธ์ž‘์šฉ๊ณผ ๊ธฐ์กด ์„œ๋ฒ„ ๋ Œ๋”๋ง์˜ ํ–ฅ์ƒ๋œ ์„ฑ๋Šฅ์„ ๊ฒฐํ•ฉํ•˜์—ฌ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์•„์šฐ๋ฅด๋Š” ์•ฑ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ณง ์ถœ์‹œ๋  ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ณธ์งˆ์ ์œผ๋กœ React์˜ ๋™์‹œ์„ฑ๊ณผ ๊ฒฐํ•ฉํ•˜์—ฌ ์žˆ์ง€๋Š” ์•Š์ง€๋งŒ, Suspense ๋ฐ ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง๊ณผ ๊ฐ™์€ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์— ๊ฐ€์žฅ ์ž˜ ๋™์ž‘ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์•„์ง ์‹คํ—˜ ๋‹จ๊ณ„์ด์ง€๋งŒ 18.x ๋งˆ์ด๋„ˆ ๋ฆด๋ฆฌ์Šค์—์„œ ์ดˆ๊ธฐ ๋ฒ„์ „์„ ์ถœ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๊ทธ๋™์•ˆ์—๋Š” ์ด ์ œ์•ˆ์„ ๋ฐœ์ „์‹œํ‚ค๊ณ  ๊ด‘๋ฒ”์œ„ํ•œ ์ฑ„ํƒ์„ ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด Next.js, Hydrogen, Remix์™€ ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ํ˜‘๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์•„์ง ์‹คํ—˜ ๋‹จ๊ณ„์ด์ง€๋งŒ 18.x ๋งˆ์ด๋„ˆ ๋ฆด๋ฆฌ์Šค์—์„œ ์ดˆ๊ธฐ ๋ฒ„์ „์„ ์ถœ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๊ทธ ๋™์•ˆ์—๋Š” ์ด ์ œ์•ˆ์„ ๋ฐœ์ „์‹œํ‚ค๊ณ  ๊ด‘๋ฒ”์œ„ํ•œ ์ฑ„ํƒ์„ ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด Next.js, Hydrogen, Remix์™€ ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ํ˜‘๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ## React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ {/*whats-new-in-react-18*/} ### ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ: ์ž๋™ Batching {/*new-feature-automatic-batching*/} -Batching์€ React๊ฐ€ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด ์—ฌ๋Ÿฌ state ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๋‚˜์˜ ๋ฆฌ๋ Œ๋”๋ง์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž๋™ batching์ด ์—†์œผ๋ฉด ์šฐ๋ฆฌ๋Š” React ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์˜ ์—…๋ฐ์ดํŠธ๋งŒ batch ํ–ˆ์Šต๋‹ˆ๋‹ค. Promises, setTimeout, ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๊ธฐํƒ€ ์ด๋ฒคํŠธ ๋‚ด๋ถ€์˜ ์—…๋ฐ์ดํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ React์—์„œ batch ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ž๋™ Batching์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฌํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ž๋™์œผ๋กœ batch ๋ฉ๋‹ˆ๋‹ค. +Batching์€ React๊ฐ€ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด ์—ฌ๋Ÿฌ State ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๋‚˜์˜ ๋ฆฌ๋ Œ๋”๋ง์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž๋™ Batching์ด ์—†์„ ๋•Œ, ์šฐ๋ฆฌ๋Š” React ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์˜ ์—…๋ฐ์ดํŠธ๋งŒ Batch ํ–ˆ์Šต๋‹ˆ๋‹ค. Promises, `setTimeout`, ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๊ธฐํƒ€ ์ด๋ฒคํŠธ ๋‚ด๋ถ€์˜ ์—…๋ฐ์ดํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ React์—์„œ Batch ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ž๋™ Batching์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฌํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ž๋™์œผ๋กœ Batch ๋ฉ๋‹ˆ๋‹ค. ```js -// ๋ณ€๊ฒฝ ์ „: ์˜ค์ง React ์ด๋ฒคํŠธ๋งŒ batch ๋ฉ๋‹ˆ๋‹ค. +// ๋ณ€๊ฒฝ ์ „: ์˜ค์ง React ์ด๋ฒคํŠธ๋งŒ Batch ๋ฉ๋‹ˆ๋‹ค. setTimeout(() => { setCount(c => c + 1); setFlag(f => !f); - // React๋Š” ๊ฐ state ์—…๋ฐ์ดํŠธ๋งˆ๋‹ค ํ•œ ๋ฒˆ์”ฉ, ์ด ๋‘ ๋ฒˆ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. (batching ์•„๋‹˜) + // React๋Š” ๊ฐ State ์—…๋ฐ์ดํŠธ๋งˆ๋‹ค ํ•œ ๋ฒˆ์”ฉ, ์ด ๋‘ ๋ฒˆ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. (Batching ์—†์Œ) }, 1000); -// ๋ณ€๊ฒฝ ํ›„: timeouts, promises ๋‚ด์—์„œ๋„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -// ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋“ค์ด batch ๋ฉ๋‹ˆ๋‹ค. +// ๋ณ€๊ฒฝ ํ›„: setTimeout, Promises ๋‚ด์—์„œ๋„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +// ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋“ค์ด Batch ๋ฉ๋‹ˆ๋‹ค. setTimeout(() => { setCount(c => c + 1); setFlag(f => !f); - // React๋Š” ๋งˆ์ง€๋ง‰์— ํ•œ ๋ฒˆ๋งŒ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. (batching!) + // React๋Š” ๋งˆ์ง€๋ง‰์— ํ•œ ๋ฒˆ๋งŒ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. (๊ทธ๊ฒŒ Batching ์ด์ฃ !) }, 1000); ``` @@ -113,43 +113,43 @@ setTimeout(() => { ### ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ: Transitions {/*new-feature-transitions*/} -Transition์€ ๊ธด๊ธ‰ ์—…๋ฐ์ดํŠธ์™€ ๋น„๊ธด๊ธ‰ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•œ React์˜ ์ƒˆ๋กœ์šด ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. +Transition์€ ๊ธด๊ธ‰ํ•œ<sup>Urgent</sup> ์—…๋ฐ์ดํŠธ์™€ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€<sup>Non-Urgent</sup> ์—…๋ฐ์ดํŠธ๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•œ React์˜ ์ƒˆ๋กœ์šด ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. -* **๊ธด๊ธ‰ ์—…๋ฐ์ดํŠธ**๋Š” ์ž…๋ ฅ, ํด๋ฆญ, ๋ˆ„๋ฅด๊ธฐ ๋“ฑ๊ณผ ๊ฐ™์€ ์ง์ ‘์ ์ธ ์ƒํ˜ธ์ž‘์šฉ์„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. +* **๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ**๋Š” ์ž…๋ ฅ, ํด๋ฆญ, ๋ˆ„๋ฅด๊ธฐ ๋“ฑ๊ณผ ๊ฐ™์€ ์ง์ ‘์ ์ธ ์ƒํ˜ธ์ž‘์šฉ์„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. * **Transition ์—…๋ฐ์ดํŠธ**๋Š” UI๋ฅผ ํ•œ ํ™”๋ฉด์—์„œ ๋‹ค๋ฅธ ํ™”๋ฉด์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -์ž…๋ ฅ, ํด๋ฆญ, ๋ˆ„๋ฅด๊ธฐ ๋“ฑ์˜ ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ๋Š” ์‹ค์ œ ์‚ฌ๋ฌผ์˜ ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์šฐ๋ฆฌ์˜ ์ง๊ด€๊ณผ ์ผ์น˜ํ•˜๋„๋ก ์ฆ‰๊ฐ์ ์ธ ๋ฐ˜์‘์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด "์ž˜๋ชป๋๋‹ค"๊ณ  ๋А๋ผ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ transition์€ ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์— ๋ชจ๋“  ์ค‘๊ฐ„๊ฐ’์„ ๋ณผ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฆ…๋‹ˆ๋‹ค. +์ž…๋ ฅ, ํด๋ฆญ, ๋ˆ„๋ฅด๊ธฐ ๋“ฑ์˜ ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ๋Š” ์‹ค์ œ ์‚ฌ๋ฌผ์˜ ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์šฐ๋ฆฌ์˜ ์ง๊ด€๊ณผ ์ผ์น˜ํ•˜๋„๋ก ์ฆ‰๊ฐ์ ์ธ ๋ฐ˜์‘์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด "์ž˜๋ชป๋๋‹ค"๊ณ  ๋А๋ผ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Transition์€ ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์— ๋ชจ๋“  ์ค‘๊ฐ„๊ฐ’์„ ๋ณผ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋“œ๋กญ๋‹ค์šด์—์„œ ํ•„ํ„ฐ๋ฅผ ์„ ํƒํ•˜๋ฉด ํด๋ฆญ ์ฆ‰์‹œ ํ•„ํ„ฐ ๋ฒ„ํŠผ ์ž์ฒด๊ฐ€ ๋ฐ˜์‘ํ•  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ๊ฒฐ๊ณผ๋Š” ๋ณ„๋„๋กœ ์ „ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฝ๊ฐ„์˜ ์ง€์—ฐ์€ ๋ˆˆ์— ๋„์ง€ ์•Š๊ณ  ์ข…์ข… ์˜ˆ์ƒ๋˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋ Œ๋”๋ง ๋˜๊ธฐ ์ „์— ํ•„ํ„ฐ๋ฅผ ๋‹ค์‹œ ๋ณ€๊ฒฝํ•˜๋ฉด ์˜ค์ง ์ตœ์‹  ๊ฒฐ๊ณผ๋งŒ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ผ๋ฐ˜์ ์œผ๋กœ ์ตœ์ƒ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์œ„ํ•ด์„œ๋Š” ํ•œ ๋ฒˆ์˜ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์œผ๋กœ ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ์™€ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ชจ๋‘ ์ด๋ฃจ์–ด์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ ์ด๋ฒคํŠธ ๋‚ด์—์„œ startTransition API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋–ค ์—…๋ฐ์ดํŠธ๊ฐ€ ๊ธด๊ธ‰ํ•œ์ง€, ์–ด๋–ค ์—…๋ฐ์ดํŠธ๊ฐ€ "transition"์ธ์ง€ React์— ์•Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ผ๋ฐ˜์ ์œผ๋กœ ์ตœ์ƒ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์œ„ํ•ด์„œ๋Š” ํ•œ ๋ฒˆ์˜ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์œผ๋กœ ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ์™€ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ชจ๋‘ ์ด๋ฃจ์–ด์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ ์ด๋ฒคํŠธ ๋‚ด์—์„œ `startTransition` API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋–ค ์—…๋ฐ์ดํŠธ๊ฐ€ ๊ธด๊ธ‰ํ•œ์ง€, ์–ด๋–ค ์—…๋ฐ์ดํŠธ๊ฐ€ "Transition"์ธ์ง€ React์— ์•Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js import { startTransition } from 'react'; -// ๊ธด๊ธ‰: Urgent: ์ž…๋ ฅํ•œ ๋‚ด์šฉ ํ‘œ์‹œ +// ๊ธด๊ธ‰(Urgent): ์ž…๋ ฅํ•œ ๋‚ด์šฉ ํ‘œ์‹œ setInputValue(input); -// ๋‚ด๋ถ€์˜ ๋ชจ๋“  state ์—…๋ฐ์ดํŠธ๋ฅผ transition์œผ๋กœ ํ‘œ์‹œ +// ๋‚ด๋ถ€์˜ ๋ชจ๋“  State ์—…๋ฐ์ดํŠธ๋ฅผ Transition์œผ๋กœ ํ‘œ์‹œ startTransition(() => { // Transition: ๊ฒฐ๊ณผ ํ‘œ์‹œ setSearchQuery(input); }); ``` -startTransition์œผ๋กœ ๋ž˜ํ•‘๋œ ์—…๋ฐ์ดํŠธ๋Š” ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉฐ ํด๋ฆญ์ด๋‚˜ ํ‚ค ๋ˆ„๋ฆ„๊ณผ ๊ฐ™์€ ๋” ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋“ค์–ด์˜ฌ ๊ฒฝ์šฐ ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์—ฌ๋Ÿฌ ๋ฌธ์ž๋ฅผ ์—ฐ์†ํ•ด์„œ ์ž…๋ ฅํ•˜๋Š” ๋“ฑ์˜ ์ด์œ ๋กœ transition์ด ์ค‘๋‹จ๋˜๋ฉด React๋Š” ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ์˜ค๋ž˜๋œ ๋ Œ๋”๋ง ์ž‘์—…์„ ๋ฒ„๋ฆฌ๊ณ  ์ตœ์‹  ์—…๋ฐ์ดํŠธ๋งŒ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. +`startTransition`์œผ๋กœ ๋ž˜ํ•‘๋œ ์—…๋ฐ์ดํŠธ๋Š” ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉฐ ํด๋ฆญ์ด๋‚˜ ํ‚ค ๋ˆ„๋ฆ„๊ณผ ๊ฐ™์€ ๋” ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋“ค์–ด์˜ฌ ๊ฒฝ์šฐ ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์—ฌ๋Ÿฌ ๋ฌธ์ž๋ฅผ ์—ฐ์†ํ•ด์„œ ์ž…๋ ฅํ•˜๋Š” ๋“ฑ์˜ ์ด์œ ๋กœ Transition์ด ์ค‘๋‹จ๋˜๋ฉด, React๋Š” ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ์˜ค๋ž˜๋œ ๋ Œ๋”๋ง ์ž‘์—…์„ ๋ฒ„๋ฆฌ๊ณ  ์ตœ์‹  ์—…๋ฐ์ดํŠธ๋งŒ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. -* `useTransition`: ๋ณด๋ฅ˜ ์ค‘์ธ(pending) state๋ฅผ ์ถ”์ ํ•˜๋Š” ๊ฐ’์„ ํฌํ•จํ•˜์—ฌ transition์„ ์‹œ์ž‘ํ•˜๋Š” Hook. -* `startTransition`: Hook์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์„ ๋•Œ transition์„ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”์„œ๋“œ. +* `useTransition`: ๋ณด๋ฅ˜ ์ค‘์ธ<sup>Pending</sup> State๋ฅผ ์ถ”์ ํ•˜๋Š” ๊ฐ’์„ ํฌํ•จํ•˜์—ฌ Transition์„ ์‹œ์ž‘ํ•˜๋Š” Hook. +* `startTransition`: Hook์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์„ ๋•Œ Transition์„ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”์„œ๋“œ. -transition์€ concurrent ๋ Œ๋”๋ง์„ ์„ ํƒํ•˜์—ฌ ์—…๋ฐ์ดํŠธ๋ฅผ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ค์‹œ ์ผ์‹œ ์ค‘๋‹จ๋˜๋ฉด, transition์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ transition ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ ํ˜„์žฌ ์ฝ˜ํ…์ธ ๋ฅผ ๊ณ„์† ํ‘œ์‹œํ•˜๋„๋ก React์— ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. (์ž์„ธํ•œ ๋‚ด์šฉ์€ [Suspense RFC](https://github.com/reactjs/rfcs/blob/main/text/0213-suspense-in-react-18.md)๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.) +Transition์€ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง์„ ์„ ํƒํ•˜์—ฌ ์—…๋ฐ์ดํŠธ๋ฅผ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ค์‹œ ์ผ์‹œ ์ค‘๋‹จ๋˜๋ฉด, Transition์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ Transition ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ ํ˜„์žฌ ์ฝ˜ํ…์ธ ๋ฅผ ๊ณ„์† ํ‘œ์‹œํ•˜๋„๋ก React์— ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. (์ž์„ธํ•œ ๋‚ด์šฉ์€ [Suspense RFC](https://github.com/reactjs/rfcs/blob/main/text/0213-suspense-in-react-18.md)๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.) -[Transitions ์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useTransition) +[Transitions ์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useTransition). -### ์ƒˆ๋กœ์šด Suspense ๊ธฐ๋Šฅ๋“ค {/*new-suspense-features*/} +### ์ƒˆ๋กœ์šด Suspense ๊ธฐ๋Šฅ {/*new-suspense-features*/} -Suspense๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์˜ ์ผ๋ถ€๊ฐ€ ์•„์ง ํ‘œ์‹œ๋  ์ค€๋น„๊ฐ€ ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋กœ๋”ฉ state๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +Suspense๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์˜ ์ผ๋ถ€๊ฐ€ ์•„์ง ํ‘œ์‹œ๋  ์ค€๋น„๊ฐ€ ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ๋กœ๋”ฉ State๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js <Suspense fallback={<Spinner />}> @@ -157,103 +157,103 @@ Suspense๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์˜ ์ผ๋ถ€๊ฐ€ ์•„์ง ํ‘œ์‹œ๋  ์ค€ </Suspense> ``` -Suspense๋Š” "UI ๋กœ๋”ฉ ์ƒํƒœ"๋ฅผ React ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์—์„œ 1๊ธ‰ ์„ ์–ธ์  ๊ฐœ๋…์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ทธ ์œ„์— ๋” ๋†’์€ ์ˆ˜์ค€์˜ ๊ธฐ๋Šฅ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +Suspense๋Š” "UI ๋กœ๋”ฉ ์ƒํƒœ"๋ฅผ React ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์—์„œ 1๊ธ‰ ์„ ์–ธ์  ๊ฐœ๋…์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ทธ ์œ„์— ๊ณ ์ˆ˜์ค€<sup>Higher-Level</sup>์˜ ๊ธฐ๋Šฅ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์šฐ๋ฆฌ๋Š” ๋ช‡ ๋…„ ์ „์— Suspense์˜ ์ œํ•œ๋œ ๋ฒ„์ „์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ง€์›๋˜๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” React.lazy๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ ๋ถ„ํ• ๋ฟ์ด์—ˆ์œผ๋ฉฐ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•  ๋•Œ๋Š” ์ „ํ˜€ ์ง€์›๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. +์ €ํฌ๋Š” ๋ช‡ ๋…„ ์ „์— Suspense์˜ ์ œํ•œ๋œ ๋ฒ„์ „์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ง€์›๋˜๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” `React.lazy`๋ฅผ ์ด์šฉํ•œ ์ฝ”๋“œ ๋ถ„ํ• ๋ฟ์ด์—ˆ์œผ๋ฉฐ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•  ๋•Œ๋Š” ์ „ํ˜€ ์ง€์›๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. -React 18์—์„œ๋Š” ์„œ๋ฒ„์—์„œ Suspense์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๊ณ  concurrent ๋ Œ๋”๋ง ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. +React 18์—์„œ๋Š” ์„œ๋ฒ„์—์„œ Suspense์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋™์‹œ์„ฑ ๋ Œ๋”๋ง ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. -React 18์˜ Suspense๋Š” transition API์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ€์žฅ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. transition ๋„์ค‘ ์ผ์‹œ ์ค‘๋‹จํ•˜๋ฉด, React๋Š” ์ด๋ฏธ ํ‘œ์‹œ๋œ ์ฝ˜ํ…์ธ ๊ฐ€ fallback์œผ๋กœ ๋Œ€์ฒด๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  React๋Š” ์ถฉ๋ถ„ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๋ Œ๋”๋ง์„ ์ง€์—ฐ์‹œ์ผœ ๋กœ๋”ฉ ์ƒํƒœ๊ฐ€ ๋‚˜๋น ์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. +React 18์˜ Suspense๋Š” Transition API์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ€์žฅ ์ž˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. Transition ๋„์ค‘ ์ผ์‹œ ์ค‘๋‹จํ•˜๋ฉด, React๋Š” ์ด๋ฏธ ํ‘œ์‹œ๋œ ์ฝ˜ํ…์ธ ๊ฐ€ Fallback์œผ๋กœ ๋Œ€์ฒด๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  React๋Š” ์ถฉ๋ถ„ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๋ Œ๋”๋ง์„ ์ง€์—ฐ์‹œ์ผœ ๋กœ๋”ฉ ์ƒํƒœ๊ฐ€ ๋‚˜๋น ์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. -[Suspense in React 18 ์ฐธ๊ณ  ๋ฌธ์„œ](https://github.com/reactjs/rfcs/blob/main/text/0213-suspense-in-react-18.md) +์ž์„ธํ•œ ๋‚ด์šฉ์€ [Suspense in React 18](https://github.com/reactjs/rfcs/blob/main/text/0213-suspense-in-react-18.md)์— ๋Œ€ํ•œ RFC๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”. -### ์ƒˆ๋กœ์šด ํด๋ผ์ด์–ธํŠธ ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง API๋“ค {/*new-client-and-server-rendering-apis*/} +### ์ƒˆ๋กœ์šด ํด๋ผ์ด์–ธํŠธ ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง API {/*new-client-and-server-rendering-apis*/} ์ด๋ฒˆ ๋ฆด๋ฆฌ์Šค์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง์„ ์œ„ํ•ด ๋…ธ์ถœํ•˜๋Š” API๋ฅผ ์žฌ์„ค๊ณ„ํ•  ๊ธฐํšŒ๋ฅผ ๊ฐ€์กŒ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž๋Š” React 18์˜ ์ƒˆ๋กœ์šด API๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋™์•ˆ React 17 ๋ชจ๋“œ์—์„œ ์ด์ „ API๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #### React DOM ํด๋ผ์ด์–ธํŠธ {/*react-dom-client*/} -์ด ์ƒˆ๋กœ์šด API๋Š” ์ด์ œ `react-dom/client`์—์„œ ๋‚ด๋ณด๋‚ด์ง‘๋‹ˆ๋‹ค. +์ƒˆ๋กœ์šด API๋Š” ์ด์ œ `react-dom/client`์—์„œ ๋‚ด๋ณด๋‚ด์ง‘๋‹ˆ๋‹ค. -* `createRoot`: `๋ Œ๋”๋ง` ๋˜๋Š” `unmount`์— ๋ฃจํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ. `ReactDOM.render` ๋Œ€์‹  ์‚ฌ์šฉํ•˜์„ธ์š”. ์ด ํ•จ์ˆ˜๊ฐ€ ์—†์œผ๋ฉด React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์ด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -* `hydrateRoot`: ์„œ๋ฒ„ ๋ Œ๋”๋ง๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ hydrateํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ. ์ƒˆ๋กœ์šด React DOM ์„œ๋ฒ„ API์™€ ํ•จ๊ป˜ `ReactDOM.hydrate` ๋Œ€์‹  ์‚ฌ์šฉํ•˜์„ธ์š”. ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ์—†์œผ๋ฉด React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +* `createRoot`: `render` ๋˜๋Š” `unmount`์— Root๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ. `ReactDOM.render` ๋Œ€์‹  ์‚ฌ์šฉํ•˜์„ธ์š”. ์ด ํ•จ์ˆ˜๊ฐ€ ์—†์œผ๋ฉด React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์ด ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +* `hydrateRoot`: ์„œ๋ฒ„ ๋ Œ๋”๋ง๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ Hydrateํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ. ์ƒˆ๋กœ์šด React DOM ์„œ๋ฒ„ API์™€ ํ•จ๊ป˜ `ReactDOM.hydrate` ๋Œ€์‹  ์‚ฌ์šฉํ•˜์„ธ์š”. ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ์—†์œผ๋ฉด React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์ด ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -`createRoot`์™€ `hydrateRoot`๋Š” ๋ชจ๋‘ ๋ Œ๋”๋ง ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ๋กœ๊น…์„ ์œ„ํ•œ hydration ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์•Œ๋ฆผ์„ ๋ฐ›๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ `onRecoverableError`๋ผ๋Š” ์ƒˆ๋กœ์šด ์˜ต์…˜์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ React๋Š” [`reportError`](https://developer.mozilla.org/en-US/docs/Web/API/reportError) ๋˜๋Š” ์˜ค๋ž˜๋œ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” `console.error`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +`createRoot`์™€ `hydrateRoot`๋Š” ๋ชจ๋‘ ๋ Œ๋”๋ง ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ๋กœ๊น…์„ ์œ„ํ•œ Hydration ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์•Œ๋ฆผ์„ ๋ฐ›๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ `onRecoverableError`๋ผ๋Š” ์ƒˆ๋กœ์šด ์˜ต์…˜์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ React๋Š” [`reportError`](https://developer.mozilla.org/en-US/docs/Web/API/reportError) ๋˜๋Š” ์˜ค๋ž˜๋œ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” `console.error`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -[React DOM ํด๋ผ์ด์–ธํŠธ ์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react-dom/client) +[React DOM ํด๋ผ์ด์–ธํŠธ ์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react-dom/client). #### React DOM ์„œ๋ฒ„ {/*react-dom-server*/} -์ด ์ƒˆ๋กœ์šด API๋Š” ์ด์ œ `react-dom/server`์—์„œ ๋‚ด๋ณด๋‚ด์ง€๋ฉฐ ์„œ๋ฒ„์—์„œ Suspense๋ฅผ ์ŠคํŠธ๋ฆฌ๋ฐํ•˜๋Š” ๋ฐ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›๋ฉ๋‹ˆ๋‹ค. +์ด ์ƒˆ๋กœ์šด API๋Š” ์ด์ œ `react-dom/server`์—์„œ ๋‚ด๋ณด๋‚ด์ง€๋ฉฐ ์„œ๋ฒ„์—์„œ์˜ Suspense ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. * `renderToPipeableStream`: Node ํ™˜๊ฒฝ์—์„œ์˜ ์ŠคํŠธ๋ฆฌ๋ฐ์šฉ. * `renderToReadableStream`: ์ตœ์‹  ์—ฃ์ง€ ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ(์˜ˆ: Deno ๋ฐ Cloudflare ์›Œ์ปค)์—์„œ์˜ ์ŠคํŠธ๋ฆฌ๋ฐ์šฉ. -๊ธฐ์กด์˜ `renderToString` ๋ฉ”์„œ๋“œ๋Š” ๊ณ„์† ์ž‘๋™ํ•˜์ง€๋งŒ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +๊ธฐ์กด์˜ `renderToString` ๋ฉ”์„œ๋“œ๋Š” ๊ณ„์† ๋™์ž‘ํ•˜์ง€๋งŒ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -[React DOM ์„œ๋ฒ„ ์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react-dom/server) +[React DOM ์„œ๋ฒ„ ์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react-dom/server). -### ์ƒˆ๋กœ์šด Strict ๋ชจ๋“œ ๋™์ž‘๋“ค {/*new-strict-mode-behaviors*/} +### ์ƒˆ๋กœ์šด Strict ๋ชจ๋“œ ๋™์ž‘ {/*new-strict-mode-behaviors*/} -์•ž์œผ๋กœ๋Š” React๊ฐ€ state๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ UI์˜ ์„น์…˜์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ ๋ฒ—์–ด๋‚˜ ๋’ค๋กœ ํƒญ ํ•  ๋•Œ React๋Š” ์ด์ „ ํ™”๋ฉด์„ ์ฆ‰์‹œ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด React๋Š” ์ด์ „๊ณผ ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ state๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋ฆฌ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค. +์•ž์œผ๋กœ๋Š” React๊ฐ€ State๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ UI์˜ ์„น์…˜์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ ๋ฒ—์–ด๋‚˜ ๋’ค๋กœ ํƒญ ํ•  ๋•Œ React๋Š” ์ด์ „ ํ™”๋ฉด์„ ์ฆ‰์‹œ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด React๋Š” ์ด์ „๊ณผ ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ State๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋ฆฌ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค. -์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด React ์•ฑ์˜ ์„ฑ๋Šฅ์ด ์ฆ‰์‹œ ํ–ฅ์ƒ๋˜์ง€๋งŒ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ effect๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ ๋งˆ์šดํŠธ ๋ฐ ์†Œ๋ฉธํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ํƒ„๋ ฅ์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ effect๋Š” ๋ณ€๊ฒฝ ์—†์ด ์ž‘๋™ํ•˜์ง€๋งŒ ์ผ๋ถ€ effect๋Š” ํ•œ ๋ฒˆ๋งŒ ๋งˆ์šดํŠธ๋˜๊ฑฐ๋‚˜ ์†Œ๋ฉธํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. +์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด React ์•ฑ์˜ ์„ฑ๋Šฅ์ด ์ฆ‰์‹œ ํ–ฅ์ƒ๋˜์ง€๋งŒ, ์ปดํฌ๋„ŒํŠธ์˜ Effect๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ ๋งˆ์šดํŠธ ๋ฐ ์†Œ๋ฉธํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ํƒ„๋ ฅ์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ Effect๋Š” ๋ณ€๊ฒฝ ์—†์ด ๋™์ž‘ํ•˜์ง€๋งŒ ์ผ๋ถ€ Effect๋Š” ํ•œ ๋ฒˆ๋งŒ ๋งˆ์šดํŠธ๋˜๊ฑฐ๋‚˜ ์†Œ๋ฉธํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. -์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด React 18์€ Strict ๋ชจ๋“œ์— ์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ ์ „์šฉ ๊ฒ€์‚ฌ๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ƒˆ๋กœ์šด ๊ฒ€์‚ฌ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ๋  ๋•Œ๋งˆ๋‹ค ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž๋™์œผ๋กœ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•˜์—ฌ ๋‘ ๋ฒˆ์งธ ๋งˆ์šดํŠธ ์‹œ ์ด์ „ state๋กœ ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค. +์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด React 18์€ Strict ๋ชจ๋“œ์— ์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ ์ „์šฉ ๊ฒ€์‚ฌ๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ƒˆ๋กœ์šด ๊ฒ€์‚ฌ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ๋  ๋•Œ๋งˆ๋‹ค ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž๋™์œผ๋กœ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•˜์—ฌ ๋‘ ๋ฒˆ์งธ ๋งˆ์šดํŠธ ์‹œ ์ด์ „ State๋กœ ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค. -์ด ๋ณ€๊ฒฝ ์ „์—๋Š” React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•˜๊ณ  effect๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. +๋ณ€๊ฒฝ ์ „์—๋Š” React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•˜๊ณ  Effect๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ``` * React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค. - * ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. - * Effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. + * ๋ ˆ์ด์•„์›ƒ ์ดํŽ™ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. + * Effect ์ดํŽ™ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ``` React 18์˜ Strict ๋ชจ๋“œ์—์„œ๋Š” ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. ``` * React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค. - * ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. - * Effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. -* React๊ฐ€ ์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ ํ•ด์ œ๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. - * ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์†Œ๋ฉธํ•ฉ๋‹ˆ๋‹ค. - * Effect๊ฐ€ ์†Œ๋ฉธํ•ฉ๋‹ˆ๋‹ค. -* React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์ „ ์ƒํƒœ๋กœ ๋งˆ์šดํŠธํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. - * ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. - * Effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. + * ๋ ˆ์ด์•„์›ƒ ์ดํŽ™ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. + * Effect ์ดํŽ™ํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. +* React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. + * ๋ ˆ์ด์•„์›ƒ ์ดํŽ™ํŠธ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. + * ์ดํŽ™ํŠธ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. +* React๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์ „ ์ƒํƒœ๋กœ ๋‹ค์‹œ ๋งˆ์šดํŠธํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. + * ๋ ˆ์ด์•„์›ƒ ์ดํŽ™ํŠธ ์…‹์—… ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. + * Effect ์…‹์—… ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ``` -[์—ฌ๊ธฐ์—์„œ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” state ๋ณด์žฅ์— ๋Œ€ํ•œ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”](/reference/react/StrictMode#fixing-bugs-found-by-re-running-effects-in-development). +[์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ State๋ฅผ ๋ณด์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”](/reference/react/StrictMode#fixing-bugs-found-by-re-running-effects-in-development). -### ์ƒˆ๋กœ์šด Hooks {/*new-hooks*/} +### ์ƒˆ๋กœ์šด Hook {/*new-hooks*/} -#### useId {/*useid*/} +#### `useId` {/*useid*/} -`useId`๋Š” hydration ๋ถˆ์ผ์น˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋ฉด์„œ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๋ชจ๋‘์—์„œ ๊ณ ์œ  ID๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ๊ณ ์œ  ID๊ฐ€ ํ•„์š”ํ•œ ์ ‘๊ทผ์„ฑ API์™€ ํ†ตํ•ฉ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” React 17 ์ดํ•˜์—์„œ ์ด๋ฏธ ์กด์žฌํ•˜๋˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋งŒ, ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ๊ฐ€ HTML์„ ์ˆœ์„œ๋Œ€๋กœ ์ „๋‹ฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— React 18์—์„œ๋Š” ๋”์šฑ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. [์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useId) +`useId`๋Š” Hydration ๋ถˆ์ผ์น˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋ฉด์„œ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๋ชจ๋‘์—์„œ ๊ณ ์œ  ID๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ๊ณ ์œ  ID๊ฐ€ ํ•„์š”ํ•œ ์ ‘๊ทผ์„ฑ API์™€ ํ†ตํ•ฉ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” React 17 ์ดํ•˜์—์„œ ์ด๋ฏธ ์กด์žฌํ•˜๋˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋งŒ, ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ๊ฐ€ HTML์„ ์ˆœ์„œ๋Œ€๋กœ ์ „๋‹ฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— React 18์—์„œ๋Š” ๋”์šฑ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. [์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useId). > ์ฃผ์˜ > -> `useId`๋Š” [๋ชฉ๋ก์—์„œ key](/learn/rendering-lists#where-to-get-your-key)๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด *์•„๋‹™๋‹ˆ๋‹ค*. Key๋Š” ์—ฌ๋Ÿฌ๋ถ„์˜ ๋ฐ์ดํ„ฐ์—์„œ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +> `useId`๋Š” [๋ชฉ๋ก์—์„œ Key](/learn/rendering-lists#where-to-get-your-key)๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด *์•„๋‹™๋‹ˆ๋‹ค*. Key๋Š” ์—ฌ๋Ÿฌ๋ถ„์˜ ๋ฐ์ดํ„ฐ์—์„œ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -#### useTransition {/*usetransition*/} +#### `useTransition` {/*usetransition*/} -`useTransition`์™€ `startTransition`์„ ์‚ฌ์šฉํ•˜๋ฉด ์ผ๋ถ€ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค๋ฅธ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋Š” ๊ธด๊ธ‰ํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. React๋Š” ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ์ƒํƒœ ์—…๋ฐ์ดํŠธ(์˜ˆ: ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋ชฉ๋ก ๋ Œ๋”๋ง)๋ฅผ ๊ธด๊ธ‰ํ•œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ(์˜ˆ: ํ…์ŠคํŠธ ์ž…๋ ฅ ์—…๋ฐ์ดํŠธ)๋กœ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. [์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useTransition). +`useTransition`์™€ `startTransition`์„ ์‚ฌ์šฉํ•˜๋ฉด ์ผ๋ถ€ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค๋ฅธ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋Š” ๊ธด๊ธ‰ํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. React๋Š” ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ์ƒํƒœ ์—…๋ฐ์ดํŠธ(์˜ˆ: ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋ชฉ๋ก ๋ Œ๋”๋ง)๋ฅผ ๊ธด๊ธ‰ํ•œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ(์˜ˆ: ํ…์ŠคํŠธ ์ž…๋ ฅ ์—…๋ฐ์ดํŠธ)๋กœ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. [์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useTransition). -#### useDeferredValue {/*usedeferredvalue*/} +#### `useDeferredValue` {/*usedeferredvalue*/} -`useDeferredValue`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŠธ๋ฆฌ์—์„œ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ๋ถ€๋ถ„์˜ ๋ฆฌ๋ Œ๋”๋ง์„ ์ง€์—ฐ(deferred)์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋””๋ฐ”์šด์‹ฑ๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ๋””๋ฐ”์šด์‹ฑ์— ๋น„ํ•ด ๋ช‡ ๊ฐ€์ง€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณ ์ •๋œ ์‹œ๊ฐ„ ์ง€์—ฐ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— React๋Š” ์ฒซ ๋ฒˆ์งธ ๋ Œ๋”๋ง์ด ํ™”๋ฉด์— ๋ฐ˜์˜๋œ ์งํ›„์— deferred ๋ Œ๋”๋ง์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. deferred ๋ Œ๋”๋ง์€ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. [์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useDeferredValue) +`useDeferredValue`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŠธ๋ฆฌ์—์„œ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ๋ถ€๋ถ„์˜ ๋ฆฌ๋ Œ๋”๋ง์„ ์ง€์—ฐ<sup>Deferred</sup>์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋””๋ฐ”์šด์‹ฑ๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ๋””๋ฐ”์šด์‹ฑ์— ๋น„ํ•ด ๋ช‡ ๊ฐ€์ง€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณ ์ •๋œ ์‹œ๊ฐ„ ์ง€์—ฐ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— React๋Š” ์ฒซ ๋ฒˆ์งธ ๋ Œ๋”๋ง์ด ํ™”๋ฉด์— ๋ฐ˜์˜๋œ ์งํ›„์— ์ง€์—ฐ๋œ<sup>Deferred</sup> ๋ Œ๋”๋ง์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ์ง€์—ฐ๋œ<sup>Deferred</sup> ๋ Œ๋”๋ง์€ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. [์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useDeferredValue). -#### useSyncExternalStore {/*usesyncexternalstore*/} +#### `useSyncExternalStore` {/*usesyncexternalstore*/} -`useSyncExternalStore`๋Š” ์Šคํ† ์–ด์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฐ•์ œ๋กœ ๋™๊ธฐํ™”ํ•˜์—ฌ ์™ธ๋ถ€ ์Šคํ† ์–ด๊ฐ€ ๋™์‹œ ์ฝ๊ธฐ๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ด Hook์€ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๊ตฌ๋…์„ ๊ตฌํ˜„ํ•  ๋•Œ useEffect๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฉฐ, React ์™ธ๋ถ€ state์™€ ํ†ตํ•ฉํ•˜๋Š” ๋ชจ๋“  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. [์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useSyncExternalStore) +`useSyncExternalStore`๋Š” Store์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฐ•์ œ๋กœ ๋™๊ธฐํ™”ํ•˜์—ฌ ์™ธ๋ถ€ Store๊ฐ€ ๋™์‹œ ์ฝ๊ธฐ๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ด Hook์€ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๊ตฌ๋…์„ ๊ตฌํ˜„ํ•  ๋•Œ `useEffect`๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฉฐ, React ์™ธ๋ถ€ State์™€ ํ†ตํ•ฉํ•˜๋Š” ๋ชจ๋“  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. [์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useSyncExternalStore). > ์ฃผ์˜ > > `useSyncExternalStore`๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -#### useInsertionEffect {/*useinsertioneffect*/} +#### `useInsertionEffect` {/*useinsertioneffect*/} -`useInsertionEffect`๋Š” CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ Œ๋”๋ง์—์„œ ์Šคํƒ€์ผ์„ ์‚ฝ์ž…ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์ด Hook์„ ์‚ฌ์šฉํ•  ์ผ์€ ์—†์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. ์ด Hook์€ DOM์ด ๋ณ€๊ฒฝ๋œ ํ›„์— ์‹คํ–‰๋˜์ง€๋งŒ, ๋ ˆ์ด์•„์›ƒ effects๊ฐ€ ์ƒˆ ๋ ˆ์ด์•„์›ƒ์„ ์ฝ๊ธฐ ์ „์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” React 17 ์ดํ•˜์—์„œ ์ด๋ฏธ ์กด์žฌํ•˜๋˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋งŒ, React 18์—์„œ๋Š” concurrent ๋ Œ๋”๋ง ์ค‘์— ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ ˆ์ด์•„์›ƒ์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ๊ธฐํšŒ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋”์šฑ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. [์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useInsertionEffect) +`useInsertionEffect`๋Š” CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ Œ๋”๋ง์—์„œ ์Šคํƒ€์ผ์„ ์‚ฝ์ž…ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์ด Hook์„ ์‚ฌ์šฉํ•  ์ผ์€ ์—†์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. ์ด Hook์€ DOM์ด ๋ณ€๊ฒฝ๋œ ํ›„์— ์‹คํ–‰๋˜์ง€๋งŒ, ๋ ˆ์ด์•„์›ƒ Effect๊ฐ€ ์ƒˆ ๋ ˆ์ด์•„์›ƒ์„ ์ฝ๊ธฐ ์ „์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” React 17 ์ดํ•˜์—์„œ ์ด๋ฏธ ์กด์žฌํ•˜๋˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋งŒ, React 18์—์„œ๋Š” ๋™์‹œ์„ฑ ๋ Œ๋”๋ง ์ค‘์— ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ ˆ์ด์•„์›ƒ์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ๊ธฐํšŒ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋”์šฑ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. [์ฐธ๊ณ  ๋ฌธ์„œ](/reference/react/useInsertionEffect). > ์ฃผ์˜ > diff --git a/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md b/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md index 923cf9376..f8fcaa7e5 100644 --- a/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md +++ b/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md @@ -34,7 +34,7 @@ Vercel ๋ฐ Shopify์™€ ํ˜‘๋ ฅํ•˜์—ฌ Webpack ๋ฐ Vite ๋ชจ๋‘์—์„œ ๊ณต์œ  ์‹œ๋งจ ํ˜„์žฌ, ์Šคํฌ๋ฆฝํŠธ, ์™ธ๋ถ€ ์Šคํƒ€์ผ, ๊ธ€๊ผด ๋ฐ ์ด๋ฏธ์ง€์™€ ๊ฐ™์€ ๋ฆฌ์†Œ์Šค๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์™ธ๋ถ€ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์ „ ๋กœ๋“œ๋˜๊ณ  ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์ŠคํŠธ๋ฆฌ๋ฐ, ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๋“ฑ๊ณผ ๊ฐ™์€ ์ƒˆ๋กœ์šด ํ™˜๊ฒฝ์—์„œ ์กฐ์ •ํ•˜๊ธฐ ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  React ํ™˜๊ฒฝ์—์„œ ์ž‘๋™ํ•˜๋Š” React API๋ฅผ ํ†ตํ•ด ์ค‘๋ณต ์ œ๊ฑฐ๋œ ์™ธ๋ถ€ ์ž์‚ฐ์„ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•˜๊ณ  ๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•ด API๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -์šฐ๋ฆฌ๋Š” ๋˜ํ•œ Suspense๋ฅผ ์ง€์›ํ•˜์—ฌ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ํ‘œ์‹œ๋ฅผ ์ฐจ๋‹จํ•˜์ง€๋งŒ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐ ๋™์‹œ ๋ Œ๋”๋ง์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๋Š” ์ด๋ฏธ์ง€, CSS ๋ฐ ๊ธ€๊ผด์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์‹œ๊ฐ์  ์š”์†Œ๊ฐ€ ํŠ€์–ด๋‚˜์˜ค๊ณ  ๋ ˆ์ด์•„์›ƒ์ด ๋ฐ”๋€” ๋•Œ ["popcorning"](https://twitter.com/sebmarkbage/status/1516852731251724293)์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์šฐ๋ฆฌ๋Š” ๋˜ํ•œ Suspense๋ฅผ ์ง€์›ํ•˜์—ฌ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ํ‘œ์‹œ๋ฅผ ์ฐจ๋‹จํ•˜์ง€๋งŒ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐ ๋™์‹œ์„ฑ ๋ Œ๋”๋ง์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๋Š” ์ด๋ฏธ์ง€, CSS ๋ฐ ๊ธ€๊ผด์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์‹œ๊ฐ์  ์š”์†Œ๊ฐ€ ํŠ€์–ด๋‚˜์˜ค๊ณ  ๋ ˆ์ด์•„์›ƒ์ด ๋ฐ”๋€” ๋•Œ ["popcorning"](https://twitter.com/sebmarkbage/status/1516852731251724293)์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ์ •์  ์„œ๋ฒ„ ๋ Œ๋”๋ง ์ตœ์ ํ™” {/*static-server-rendering-optimizations*/} @@ -56,7 +56,7 @@ Vercel ๋ฐ Shopify์™€ ํ˜‘๋ ฅํ•˜์—ฌ Webpack ๋ฐ Vite ๋ชจ๋‘์—์„œ ๊ณต์œ  ์‹œ๋งจ ์˜คํ”„์Šคํฌ๋ฆฐ์€ UI๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ์ˆจ๊ธฐ๋˜ ์ฝ˜ํ…์ธ ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋‚ฎ์ถ”๋Š” ์„ธ ๋ฒˆ์งธ ์˜ต์…˜์„ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ์ด ์•„์ด๋””์–ด๋Š” `content-visibility` CSS ํ”„๋กœํผํ‹ฐ์™€ ๋น„์Šทํ•œ ๊ฐœ๋…์œผ๋กœ, ์ฝ˜ํ…์ธ ๊ฐ€ ์ˆจ๊ฒจ์ ธ ์žˆ์„ ๋•Œ ๋‚˜๋จธ์ง€ UI์™€ ๋™๊ธฐํ™” ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. React๋Š” ์•ฑ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์ด ์œ ํœด ์ƒํƒœ๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๋˜๋Š” ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ค์‹œ ํ‘œ์‹œ๋  ๋•Œ๊นŒ์ง€ ๋ Œ๋”๋ง ์ž‘์—…์„ ์—ฐ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์˜คํ”„์Šคํฌ๋ฆฐ์€ ๋†’์€ ์ˆ˜์ค€์˜ ๊ธฐ๋Šฅ์„ ์ž ๊ธˆ ํ•ด์ œํ•˜๋Š” ๋‚ฎ์€ ์ˆ˜์ค€์˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. `startTransition` ๊ณผ ๊ฐ™์€ React์˜ ๋‹ค๋ฅธ ๋™์‹œ ๊ธฐ๋Šฅ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์˜คํ”„์Šคํฌ๋ฆฐ API์™€ ์ง์ ‘ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๊ณ  ๋…๋‹จ์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŒจํ„ด์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. +์˜คํ”„์Šคํฌ๋ฆฐ์€ ๋†’์€ ์ˆ˜์ค€์˜ ๊ธฐ๋Šฅ์„ ์ž ๊ธˆ ํ•ด์ œํ•˜๋Š” ๋‚ฎ์€ ์ˆ˜์ค€์˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. `startTransition` ๊ณผ ๊ฐ™์€ React์˜ ๋‹ค๋ฅธ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์˜คํ”„์Šคํฌ๋ฆฐ API์™€ ์ง์ ‘ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๊ณ  ๋…๋‹จ์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŒจํ„ด์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. * **์ฆ‰๊ฐ์ ์ธ ์ „ํ™˜.** ์ผ๋ถ€ ๋ผ์šฐํŒ… ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๋งํฌ ์œ„๋กœ ๋งˆ์šฐ์Šค๋ฅผ ๊ฐ€์ ธ๊ฐˆ ๋•Œ์™€ ๊ฐ™์ด ํ›„์† ํƒ์ƒ‰ ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ด๋ฏธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์˜คํ”„์Šคํฌ๋ฆฐ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋‹ค์Œ ํ™”๋ฉด์„ ๋ฏธ๋ฆฌ ๋ Œ๋”๋งํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. * **์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ state.** ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฒฝ๋กœ๋‚˜ ํƒญ ์‚ฌ์ด๋ฅผ ํƒ์ƒ‰ํ•  ๋•Œ ์˜คํ”„์Šคํฌ๋ฆฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด์ „ ํ™”๋ฉด์˜ state๋ฅผ ๋ณด์กดํ•˜์—ฌ ์ค‘๋‹จํ•œ ์ง€์ ์—์„œ ๋‹ค์‹œ ์ „ํ™˜ํ•˜๊ณ  ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. diff --git a/src/content/blog/index.md b/src/content/blog/index.md index 8e0787649..8b9f06d6d 100644 --- a/src/content/blog/index.md +++ b/src/content/blog/index.md @@ -65,7 +65,7 @@ React 18์€ ์ˆ˜๋…„๊ฐ„์˜ ์ค€๋น„ ๋์— ํƒ„์ƒํ•œ ๋ฒ„์ „์œผ๋กœ React ํŒ€์—๊ฒŒ </BlogCard> <BlogCard title="React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•" date="2022๋…„ 3์›” 8์ผ" url="/blog/2022/03/08/react-18-upgrade-guide"> -React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ, ์ƒˆ๋กœ์šด ๋™์‹œ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. +React 18์€ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ, ์ƒˆ๋กœ์šด ๋™์‹œ์„ฑ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋„์ž…ํ•˜์—ฌ ๊ธฐ์กด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์ง„์ ์œผ๋กœ ์ ์šฉํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. </BlogCard> <BlogCard title="React Conf 2021 ์š”์•ฝ" date="2021๋…„ 12์›” 17์ผ" url="/blog/2021/12/17/react-conf-2021-recap"> From 29d7b8f1d023c69c5b6c8d952f9cfe999cdc7749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 14:44:43 +0900 Subject: [PATCH 0356/1059] docs: update `react-labs-what-we-have-benn-working-on-june-2022.md` --- ...-what-we-have-been-working-on-june-2022.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md b/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md index f8fcaa7e5..15586cd79 100644 --- a/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md +++ b/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md @@ -11,7 +11,7 @@ description: React 18 ์€ ์ˆ˜๋…„๊ฐ„์˜ ์ค€๋น„ ๋์— ํƒ„์ƒํ•œ ๋ฒ„์ „์œผ๋กœ Reac <Intro> -[React 18](/blog/2022/03/29/react-v18)์€ ์ˆ˜๋…„๊ฐ„์˜ ์ค€๋น„ ๋์— ํƒ„์ƒํ•œ ๋ฒ„์ „์œผ๋กœ React ํŒ€์—๊ฒŒ ๊ท€์ค‘ํ•œ ๊ตํ›ˆ์„ ๊ฐ€์ ธ๋‹ค์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ˆ˜๋…„๊ฐ„์˜ ์—ฐ๊ตฌ์™€ ๋‹ค์–‘ํ•œ ๊ฒฝ๋กœ๋ฅผ ๋ชจ์ƒ‰ํ•œ ๋์— ์ถœ์‹œ๋œ ์ œํ’ˆ์ž…๋‹ˆ๋‹ค. ๊ทธ ๊ฒฝ๋กœ ์ค‘ ์ผ๋ถ€๋Š” ์„ฑ๊ณต์ ์ด์—ˆ์ง€๋งŒ ๋” ๋งŽ์€ ๊ฒฝ๋กœ๊ฐ€ ๋ง‰๋‹ค๋ฅธ ๊ณจ๋ชฉ์—์„œ ์ƒˆ๋กœ์šด ์ธ์‚ฌ์ดํŠธ๋กœ ์ด์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์–ป์€ ํ•œ ๊ฐ€์ง€ ๊ตํ›ˆ์€ ์šฐ๋ฆฌ๊ฐ€ ํƒ์ƒ‰ํ•˜๊ณ  ์žˆ๋Š” ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ์ธ์‚ฌ์ดํŠธ๋ฅผ ๊ณต์œ ๋ฐ›์ง€ ๋ชปํ•œ ์ฑ„ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์€ ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์‹ค๋ง๊ฐ์„ ์ค€๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. +[React 18](/blog/2022/03/29/react-v18)์€ ์ˆ˜๋…„๊ฐ„์˜ ์ค€๋น„ ๋์— ํƒ„์ƒํ•œ ๋ฒ„์ „์œผ๋กœ React ํŒ€์—๊ฒŒ ๊ท€์ค‘ํ•œ ๊ตํ›ˆ์„ ๊ฐ€์ ธ๋‹ค์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ˆ˜๋…„๊ฐ„์˜ ์—ฐ๊ตฌ์™€ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ๋ชจ์ƒ‰ํ•œ ๋์— ์ถœ์‹œ๋œ ์ œํ’ˆ์ž…๋‹ˆ๋‹ค. ๊ทธ ๋ฐฉ๋ฒ• ์ค‘ ์ผ๋ถ€๋Š” ์„ฑ๊ณต์ ์ด์—ˆ์ง€๋งŒ ๋” ๋งŽ์€ ๋ฐฉ๋ฒ•๋“ค์ด ๋ง‰๋‹ค๋ฅธ ๊ณจ๋ชฉ์—์„œ ์ƒˆ๋กœ์šด ํ†ต์ฐฐ๋กœ ์ด์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์–ป์€ ํ•œ ๊ฐ€์ง€ ๊ตํ›ˆ์€ ์šฐ๋ฆฌ๊ฐ€ ํƒ์ƒ‰ํ•˜๊ณ  ์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํ†ต์ฐฐ์„ ๊ณต์œ ๋ฐ›์ง€ ๋ชปํ•œ ์ฑ„ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์€ ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์‹ค๋ง๊ฐ์„ ์ค€๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. </Intro> @@ -29,7 +29,7 @@ description: React 18 ์€ ์ˆ˜๋…„๊ฐ„์˜ ์ค€๋น„ ๋์— ํƒ„์ƒํ•œ ๋ฒ„์ „์œผ๋กœ Reac Vercel ๋ฐ Shopify์™€ ํ˜‘๋ ฅํ•˜์—ฌ Webpack ๋ฐ Vite ๋ชจ๋‘์—์„œ ๊ณต์œ  ์‹œ๋งจํ‹ฑ์— ๋Œ€ํ•œ ๋ฒˆ๋“ค๋Ÿฌ ์ง€์›์„ ํ†ตํ•ฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ถœ์‹œ ์ „์— ์ „์ฒด React ์ƒํƒœ๊ณ„์—์„œ RSC์˜ ์˜๋ฏธ๊ฐ€ ๋™์ผํ•œ์ง€ ํ™•์ธํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์•ˆ์ •์— ๋„๋‹ฌํ•˜๋Š” ๋ฐ ์ฃผ์š” ์žฅ์• ๋ฌผ์ž…๋‹ˆ๋‹ค. -## ์ž์‚ฐ ๋กœ๋”ฉ {/*asset-loading*/} +## ์ž์‚ฐ<sup>Asset</sup> ๋กœ๋”ฉ {/*asset-loading*/} ํ˜„์žฌ, ์Šคํฌ๋ฆฝํŠธ, ์™ธ๋ถ€ ์Šคํƒ€์ผ, ๊ธ€๊ผด ๋ฐ ์ด๋ฏธ์ง€์™€ ๊ฐ™์€ ๋ฆฌ์†Œ์Šค๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์™ธ๋ถ€ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์ „ ๋กœ๋“œ๋˜๊ณ  ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์ŠคํŠธ๋ฆฌ๋ฐ, ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๋“ฑ๊ณผ ๊ฐ™์€ ์ƒˆ๋กœ์šด ํ™˜๊ฒฝ์—์„œ ์กฐ์ •ํ•˜๊ธฐ ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  React ํ™˜๊ฒฝ์—์„œ ์ž‘๋™ํ•˜๋Š” React API๋ฅผ ํ†ตํ•ด ์ค‘๋ณต ์ œ๊ฑฐ๋œ ์™ธ๋ถ€ ์ž์‚ฐ์„ ๋ฏธ๋ฆฌ ๋กœ๋“œํ•˜๊ณ  ๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•ด API๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. @@ -38,32 +38,32 @@ Vercel ๋ฐ Shopify์™€ ํ˜‘๋ ฅํ•˜์—ฌ Webpack ๋ฐ Vite ๋ชจ๋‘์—์„œ ๊ณต์œ  ์‹œ๋งจ ## ์ •์  ์„œ๋ฒ„ ๋ Œ๋”๋ง ์ตœ์ ํ™” {/*static-server-rendering-optimizations*/} -์ •์  ์‚ฌ์ดํŠธ ์ƒ์„ฑ(SSG)๊ณผ ์ฆ๋ถ„ ์ •์  ์žฌ์ƒ์„ฑ(ISR)์€ ์บ์‹œ ๊ฐ€๋Šฅํ•œ ํŽ˜์ด์ง€์˜ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒํ•˜๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ, ๋™์  ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง(SSR)์˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๋” ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค - ํŠนํžˆ, ๋Œ€๋ถ€๋ถ„์˜ ์ปจํ…์ธ ๊ฐ€ ์บ์‹ฑ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ผ๋ถ€๋งŒ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด์„œ์š”. ์ปดํŒŒ์ผ ๋ฐ ์ •์  ํŒจ์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ์ƒ‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์ •์  ์‚ฌ์ดํŠธ ์ƒ์„ฑ<sup>SSG</sup>๊ณผ ์ฆ๋ถ„ ์ •์  ์žฌ์ƒ์„ฑ<sup>ISR</sup>์€ ์บ์‹œ ๊ฐ€๋Šฅํ•œ ํŽ˜์ด์ง€์˜ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒํ•˜๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ, ๋™์  ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง<sup>SSR</sup>์˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๋” ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ, ๋Œ€๋ถ€๋ถ„์˜ ์ปจํ…์ธ ๊ฐ€ ์บ์‹ฑ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ผ๋ถ€๋งŒ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด์„œ์š”. ์ปดํŒŒ์ผ ๋ฐ ์ •์  ๊ฒฝ๋กœ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ์ƒ‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ## React ์ตœ์ ํ™” ์ปดํŒŒ์ผ๋Ÿฌ {/*react-compiler*/} -์šฐ๋ฆฌ๋Š” React Conf 2021์—์„œ React Forget์„ [๋ฏธ๋ฆฌ ์„ ๋ณด์˜€์Šต๋‹ˆ๋‹ค](https://www.youtube.com/watch?v=lGEMwh32soc). ์ด ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ์žฌ๋ Œ๋”๋ง ๋น„์šฉ์„ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด `useMemo` ์™€ `useCallback` ์— ์ƒ์‘ํ•˜๋Š” ํ˜ธ์ถœ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์ž…๋‹ˆ๋‹ค. +์šฐ๋ฆฌ๋Š” React Conf 2021์—์„œ React Forget์„ [๋ฏธ๋ฆฌ ์„ ๋ณด์˜€์Šต๋‹ˆ๋‹ค](https://www.youtube.com/watch?v=lGEMwh32soc). ์ด ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ์žฌ๋ Œ๋”๋ง ๋น„์šฉ์„ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด `useMemo` ์™€ `useCallback`์— ์ƒ์‘ํ•˜๋Š” ํ˜ธ์ถœ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์ž…๋‹ˆ๋‹ค. -์ตœ๊ทผ ์ €ํฌ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์•ˆ์ •์„ฑ๊ณผ ์„ฑ๋Šฅ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ปดํŒŒ์ผ๋Ÿฌ ์žฌ์ž‘์—…์„ ์™„๋ฃŒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ƒˆ๋กœ์šด ์•„ํ‚คํ…์ฒ˜๋ฅผ ํ†ตํ•ด [๋กœ์ปฌ ๋ณ€์ด ์‚ฌ์šฉ](/learn/keeping-components-pure#local-mutation-your-components-little-secret)๊ณผ ๊ฐ™์€ ๋” ๋ณต์žกํ•œ ํŒจํ„ด์„ ๋ถ„์„ํ•˜๊ณ  ๋ฉ”๋ชจํ™”ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์œผ๋ฉฐ, memoization Hooks ์™€ ๋™๋“ฑํ•œ ์ˆ˜์ค€ ์ด์ƒ์œผ๋กœ ๋งŽ์€ ์ƒˆ๋กœ์šด ์ปดํŒŒ์ผ ์‹œ๊ฐ„ ์ตœ์ ํ™” ๊ธฐํšŒ๊ฐ€ ์—ด๋ฆฌ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +์ตœ๊ทผ ์ €ํฌ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์•ˆ์ •์„ฑ๊ณผ ์„ฑ๋Šฅ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ปดํŒŒ์ผ๋Ÿฌ ์žฌ์ž‘์—…์„ ์™„๋ฃŒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ƒˆ๋กœ์šด ์•„ํ‚คํ…์ฒ˜๋ฅผ ํ†ตํ•ด [๋กœ์ปฌ ๋ณ€ํ˜• ์‚ฌ์šฉ](/learn/keeping-components-pure#local-mutation-your-components-little-secret)๊ณผ ๊ฐ™์€ ๋” ๋ณต์žกํ•œ ํŒจํ„ด์„ ๋ถ„์„ํ•˜๊ณ  ๋ฉ”๋ชจํ™”ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์œผ๋ฉฐ, Memoization Hook๊ณผ ๋™๋“ฑํ•œ ์ˆ˜์ค€ ์ด์ƒ์œผ๋กœ ๋งŽ์€ ์ƒˆ๋กœ์šด ์ปดํŒŒ์ผ ์‹œ๊ฐ„ ์ตœ์ ํ™” ๊ธฐํšŒ๊ฐ€ ์—ด๋ฆฌ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -๋˜ํ•œ ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์—ฌ๋Ÿฌ ์ธก๋ฉด์„ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ๋„ ๊ฐœ๋ฐœ ์ค‘์ž…๋‹ˆ๋‹ค. ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ์˜ ๋ชฉํ‘œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋” ์‰ฝ๊ฒŒ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ณ  ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•˜๋Š” ์ผ์— ๋Œ€ํ•œ ์ง๊ด€๋ ฅ์„ ํ‚ค์šฐ๋Š” ๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋‚ด๋ถ€์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ์ž…๋ ฅํ•˜๋Š” ๋Œ€๋กœ ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์ถœ๋ ฅ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ถœ์‹œ๋  ๋•Œ ํ•จ๊ป˜ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. +๋˜ํ•œ ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์—ฌ๋Ÿฌ ์ธก๋ฉด์„ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ๋„ ๊ฐœ๋ฐœ ์ค‘์ž…๋‹ˆ๋‹ค. ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ์˜ ๋ชฉํ‘œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋” ์‰ฝ๊ฒŒ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ณ  ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•˜๋Š” ์ผ์— ๋Œ€ํ•œ ์ง๊ด€๋ ฅ์„ ํ‚ค์šฐ๋Š” ๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋‚ด๋ถ€์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๋‹ค์–‘ํ•œ ํ†ต์ฐฐ์„ ์ œ๊ณตํ•˜๋ฉฐ, ์ž…๋ ฅํ•˜๋Š” ๋Œ€๋กœ ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์ถœ๋ ฅ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ถœ์‹œ๋  ๋•Œ ํ•จ๊ป˜ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ## ์˜คํ”„์Šคํฌ๋ฆฐ {/*offscreen*/} -์ด์ œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ˆจ๊ธฐ๊ฑฐ๋‚˜ ํ‘œ์‹œํ•˜๋ ค๋ฉด ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” ํŠธ๋ฆฌ์—์„œ ์™„์ „ํžˆ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์˜ ๋ฌธ์ œ์ ์€ ๋งˆ์šดํŠธ๋ฅผ ํ•ด์ œํ•  ๋•Œ๋งˆ๋‹ค ์Šคํฌ๋กค ์œ„์น˜์™€ ๊ฐ™์ด DOM์— ์ €์žฅ๋œ state๋ฅผ ํฌํ•จํ•˜์—ฌ UI์˜ state๊ฐ€ ์†์‹ค๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ด์ œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ˆจ๊ธฐ๊ฑฐ๋‚˜ ํ‘œ์‹œํ•˜๋ ค๋ฉด ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” ํŠธ๋ฆฌ์—์„œ ์™„์ „ํžˆ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์˜ ๋ฌธ์ œ์ ์€ ๋งˆ์šดํŠธ๋ฅผ ํ•ด์ œํ•  ๋•Œ๋งˆ๋‹ค ์Šคํฌ๋กค ์œ„์น˜์™€ ๊ฐ™์ด DOM์— ์ €์žฅ๋œ State๋ฅผ ํฌํ•จํ•˜์—ฌ UI์˜ State๊ฐ€ ์†์‹ค๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. -๋‹ค๋ฅธ ์˜ต์…˜์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•œ ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๊ณ  CSS๋ฅผ ์‚ฌ์šฉํ•ด ์‹œ๊ฐ์ ์œผ๋กœ ๋ชจ์–‘์„ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ UI์˜ state๋ฅผ ์œ ์ง€ํ•˜์ง€๋งŒ, React๊ฐ€ ์ƒˆ๋กœ์šด ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค ์ˆจ๊ฒจ์ง„ ์ปดํฌ๋„ŒํŠธ์™€ ๊ทธ ๋ชจ๋“  ์ž์‹๋“ค์„ ๊ณ„์† ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์„ฑ๋Šฅ์— ๋น„์šฉ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. +๋‹ค๋ฅธ ์˜ต์…˜์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•œ ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๊ณ  CSS๋ฅผ ์‚ฌ์šฉํ•ด ์‹œ๊ฐ์ ์œผ๋กœ ๋ชจ์–‘์„ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ UI์˜ State๋ฅผ ์œ ์ง€ํ•˜์ง€๋งŒ, React๊ฐ€ ์ƒˆ๋กœ์šด ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค ์ˆจ๊ฒจ์ง„ ์ปดํฌ๋„ŒํŠธ์™€ ๊ทธ ๋ชจ๋“  ์ž์‹๋“ค์„ ๊ณ„์† ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์„ฑ๋Šฅ์— ๋น„์šฉ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์˜คํ”„์Šคํฌ๋ฆฐ์€ UI๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ์ˆจ๊ธฐ๋˜ ์ฝ˜ํ…์ธ ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋‚ฎ์ถ”๋Š” ์„ธ ๋ฒˆ์งธ ์˜ต์…˜์„ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ์ด ์•„์ด๋””์–ด๋Š” `content-visibility` CSS ํ”„๋กœํผํ‹ฐ์™€ ๋น„์Šทํ•œ ๊ฐœ๋…์œผ๋กœ, ์ฝ˜ํ…์ธ ๊ฐ€ ์ˆจ๊ฒจ์ ธ ์žˆ์„ ๋•Œ ๋‚˜๋จธ์ง€ UI์™€ ๋™๊ธฐํ™” ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. React๋Š” ์•ฑ์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์ด ์œ ํœด ์ƒํƒœ๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๋˜๋Š” ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ค์‹œ ํ‘œ์‹œ๋  ๋•Œ๊นŒ์ง€ ๋ Œ๋”๋ง ์ž‘์—…์„ ์—ฐ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์˜คํ”„์Šคํฌ๋ฆฐ์€ ๋†’์€ ์ˆ˜์ค€์˜ ๊ธฐ๋Šฅ์„ ์ž ๊ธˆ ํ•ด์ œํ•˜๋Š” ๋‚ฎ์€ ์ˆ˜์ค€์˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. `startTransition` ๊ณผ ๊ฐ™์€ React์˜ ๋‹ค๋ฅธ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์˜คํ”„์Šคํฌ๋ฆฐ API์™€ ์ง์ ‘ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๊ณ  ๋…๋‹จ์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŒจํ„ด์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. +์˜คํ”„์Šคํฌ๋ฆฐ์€ ๊ณ ์ˆ˜์ค€<sup>High Level</sup>์˜ ๊ธฐ๋Šฅ์„ ์ž ๊ธˆ ํ•ด์ œํ•˜๋Š” ์ €์ˆ˜์ค€<sup>Low Level</sup>์˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. `startTransition` ๊ณผ ๊ฐ™์€ React์˜ ๋‹ค๋ฅธ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์˜คํ”„์Šคํฌ๋ฆฐ API์™€ ์ง์ ‘ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๊ณ  ๋…๋‹จ์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŒจํ„ด์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. * **์ฆ‰๊ฐ์ ์ธ ์ „ํ™˜.** ์ผ๋ถ€ ๋ผ์šฐํŒ… ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๋งํฌ ์œ„๋กœ ๋งˆ์šฐ์Šค๋ฅผ ๊ฐ€์ ธ๊ฐˆ ๋•Œ์™€ ๊ฐ™์ด ํ›„์† ํƒ์ƒ‰ ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ด๋ฏธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์˜คํ”„์Šคํฌ๋ฆฐ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋‹ค์Œ ํ™”๋ฉด์„ ๋ฏธ๋ฆฌ ๋ Œ๋”๋งํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -* **์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ state.** ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฒฝ๋กœ๋‚˜ ํƒญ ์‚ฌ์ด๋ฅผ ํƒ์ƒ‰ํ•  ๋•Œ ์˜คํ”„์Šคํฌ๋ฆฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด์ „ ํ™”๋ฉด์˜ state๋ฅผ ๋ณด์กดํ•˜์—ฌ ์ค‘๋‹จํ•œ ์ง€์ ์—์„œ ๋‹ค์‹œ ์ „ํ™˜ํ•˜๊ณ  ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* **์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ State.** ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฒฝ๋กœ๋‚˜ ํƒญ ์‚ฌ์ด๋ฅผ ํƒ์ƒ‰ํ•  ๋•Œ ์˜คํ”„์Šคํฌ๋ฆฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด์ „ ํ™”๋ฉด์˜ State๋ฅผ ๋ณด์กดํ•˜์—ฌ ์ค‘๋‹จํ•œ ์ง€์ ์—์„œ ๋‹ค์‹œ ์ „ํ™˜ํ•˜๊ณ  ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **๊ฐ€์ƒํ™”๋œ ๋ชฉ๋ก ๋ Œ๋”๋ง.** ๋งŽ์€ ํ•ญ๋ชฉ ๋ชฉ๋ก์„ ํ‘œ์‹œํ•  ๋•Œ ๊ฐ€์ƒํ™”๋œ ๋ชฉ๋ก ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ํ˜„์žฌ ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ํ–‰์„ ๋ฏธ๋ฆฌ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์˜คํ”„์Šคํฌ๋ฆฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ˆจ๊ฒจ์ง„ ํ–‰์„ ๋ชฉ๋ก์— ๋ณด์ด๋Š” ํ•ญ๋ชฉ๋ณด๋‹ค ๋‚ฎ์€ ์šฐ์„  ์ˆœ์œ„๋กœ ๋ฏธ๋ฆฌ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **๋ฐฐ๊ฒฝ ์ฝ˜ํ…์ธ .** ๋˜ํ•œ ๋ชจ๋‹ฌ ์˜ค๋ฒ„๋ ˆ์ด๋ฅผ ํ‘œ์‹œํ•  ๋•Œ์™€ ๊ฐ™์ด ์ฝ˜ํ…์ธ ๋ฅผ ์ˆจ๊ธฐ์ง€ ์•Š๊ณ  ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์šฐ์„  ์ˆœ์œ„๋ฅผ ๋‚ฎ์ถ”๋Š” ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ํƒ์ƒ‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -## ์ „ํ™˜ ์ถ”์  {/*transition-tracing*/} +## Transition ์ถ”์  {/*transition-tracing*/} ํ˜„์žฌ React์—๋Š” ๋‘ ๊ฐ€์ง€ ํ”„๋กœํŒŒ์ผ๋ง ๋„๊ตฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. [๊ธฐ์กด์˜ ํ”„๋กœํŒŒ์ผ๋Ÿฌ](https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html)๋Š” ํ”„๋กœํŒŒ์ผ๋ง ์„ธ์…˜์˜ ๋ชจ๋“  ์ปค๋ฐ‹์— ๋Œ€ํ•œ ๊ฐœ์š”๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๊ฐ ์ปค๋ฐ‹์— ๋Œ€ํ•ด ๋ Œ๋”๋ง๋œ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์™€ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฐ ์‹œ๊ฐ„๋„ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ React 18์— ๋„์ž…๋œ [Timeline Profiler](https://github.com/reactwg/react-18/discussions/76)์˜ ๋ฒ ํƒ€ ๋ฒ„์ „์ด ์žˆ๋Š”๋ฐ, ์ด ๊ธฐ๋Šฅ์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—…๋ฐ์ดํŠธ๋ฅผ ์˜ˆ์•ฝํ•˜๋Š” ์‹œ๊ธฐ์™€ React๊ฐ€ ์ด๋Ÿฌํ•œ ์—…๋ฐ์ดํŠธ์—์„œ ์ž‘๋™ํ•˜๋Š” ์‹œ๊ธฐ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด ๋‘ ํ”„๋กœํŒŒ์ผ๋Ÿฌ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ์—์„œ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. @@ -75,8 +75,8 @@ Vercel ๋ฐ Shopify์™€ ํ˜‘๋ ฅํ•˜์—ฌ Webpack ๋ฐ Vite ๋ชจ๋‘์—์„œ ๊ณต์œ  ์‹œ๋งจ ## ์ƒˆ๋กœ์šด React ๋ฌธ์„œ {/*new-react-docs*/} -์ž‘๋…„์— ์šฐ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด React ๋ฌธ์„œ ์›น์‚ฌ์ดํŠธ์˜ ๋ฒ ํƒ€ ๋ฒ„์ „([๋‚˜์ค‘์— react.dev๋กœ ์ถœ์‹œ](/blog/2023/03/16/introducing-react-dev))์„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํ•™์Šต ์ž๋ฃŒ๋Š” Hooks๋ฅผ ๋จผ์ € ๊ฐ€๋ฅด์น˜๊ณ  ์ƒˆ๋กœ์šด ๋‹ค์ด์–ด๊ทธ๋žจ, ์ผ๋Ÿฌ์ŠคํŠธ๋ ˆ์ด์…˜, ๋งŽ์€ ๋Œ€ํ™”ํ˜• ์˜ˆ์‹œ ๋ฐ ๊ณผ์ œ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” React 18 ๋ฆด๋ฆฌ์Šค์— ์ง‘์ค‘ํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ์ž‘์—…์—์„œ ์ž ์‹œ ํœด์‹์„ ์ทจํ–ˆ์ง€๋งŒ ์ด์ œ React 18์ด ์ถœ์‹œ๋˜์—ˆ์œผ๋ฏ€๋กœ ์ƒˆ ๋ฌธ์„œ๋ฅผ ์™„๋ฃŒํ•˜๊ณ  ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ ๊ทน์ ์œผ๋กœ ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์ž‘๋…„์— ์ƒˆ๋กœ์šด React ๋ฌธ์„œ ์›น์‚ฌ์ดํŠธ์˜ ๋ฒ ํƒ€ ๋ฒ„์ „([ํ›—๋‚  react.dev๋กœ ์ถœ์‹œ](/blog/2023/03/16/introducing-react-dev))์„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํ•™์Šต ์ž๋ฃŒ๋Š” Hook์„ ๋จผ์ € ๊ฐ€๋ฅด์น˜๊ณ  ์ƒˆ๋กœ์šด ๋‹ค์ด์–ด๊ทธ๋žจ, ์ผ๋Ÿฌ์ŠคํŠธ๋ ˆ์ด์…˜, ๋งŽ์€ ๋Œ€ํ™”ํ˜• ์˜ˆ์‹œ ๋ฐ ๊ณผ์ œ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” React 18 ๋ฆด๋ฆฌ์Šค์— ์ง‘์ค‘ํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ์ž‘์—…์—์„œ ์ž ์‹œ ํœด์‹์„ ์ทจํ–ˆ์ง€๋งŒ ์ด์ œ React 18์ด ์ถœ์‹œ๋˜์—ˆ์œผ๋ฏ€๋กœ ์ƒˆ ๋ฌธ์„œ๋ฅผ ์™„๋ฃŒํ•˜๊ณ  ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ ๊ทน์ ์œผ๋กœ ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -์‹ ๊ทœ ๋ฐ ์ˆ™๋ จ๋œ React ์‚ฌ์šฉ์ž ๋ชจ๋‘์—๊ฒŒ ๋” ์–ด๋ ค์šด ์ฃผ์ œ ์ค‘ ํ•˜๋‚˜๋ผ๊ณ  ๋“ค์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ effect์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„น์…˜์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. [effect์™€ ๋™๊ธฐํ™”](/learn/synchronizing-with-effects)๋Š” ์‹œ๋ฆฌ์ฆˆ์˜ ์ฒซ ๋ฒˆ์งธ ๊ฒŒ์‹œ๋œ ํŽ˜์ด์ง€์ด๋ฉฐ ๋‹ค์Œ ์ฃผ์— ๋” ๋งŽ์€ ํŽ˜์ด์ง€๊ฐ€ ์ถ”๊ฐ€๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. effect์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„น์…˜์„ ์ฒ˜์Œ ์ž‘์„ฑํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ React์— ์ƒˆ๋กœ์šด ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋งŽ์€ ์ผ๋ฐ˜์ ์ธ effect ํŒจํ„ด์„ ๋‹จ์ˆœํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. [useEvent RFC](https://github.com/reactjs/rfcs/pull/220)์—์„œ ์ด์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ดˆ๊ธฐ ์ƒ๊ฐ์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์ดˆ๊ธฐ ์—ฐ๊ตฌ ๋‹จ๊ณ„์— ์žˆ์œผ๋ฉฐ ์—ฌ์ „ํžˆ ์•„์ด๋””์–ด๋ฅผ ๋ฐ˜๋ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ RFC์— ๋Œ€ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์˜๊ฒฌ๊ณผ ์ง„ํ–‰ ์ค‘์ธ ๋ฌธ์„œ ์žฌ์ž‘์„ฑ์— ๋Œ€ํ•œ [ํ”ผ๋“œ๋ฐฑ](https://github.com/reactjs/react.dev/issues/3308) ๋ฐ ๊ธฐ์—ฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์›น ์‚ฌ์ดํŠธ ๊ตฌํ˜„์— ๋Œ€ํ•œ ๋งŽ์€ ๊ฐœ์„  ์‚ฌํ•ญ์„ ์ œ์ถœํ•˜๊ณ  ๊ฒ€ํ† ํ•œ [Harish Kumar](https://github.com/harish-sethuraman)์—๊ฒŒ ํŠน๋ณ„ํžˆ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. +์ƒˆ๋กœ์šด ํ˜น์€ ์ˆ™๋ จ๋œ React ์‚ฌ์šฉ์ž ๋ชจ๋‘์—๊ฒŒ ์–ด๋ ค์šด ์ฃผ์ œ ์ค‘ ํ•˜๋‚˜๋ผ๊ณ  ๋“ค์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ˜„์žฌ Effect์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„น์…˜์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. [Effect๋กœ ๋™๊ธฐํ™”ํ•˜๊ธฐ](/learn/synchronizing-with-effects)๋Š” ์‹œ๋ฆฌ์ฆˆ์˜ ์ฒซ ๋ฒˆ์งธ ํŽ˜์ด์ง€์ด๋ฉฐ ๋‹ค์Œ ์ฃผ์— ๋” ๋งŽ์€ ํŽ˜์ด์ง€๊ฐ€ ์ถ”๊ฐ€๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. Effect์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„น์…˜์„ ์ฒ˜์Œ ์ž‘์„ฑํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ React์— ์ƒˆ๋กœ์šด ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋งŽ์€ ์ผ๋ฐ˜์ ์ธ Effect ํŒจํ„ด์„ ๋‹จ์ˆœํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. [useEvent RFC](https://github.com/reactjs/rfcs/pull/220)์—์„œ ์ด์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ดˆ๊ธฐ ์ƒ๊ฐ์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์ดˆ๊ธฐ ์—ฐ๊ตฌ ๋‹จ๊ณ„์— ์žˆ์œผ๋ฉฐ ์—ฌ์ „ํžˆ ์•„์ด๋””์–ด๋ฅผ ๋ฐ˜๋ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ RFC์— ๋Œ€ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์˜๊ฒฌ๊ณผ ์ง„ํ–‰ ์ค‘์ธ ๋ฌธ์„œ ์žฌ์ž‘์„ฑ์— ๋Œ€ํ•œ [ํ”ผ๋“œ๋ฐฑ](https://github.com/reactjs/react.dev/issues/3308) ๋ฐ ๊ธฐ์—ฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์›น ์‚ฌ์ดํŠธ ๊ตฌํ˜„์— ๋Œ€ํ•œ ๋งŽ์€ ๊ฐœ์„  ์‚ฌํ•ญ์„ ์ œ์ถœํ•˜๊ณ  ๊ฒ€ํ† ํ•œ [Harish Kumar](https://github.com/harish-sethuraman)์—๊ฒŒ ํŠน๋ณ„ํžˆ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. *์ด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์„ ๊ฒ€ํ† ํ•ด ์ฃผ์‹  [Sophie Alpert](https://twitter.com/sophiebits)์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!* From ca02700c6c243b0863e7ba3539b137727437e191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 15:11:47 +0900 Subject: [PATCH 0357/1059] docs: update `introducing-react-dev` --- .../blog/2023/03/16/introducing-react-dev.md | 58 +++++++++---------- .../server/renderToReadableStream.md | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/content/blog/2023/03/16/introducing-react-dev.md b/src/content/blog/2023/03/16/introducing-react-dev.md index 8b13cb55e..4aecb0440 100644 --- a/src/content/blog/2023/03/16/introducing-react-dev.md +++ b/src/content/blog/2023/03/16/introducing-react-dev.md @@ -20,29 +20,29 @@ description: ์˜ค๋Š˜ React์™€ React ๋ฌธ์„œ์˜ ์ƒˆ๋กœ์šด ๋ณด๊ธˆ์ž๋ฆฌ์ธ react.dev ## ์š”์•ฝ {/*tldr*/} -* ์ƒˆ๋กœ์šด React ์‚ฌ์ดํŠธ ([react.dev](https://react.dev)) ๋Š” ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์™€ Hooks๋ฅผ ์‚ฌ์šฉํ•œ ํ˜„๋Œ€์ ์ธ React๋ฅผ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. -* ๋‹ค์ด์–ด๊ทธ๋žจ, ์‚ฝํ™”, ๋„์ „ ๊ณผ์ œ, ๊ทธ๋ฆฌ๊ณ  600๊ฐœ ์ด์ƒ์˜ ์ƒˆ๋กœ์šด ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ํฌํ•จํ–ˆ์Šต๋‹ˆ๋‹ค. +* ์ƒˆ๋กœ์šด React ์‚ฌ์ดํŠธ ([react.dev](https://react.dev))๋Š” ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์™€ Hook์„ ์‚ฌ์šฉํ•œ ํ˜„๋Œ€์ ์ธ React๋ฅผ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. +* ๋‹ค์ด์–ด๊ทธ๋žจ, ์‚ฝํ™”, ๋„์ „ ๊ณผ์ œ, ๊ทธ๋ฆฌ๊ณ  600๊ฐœ ์ด์ƒ์˜ ์ƒˆ๋กœ์šด ์ƒํ˜ธ ์ž‘์šฉ ์˜ˆ์‹œ๋ฅผ ํฌํ•จํ–ˆ์Šต๋‹ˆ๋‹ค. * ์˜ˆ์ „ React ๋ฌธ์„œ ์‚ฌ์ดํŠธ๋Š” ์ด์ œ [legacy.reactjs.org](https://legacy.reactjs.org)๋กœ ์ด์ „๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ## ์ƒˆ๋กœ์šด ์‚ฌ์ดํŠธ, ์ƒˆ๋กœ์šด ๋„๋ฉ”์ธ, ์ƒˆ๋กœ์šด ํ™ˆํŽ˜์ด์ง€ {/*new-site-new-domain-new-homepage*/} ์šฐ์„ , ์กฐ๊ธˆ์˜ ์ •๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. -์ƒˆ๋กœ์šด ๋ฌธ์„œ์˜ ์ถœ์‹œ๋ฅผ ์ถ•ํ•˜ํ•˜๊ณ , ๋”์šฑ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์˜ค๋ž˜๋œ ๋‚ด์šฉ๊ณผ ์ƒˆ๋กœ์šด ๋‚ด์šฉ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด, ๋” ์งง์€ [react.dev](https://react.dev) ๋„๋ฉ”์ธ์œผ๋กœ ์ด์ „ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ „ [reactjs.org](https://reactjs.org) ๋„๋ฉ”์ธ์€ ์ด์ œ ์ด๊ณณ์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ƒˆ๋กœ์šด ๋ฌธ์„œ์˜ ์ถœ์‹œ๋ฅผ ์ถ•ํ•˜ํ•˜๊ณ , ๋”์šฑ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์˜ค๋ž˜๋œ ๋‚ด์šฉ๊ณผ ์ƒˆ๋กœ์šด ๋‚ด์šฉ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด, ๋” ์งง์€ [react.dev](https://react.dev) ๋„๋ฉ”์ธ์œผ๋กœ ์ด์ „ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ „ [reactjs.org](https://reactjs.org) ๋„๋ฉ”์ธ์„ ์ด์ œ ์ด๊ณณ์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. -์˜ˆ์ „ React ๋ฌธ์„œ๋Š” ์ด์ œ [legacy.reactjs.org](https://legacy.reactjs.org)์— ๋ณด๊ด€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ „ ๋‚ด์šฉ์œผ๋กœ ๊ฐ€๋Š” ๋ชจ๋“  ๊ธฐ์กด ๋งํฌ๋Š” "์›น์„ ๋ง๊ฐ€ํŠธ๋ฆฌ๋Š” ๊ฒƒ"์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ž๋™์œผ๋กœ ํ•ด๋‹น ์œ„์น˜๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•  ๊ฒƒ์ด์ง€๋งŒ, ๋ ˆ๊ฑฐ์‹œ ์‚ฌ์ดํŠธ๋Š” ๋” ์ด์ƒ ์—…๋ฐ์ดํŠธ ๋ฐ›์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์˜ˆ์ „ React ๋ฌธ์„œ๋Š” ์ด์ œ [legacy.reactjs.org](https://legacy.reactjs.org)์— ๋ณด๊ด€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ „ ๋‚ด์šฉ์œผ๋กœ ํ†ตํ•˜๋Š” ๋ชจ๋“  ๊ธฐ์กด ๋งํฌ๋Š” "์›น์„ ๋ง๊ฐ€ํŠธ๋ฆฌ๋Š” ๊ฒƒ"์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ž๋™์œผ๋กœ ํ•ด๋‹น ์œ„์น˜๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•  ๊ฒƒ์ด์ง€๋งŒ, ๋ ˆ๊ฑฐ์‹œ ์‚ฌ์ดํŠธ์—๋Š” ๋” ์ด์ƒ ์—…๋ฐ์ดํŠธ ๋ฐ›์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -๋ฏฟ๊ธฐ ํž˜๋“ค๊ฒ ์ง€๋งŒ, React๋Š” ๊ณง 10์‚ด์ด ๋ฉ๋‹ˆ๋‹ค. JavaScript ์‹œ๋Œ€์—, ์ด๊ฑด ๋งˆ์น˜ ํ•œ ์„ธ๊ธฐ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค! ์˜ค๋Š˜๋‚  React๊ฐ€ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ›Œ๋ฅญํ•œ ๋ฐฉ๋ฒ•์ธ ์ด์œ ๋ฅผ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด [React ํ™ˆํŽ˜์ด์ง€๋ฅผ ๊ฐฑ์‹ ํ•˜๊ณ ](https://react.dev), ํ˜„๋Œ€์ ์ธ React ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋”์šฑ ๋ช…ํ™•ํ•˜๊ฒŒ ์–ธ๊ธ‰ํ•˜๊ธฐ ์œ„ํ•ด ์‹œ์ž‘ ๊ฐ€์ด๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. +๋ฏฟ๊ธฐ ํž˜๋“ค๊ฒ ์ง€๋งŒ, React๋Š” ๊ณง 10์‚ด์ด ๋ฉ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์‹œ๋Œ€์—, ์ด๊ฑด ๋งˆ์น˜ ํ•œ ์„ธ๊ธฐ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค! ์˜ค๋Š˜๋‚  React๊ฐ€ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ›Œ๋ฅญํ•œ ๋ฐฉ๋ฒ•์ธ ์ด์œ ๋ฅผ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด [React ํ™ˆํŽ˜์ด์ง€๋ฅผ ๊ฐฑ์‹ ํ•˜๊ณ ](https://react.dev), ํ˜„๋Œ€์ ์ธ React ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋”์šฑ ๋ช…ํ™•ํ•˜๊ฒŒ ์–ธ๊ธ‰ํ•˜๊ธฐ ์œ„ํ•ด ์‹œ์ž‘ ๊ฐ€์ด๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„์ง ์ƒˆ๋กœ์šด ํ™ˆํŽ˜์ด์ง€๋ฅผ ๋ณด์ง€ ์•Š์•˜๋‹ค๋ฉด, ๊ผญ ํ™•์ธํ•ด ๋ณด์„ธ์š”! -## Hooks๋ฅผ ์‚ฌ์šฉํ•œ ํ˜„๋Œ€์ ์ธ React์— ์ „๋…ํ•˜๊ธฐ {/*going-all-in-on-modern-react-with-hooks*/} +## Hook์„ ์‚ฌ์šฉํ•œ ํ˜„๋Œ€์ ์ธ React์— ์ „๋…ํ•˜๊ธฐ {/*going-all-in-on-modern-react-with-hooks*/} -2018๋…„์— React Hooks๋ฅผ ๋ฐœํ‘œํ–ˆ์„ ๋•Œ, Hooks ๋ฌธ์„œ๋Š” ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์— ์ต์ˆ™ํ•œ ๋…์ž๋ฅผ ๊ฐ€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ Hooks๋ฅผ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ์ฑ„ํƒํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์—ˆ์ง€๋งŒ, ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด์„œ ์˜ˆ์ „ ๋ฌธ์„œ๋Š” ์ƒˆ๋กœ์šด ๋…์ž์—๊ฒŒ ์ ํ•ฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋…์ž๋Š” ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์™€ Hooks๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ์œผ๋กœ React๋ฅผ ๋‘ ๋ฒˆ ๋ฐฐ์›Œ์•ผ๋งŒ ํ–ˆ์Šต๋‹ˆ๋‹ค. +2018๋…„์— React Hook์„ ๋ฐœํ‘œํ–ˆ์„ ๋•Œ, Hook ๋ฌธ์„œ๋Š” ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์— ์ต์ˆ™ํ•œ ๋…์ž๋ฅผ ๊ฐ€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ Hook์„ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ์ฑ„ํƒํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์—ˆ์ง€๋งŒ, ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด์„œ ์˜ˆ์ „ ๋ฌธ์„œ๋Š” ์ƒˆ๋กœ์šด ๋…์ž์—๊ฒŒ ์ ํ•ฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋…์ž๋Š” ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์™€ Hook์„ ์‚ฌ์šฉํ•œ ๊ฒƒ์œผ๋กœ React๋ฅผ ๋‘ ๋ฒˆ ๋ฐฐ์›Œ์•ผ๋งŒ ํ–ˆ์Šต๋‹ˆ๋‹ค. -**์ƒˆ๋กœ์šด ๋ฌธ์„œ๋Š” Hooks๋ฅผ ์‚ฌ์šฉํ•œ React๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค.** ๋ฌธ์„œ๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ์„น์…˜์œผ๋กœ ๋‚˜๋‰˜์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. +**์ƒˆ๋กœ์šด ๋ฌธ์„œ๋Š” Hook์„ ์‚ฌ์šฉํ•œ React๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค.** ๋ฌธ์„œ๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ์„น์…˜์œผ๋กœ ๋‚˜๋‰˜์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. -* **[React ๋ฐฐ์šฐ๊ธฐ](/learn)** ๋Š” React๋ฅผ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ์Šค์Šค๋กœ ํ•™์Šตํ•  ์ˆ˜ ์žˆ๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. +* **[React ํ•™์Šตํ•˜๊ธฐ](/learn)** ๋Š” React๋ฅผ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ์Šค์Šค๋กœ ํ•™์Šตํ•  ์ˆ˜ ์žˆ๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. * **[API ์ฐธ๊ณ ์„œ](/reference)** ๋Š” ๋ชจ๋“  React API์— ๋Œ€ํ•œ ์„ธ๋ถ€ ๋‚ด์šฉ๊ณผ ์‚ฌ์šฉ ์˜ˆ์‹œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์„น์…˜์—์„œ ๋ฌด์Šจ ๋‚ด์šฉ์„ ์•Œ ์ˆ˜ ์žˆ๋Š”์ง€ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. @@ -55,9 +55,9 @@ description: ์˜ค๋Š˜ React์™€ React ๋ฌธ์„œ์˜ ์ƒˆ๋กœ์šด ๋ณด๊ธˆ์ž๋ฆฌ์ธ react.dev ## ๋น ๋ฅด๊ฒŒ ์‹œ์ž‘ํ•˜๊ธฐ {/*quick-start*/} -ํ•™์Šต ์„น์…˜์€ [๋น ๋ฅด๊ฒŒ ์‹œ์ž‘ํ•˜๊ธฐ](/learn) ํŽ˜์ด์ง€๋กœ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” React๋ฅผ ์งง๊ฒŒ ์†Œ๊ฐœํ•˜๋Š” ์—ฌ์ •์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ, props, state ๊ฐ™์€ ๊ฐœ๋…์— ๋Œ€ํ•œ ๋ฌธ๋ฒ•์„ ์†Œ๊ฐœํ•˜์ง€๋งŒ, ๊ทธ๋“ค์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์„ธ๋ถ€ ๋‚ด์šฉ์„ ๋‹ค๋ฃจ์ง„ ์•Š์Šต๋‹ˆ๋‹ค. +ํ•™์Šต ์„น์…˜์€ [๋น ๋ฅด๊ฒŒ ์‹œ์ž‘ํ•˜๊ธฐ](/learn) ํŽ˜์ด์ง€๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” React๋ฅผ ์งง๊ฒŒ ์†Œ๊ฐœํ•˜๋Š” ์—ฌ์ •์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ, Props, State ๊ฐ™์€ ๊ฐœ๋…์— ๋Œ€ํ•œ ๋ฌธ๋ฒ•์„ ์†Œ๊ฐœํ•˜์ง€๋งŒ, ๊ทธ๋“ค์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์„ธ๋ถ€ ๋‚ด์šฉ์„ ๋‹ค๋ฃจ์ง„ ์•Š์Šต๋‹ˆ๋‹ค. -์ง์ ‘ ํ•ด๋ณด๋ฉฐ ๋ฐฐ์šฐ๊ณ  ์‹ถ๋‹ค๋ฉด, ๋‹ค์Œ์œผ๋กœ [Tic-Tac-Toe ์ž์Šต์„œ](/learn/tutorial-tic-tac-toe)๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. React๋กœ ์ž‘์€ ๊ฒŒ์ž„์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋ฉด์„œ, ๋™์‹œ์— ์ผ์ƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ๊ธฐ์ˆ ์„ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๊ตฌํ˜„ํ•˜๊ฒŒ ๋  ๋‚ด์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. +์ง์ ‘ ํ•ด๋ณด๋ฉฐ ๋ฐฐ์šฐ๊ณ  ์‹ถ๋‹ค๋ฉด, ๋‹ค์Œ์œผ๋กœ [์ž์Šต์„œ: ํ‹ฑํƒํ†  ๊ฒŒ์ž„](/learn/tutorial-tic-tac-toe)์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. React๋กœ ์ž‘์€ ๊ฒŒ์ž„์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋ฉด์„œ, ๋™์‹œ์— ์ผ์ƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ๊ธฐ์ˆ ์„ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๊ตฌํ˜„ํ•˜๊ฒŒ ๋  ๋‚ด์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. <Sandpack> @@ -226,11 +226,11 @@ body { </Sandpack> -๋˜ํ•œ ๋งŽ์€ ์‚ฌ๋žŒ์—๊ฒŒ React๋ฅผ "์™„์ „ํžˆ ์ดํ•ด์‹œ์ผœ ์ค€" ์ž์Šต์„œ์ธ [React๋กœ ์‚ฌ๊ณ ํ•˜๊ธฐ](/learn/thinking-in-react)๋„ ๊ฐ•์กฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. **๋‘ ๊ฐ€์ง€ ํด๋ž˜์‹ ์ž์Šต์„œ ๋ชจ๋‘ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์™€ Hooks๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์—…๋ฐ์ดํŠธํ–ˆ๊ณ ,** ๋”ฐ๋ผ์„œ ์ƒˆ ์ž์Šต์„œ๋งŒํผ ์ข‹์Šต๋‹ˆ๋‹ค. +๋˜ํ•œ ๋งŽ์€ ์‚ฌ๋žŒ์—๊ฒŒ React๋ฅผ "์™„์ „ํžˆ ์ดํ•ด์‹œ์ผœ ์ค€" ์ž์Šต์„œ์ธ [React๋กœ ์‚ฌ๊ณ ํ•˜๊ธฐ](/learn/thinking-in-react)๋„ ๊ฐ•์กฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. **๋‘ ๊ฐ€์ง€ ํด๋ž˜์‹ ์ž์Šต์„œ ๋ชจ๋‘ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์™€ Hook์„ ์‚ฌ์šฉํ•˜๋„๋ก ์—…๋ฐ์ดํŠธํ–ˆ๊ธฐ์—**, ์ƒˆ ์ž์Šต์„œ๋งŒํผ ํ›Œ๋ฅญํ•ฉ๋‹ˆ๋‹ค. <Note> -์œ„์ชฝ์— ์žˆ๋Š” ์˜ˆ์‹œ๋Š” *์ƒŒ๋“œ๋ฐ•์Šค*์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” 600๊ฐœ ์ด์ƒ์˜ ๋งŽ์€ ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ์‚ฌ์ดํŠธ ์ „์ฒด ๋ชจ๋“  ๊ณณ์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ฌด ์ƒŒ๋“œ๋ฐ•์Šค๋‚˜ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ๊ณ , ์šฐ์ธก ์ƒ๋‹จ์— ์žˆ๋Š” "Fork"๋ฅผ ๋ˆŒ๋Ÿฌ ๋ณ„๋„์˜ ํƒญ์—์„œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒŒ๋“œ๋ฐ•์Šค๋Š” React API๋ฅผ ๋น ๋ฅด๊ฒŒ ๊ฐ–๊ณ  ๋†€๋ฉด์„œ, ์•„์ด๋””์–ด๋ฅผ ํƒ๊ตฌํ•˜๊ณ , ์ดํ•ด๋ฅผ ํ™•์ธํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. +์œ„์ชฝ์— ์žˆ๋Š” ์˜ˆ์‹œ๋Š” *์ƒŒ๋“œ๋ฐ•์Šค*์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” 600๊ฐœ ์ด์ƒ์˜ ๋งŽ์€ ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ์‚ฌ์ดํŠธ ์ „์ฒด์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ๊ณ , ์šฐ์ธก ์ƒ๋‹จ์— ์žˆ๋Š” "Fork"๋ฅผ ๋ˆŒ๋Ÿฌ ๋ณ„๋„์˜ ํƒญ์—์„œ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒŒ๋“œ๋ฐ•์Šค๋Š” React API๋ฅผ ๋น ๋ฅด๊ฒŒ ๊ฐ–๊ณ  ๋†€๋ฉด์„œ, ์•„์ด๋””์–ด๋ฅผ ํƒ๊ตฌํ•˜๊ณ , ์ดํ•ด๋ฅผ ํ™•์ธํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. </Note> @@ -240,15 +240,15 @@ body { ์ด๊ฒƒ์ด ํ•™์Šต ์„น์…˜์ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์žฅ์œผ๋กœ ๊ตฌ๋ถ„๋œ ์ž๊ธฐ ์ฃผ๋„ ํ•™์Šต ๊ณผ์ •์œผ๋กœ ๊ตฌ์„ฑ๋œ ์ด์œ ์ž…๋‹ˆ๋‹ค. ์ฒ˜์Œ ๋‘ ์žฅ์€ React์˜ ๊ธฐ์ดˆ์— ๊ด€ํ•ด์„œ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. React๊ฐ€ ์ฒ˜์Œ์ด๊ฑฐ๋‚˜ ๊ธฐ์–ต์„ ๋˜์‚ด๋ฆฌ๊ณ  ์‹ถ๋‹ค๋ฉด, ์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์„ธ์š”. -- **[UI ํ‘œํ˜„ํ•˜๊ธฐ](/learn/describing-the-ui)**์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ๋กœ ์–ด๋–ป๊ฒŒ ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•˜๋Š”์ง€ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. -- **[์ƒํ˜ธ์ž‘์šฉ ์ถ”๊ฐ€ํ•˜๊ธฐ](/learn/adding-interactivity)**์—์„œ๋Š” ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ํ™”๋ฉด์„ ์–ด๋–ป๊ฒŒ ์—…๋ฐ์ดํŠธํ•˜๋Š”์ง€ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. +- <strong>[UI ํ‘œํ˜„ํ•˜๊ธฐ](/learn/describing-the-ui)</strong>์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ๋กœ ์–ด๋–ป๊ฒŒ ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•˜๋Š”์ง€ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. +- <strong>[์ƒํ˜ธ์ž‘์šฉ ์ถ”๊ฐ€ํ•˜๊ธฐ](/learn/adding-interactivity)</strong>์—์„œ๋Š” ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ํ™”๋ฉด์„ ์–ด๋–ป๊ฒŒ ์—…๋ฐ์ดํŠธํ•˜๋Š”์ง€ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‘ ์žฅ์€ ๋”์šฑ ๊ณ ๊ธ‰ ๋‚ด์šฉ์„ ๋‹ค๋ฃจ๋ฉฐ, ๋” ๋ณต์žกํ•œ ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ ๊นŠ์€ ํ†ต์ฐฐ์„ ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -- **[State ๊ด€๋ฆฌํ•˜๊ธฐ](/learn/managing-state)**์—์„œ๋Š” ์•ฑ์˜ ๋ณต์žก์„ฑ์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ์–ด๋–ป๊ฒŒ ๋กœ์ง์„ ์กฐ์งํ™”ํ•˜๋Š”์ง€ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. -- **[ํƒˆ์ถœ๊ตฌ](/learn/escape-hatches)**์—์„œ๋Š” React "์™ธ๋ถ€๋กœ ํƒˆ์ถœ"ํ•  ๋ฐฉ๋ฒ•๊ณผ, ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ์— ๊ฐ€์žฅ ์ ์ ˆํ•œ ์‹œ๊ธฐ๋ฅผ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. +- <strong>[State ๊ด€๋ฆฌํ•˜๊ธฐ](/learn/managing-state)</strong>์—์„œ๋Š” ์•ฑ์˜ ๋ณต์žก์„ฑ์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ์–ด๋–ป๊ฒŒ ๋กœ์ง์„ ์กฐ์งํ™”ํ•˜๋Š”์ง€ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. +- <strong>[ํƒˆ์ถœ๊ตฌ](/learn/escape-hatches)</strong>์—์„œ๋Š” React "์™ธ๋ถ€๋กœ ํƒˆ์ถœ"ํ•  ๋ฐฉ๋ฒ•๊ณผ, ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ์— ๊ฐ€์žฅ ์ ์ ˆํ•œ ์‹œ๊ธฐ๋ฅผ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. -๋ชจ๋“  ์žฅ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ด€๋ จ๋œ ํŽ˜์ด์ง€๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ํŽ˜์ด์ง€๋Š” ํŠน์ • ๊ธฐ์ˆ ์ด๋‚˜ ๊ธฐ๋ฒ•์„ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค-์˜ˆ๋ฅผ ๋“ค์–ด, [JSX๋กœ ๋งˆํฌ์—… ์ž‘์„ฑํ•˜๊ธฐ](/learn/writing-markup-with-jsx), [State์— ์žˆ๋Š” ๊ฐ์ฒด ์—…๋ฐ์ดํŠธํ•˜๊ธฐ](/learn/updating-objects-in-state)๋‚˜ [์ปดํฌ๋„ŒํŠธ ๊ฐ„ State ๊ณต์œ ํ•˜๊ธฐ](/learn/sharing-state-between-components) ๊ฐ™์€ ๊ฒƒ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. [๋ Œ๋”์™€ ์ปค๋ฐ‹](/learn/render-and-commit), [์Šค๋ƒ…์ƒท์œผ๋กœ์„œ์˜ State](/learn/state-as-a-snapshot)์™€ ๊ฐ™์€ ๋ช‡๋ช‡ ํŽ˜์ด์ง€๋“ค์€ ์•„์ด๋””์–ด๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์— ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ์˜ ๊ฒฝํ—˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ œ์•ˆ์„ ๊ณต์œ ํ•˜๋Š” [Effect๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค](/learn/you-might-not-need-an-effect) ๊ฐ™์€ ํŽ˜์ด์ง€๋„ ๋ช‡ ๊ฐœ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ชจ๋“  ์žฅ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ด€๋ จ๋œ ํŽ˜์ด์ง€๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ํŽ˜์ด์ง€๋Š” ํŠน์ • ๊ธฐ์ˆ ์ด๋‚˜ ๊ธฐ๋ฒ•์„ ๊ฐ€๋ฅด์นฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, [JSX๋กœ ๋งˆํฌ์—… ์ž‘์„ฑํ•˜๊ธฐ](/learn/writing-markup-with-jsx), [State์— ์žˆ๋Š” ๊ฐ์ฒด ์—…๋ฐ์ดํŠธํ•˜๊ธฐ](/learn/updating-objects-in-state)๋‚˜ [์ปดํฌ๋„ŒํŠธ ๊ฐ„ State ๊ณต์œ ํ•˜๊ธฐ](/learn/sharing-state-between-components) ๊ฐ™์€ ๊ฒƒ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. [๋ Œ๋”๋ง ๊ทธ๋ฆฌ๊ณ  ์ปค๋ฐ‹](/learn/render-and-commit), [์Šค๋ƒ…์ƒท์œผ๋กœ์„œ์˜ State](/learn/state-as-a-snapshot)์™€ ๊ฐ™์€ ๋ช‡๋ช‡ ํŽ˜์ด์ง€๋“ค์€ ์•„์ด๋””์–ด๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์— ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ์˜ ๊ฒฝํ—˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ œ์•ˆ์„ ๊ณต์œ ํ•˜๋Š” [Effect๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค](/learn/you-might-not-need-an-effect) ๊ฐ™์€ ํŽ˜์ด์ง€๋„ ๋ช‡ ๊ฐœ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์žฅ๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ ์ฝ์„ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ฐ€ ๊ทธ๋Ÿฐ ์‹œ๊ฐ„์ด ์žˆ์„๊นŒ์š”?! ํ•˜์ง€๋งŒ ์ฝ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•™์Šต ์„น์…˜์— ์žˆ๋Š” ํŽ˜์ด์ง€๋Š” ์˜ค๋กœ์ง€ ์ด์ „ ํŽ˜์ด์ง€์— ์†Œ๊ฐœ๋œ ๊ฐœ๋…์—๋งŒ ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ์ฑ…์ฒ˜๋Ÿผ ์ฝ๊ณ  ์‹ถ๋‹ค๋ฉด, ๋„์ „ํ•ด ๋ณด์„ธ์š”! @@ -342,7 +342,7 @@ export default function PackingList() { #### `&&`๋กœ ํ•ญ๋ชฉ์˜ ์ค‘์š”์„ฑ์„ ๋ณด์—ฌ์ฃผ์„ธ์š” {/*show-the-item-importance-with-*/} -์ด ์˜ˆ์‹œ์—์„œ๋Š”, ๊ฐ `Item`์ด ์ˆซ์ž๋กœ ๋œ `importance` prop์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์˜ค์ง ์ค‘์š”๋„๊ฐ€ 0์ด ์•„๋‹Œ ํ•ญ๋ชฉ๋งŒ "_(์ค‘์š”๋„: X)_"์„ ์ดํƒค๋ฆญ์ฒด๋กœ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด `&&` ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ์•„์ดํ…œ ๋ชฉ๋ก์€ ์ตœ์ข…์ ์œผ๋กœ ์ด๋ ‡๊ฒŒ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค: +์ด ์˜ˆ์‹œ์—์„œ๋Š”, ๊ฐ `Item`์ด ์ˆซ์ž๋กœ ๋œ `importance` prop์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์˜ค์ง ์ค‘์š”๋„๊ฐ€ `0`์ด ์•„๋‹Œ ํ•ญ๋ชฉ๋งŒ "_(์ค‘์š”๋„: X)_"์„ ์ดํƒค๋ฆญ์ฒด๋กœ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด `&&` ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ์•„์ดํ…œ ๋ชฉ๋ก์€ ์ตœ์ข…์ ์œผ๋กœ ์ด๋ ‡๊ฒŒ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค: * ์šฐ์ฃผ๋ณต _(์ค‘์š”๋„: 9)_ * ๊ธˆ์ƒ‰ ์žŽ์‚ฌ๊ท€๊ฐ€ ๋‹ฌ๋ฆฐ ํ—ฌ๋ฉง @@ -442,7 +442,7 @@ export default function PackingList() { ### ๋‹ค์ด์–ด๊ทธ๋žจ๊ณผ ์‚ฝํ™”๋กœ ์ง๊ด€๋ ฅ์„ ๋†’์—ฌ๋ณด์„ธ์š” {/*build-an-intuition-with-diagrams-and-illustrations*/} -์ฝ”๋“œ์™€ ๋‹จ์–ด๋งŒ์œผ๋กœ ์–ด๋–ค ๊ฒƒ์„ ์„ค๋ช…ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ, ์ง๊ด€์ ์œผ๋กœ ๋„์›€์„ ์ฃผ๋Š” ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๊ธฐ [State๋ฅผ ๋ณด์žฅํ•˜๊ณ  ์žฌ์„ค์ •ํ•˜๊ธฐ](/learn/preserving-and-resetting-state)์— ์žˆ๋Š” ๋‹ค์ด์–ด๊ทธ๋žจ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +์ฝ”๋“œ์™€ ๋‹จ์–ด๋งŒ์œผ๋กœ ์–ด๋–ค ๊ฒƒ์„ ์„ค๋ช…ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ, ์ง๊ด€์ ์œผ๋กœ ๋„์›€์„ ์ฃผ๋Š” ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๊ธฐ [State๋ฅผ ๋ณด์กดํ•˜๊ณ  ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ](/learn/preserving-and-resetting-state)์— ์žˆ๋Š” ๋‹ค์ด์–ด๊ทธ๋žจ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. <Diagram name="preserving_state_diff_same_pt1" height={350} width={794} alt="๋‹ค์ด์–ด๊ทธ๋žจ์—๋Š” ์„ธ ๊ฐœ์˜ ์„น์…˜์ด ์žˆ์œผ๋ฉฐ, ๊ฐ ์„น์…˜ ์‚ฌ์ด์— ์ „ํ™˜๋˜๋Š” ํ™”์‚ดํ‘œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์„น์…˜์—๋Š” 'div'๋กœ ๋ ˆ์ด๋ธ” ๋œ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ปดํฌ๋„ŒํŠธ์˜ ๋‹จ์ผ ์ž์‹์œผ๋กœ 'section'์ด๋ผ๊ณ  ๋ ˆ์ด๋ธ” ๋œ ์„น์…˜์ด ์žˆ์œผ๋ฉฐ, ๊ทธ ์•ˆ์— 'Counter'๋ผ๊ณ  ๋ ˆ์ด๋ธ” ๋œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ปดํฌ๋„ŒํŠธ ์•ˆ์—๋Š” 'count'๋ผ๊ณ  ๋ ˆ์ด๋ธ” ๋œ state ๋ฒ„๋ธ”์ด ์žˆ์œผ๋ฉฐ ๊ฐ’์€ 3์ž…๋‹ˆ๋‹ค. ์ค‘๊ฐ„ ์„น์…˜์—๋Š” ๋™์ผํ•œ 'div' ๋ถ€๋ชจ๊ฐ€ ์žˆ์ง€๋งŒ, ์ด์ œ๋Š” ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์‚ญ์ œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๋…ธ๋ž€์ƒ‰ 'proof' ์ด๋ฏธ์ง€๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์„ธ ๋ฒˆ์งธ ์„น์…˜์—๋Š” ๋‹ค์‹œ ๋™์ผํ•œ 'div' ๋ถ€๋ชจ๊ฐ€ ์žˆ์œผ๋ฉฐ, ์ด๋ฒˆ์—๋Š” 'div'๋ผ๊ณ  ๋ ˆ์ด๋ธ” ๋œ ์ƒˆ๋กœ์šด ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ปดํฌ๋„ŒํŠธ ์•ˆ์—๋Š” 'Counter'๋ผ๊ณ  ๋ ˆ์ด๋ธ” ๋œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์œผ๋ฉฐ, ๊ทธ ์•ˆ์— 'count'๋ผ๊ณ  ๋ ˆ์ด๋ธ” ๋œ state ๋ฒ„๋ธ”์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ๊ฐ’์ด 0์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๋ถ€๋ถ„์ด ๋…ธ๋ž€์ƒ‰์œผ๋กœ ๊ฐ•์กฐ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค."> @@ -450,7 +450,7 @@ export default function PackingList() { </Diagram> -๋˜ํ•œ ๋ฌธ์„œ ๊ณณ๊ณณ์—์„œ ๋ช‡๋ช‡ ์‚ฝํ™”๋ฅผ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค--์—ฌ๊ธฐ [ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๋Š” ๋ธŒ๋ผ์šฐ์ €](/learn/render-and-commit#epilogue-browser-paint) ์ค‘ ํ•˜๋‚˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +๋˜ํ•œ ๋ฌธ์„œ ๊ณณ๊ณณ์—์„œ ๋ช‡๋ช‡ ์‚ฝํ™”๋ฅผ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ [ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๋Š” ๋ธŒ๋ผ์šฐ์ €](/learn/render-and-commit#epilogue-browser-paint) ์ค‘ ํ•˜๋‚˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. <Illustration alt="'์นด๋“œ ์š”์†Œ๊ฐ€ ์žˆ๋Š” ์ •๋ฌผํ™”'๋ฅผ ๊ทธ๋ฆฌ๋Š” ๋ธŒ๋ผ์šฐ์ €" src="/images/docs/illustrations/i_browser-paint.png" /> @@ -460,23 +460,23 @@ export default function PackingList() { [API ์ฐธ๊ณ ์„œ](/reference/react)์—์„œ, ์ด์ œ ๋ชจ๋“  React API๋Š” ์ „์šฉ ํŽ˜์ด์ง€๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ๋ชจ๋“  ์ข…๋ฅ˜์˜ API๋“ค์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. -- [`useState`](/reference/react/useState) ๊ฐ™์€ ๋‚ด์žฅ Hooks +- [`useState`](/reference/react/useState) ๊ฐ™์€ ๋‚ด์žฅ Hook - [`<Suspense>`](/reference/react/Suspense) ๊ฐ™์€ ๋‚ด์žฅ ์ปดํฌ๋„ŒํŠธ - [`<input>`](/reference/react-dom/components/input) ๊ฐ™์€ ๋ธŒ๋ผ์šฐ์ € ๋‚ด์žฅ ์ปดํฌ๋„ŒํŠธ - [`renderToPipeableStream`](/reference/react-dom/server/renderToReadableStream) ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ ์ง€ํ–ฅ API - [`memo`](/reference/react/memo) ๊ฐ™์€ ๊ทธ ๋ฐ–์˜ React API - +r ๋ชจ๋“  API ํŽ˜์ด์ง€๊ฐ€ *๋ ˆํผ๋Ÿฐ์Šค* ์™€ *์‚ฌ์šฉ๋ฒ•*์„ ํฌํ•จํ•˜๋Š” ์ตœ์†Œ ๋‘ ๊ฐœ์˜ ์„ธ๊ทธ๋จผํŠธ๋กœ ๋‚˜๋‰˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [๋ ˆํผ๋Ÿฐ์Šค](/reference/react/useState#reference)๋Š” ์ธ์ž์™€ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๋‚˜์—ดํ•˜์—ฌ ํ˜•์‹์ ์ธ API ์„œ๋ช…์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ„๊ฒฐํ•˜์ง€๋งŒ, ํ•ด๋‹น API์— ์ต์ˆ™ํ•˜์ง€ ์•Š๋‹ค๋ฉด ์•ฝ๊ฐ„ ์ถ”์ƒ์ ์œผ๋กœ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ API๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€๊ฐ€ ์•„๋‹Œ, API๊ฐ€ ๋ฌด์—‡์„ ํ•˜๋Š”์ง€๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. [์‚ฌ์šฉ๋ฒ•](/reference/react/useState#usage)์€ ๋™๋ฃŒ๋‚˜ ์นœ๊ตฌ๊ฐ€ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์‹ค์ œ๋กœ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ์™€ ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. **์ด๋Š” React ํŒ€์—์„œ ๊ฐ API๊ฐ€ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜๊ธฐ๋ฅผ ์˜๋„ํ•œ ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ํ‘œ์ค€์ ์ธ ์‹œ๋‚˜๋ฆฌ์˜ค**๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ƒ‰์ƒ ์žˆ๋Š” ์ฝ”๋“œ ์Šค๋‹ˆํŽซ, ์„œ๋กœ ๋‹ค๋ฅธ API๋“ค์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์‹œ, ๋ณต์‚ฌ ๋ฐ ๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ ˆ์‹œํ”ผ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. -<Recipes titleText="Basic useState examples" titleId="examples-basic"> +<Recipes titleText="๊ธฐ๋ณธ useState ์˜ˆ์‹œ" titleId="examples-basic"> #### ์นด์šดํ„ฐ (์ˆซ์ž) {/*counter-number*/} -์ด ์˜ˆ์‹œ์—์„œ `count` state ๋ณ€์ˆ˜๋Š” ์ˆซ์ž๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ˆซ์ž๊ฐ€ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. +์ด ์˜ˆ์‹œ์—์„œ `count` State ๋ณ€์ˆ˜๋Š” ์ˆซ์ž๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ˆซ์ž๊ฐ€ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. <Sandpack> @@ -504,7 +504,7 @@ export default function Counter() { #### ํ…์ŠคํŠธ ํ•„๋“œ (๋ฌธ์ž์—ด) {/*text-field-string*/} -์ด ์˜ˆ์‹œ์—์„œ `text` state ๋ณ€์ˆ˜๋Š” ๋ฌธ์ž์—ด์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•  ๋•Œ, `handleChange`๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์˜ input DOM ์š”์†Œ๋กœ๋ถ€ํ„ฐ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ž…๋ ฅ๋œ ๊ฐ’์„ ์ฝ๊ณ  state๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด `setText`๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ํ˜„์žฌ์˜ `text`๋ฅผ ์•„๋ž˜์— ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด ์˜ˆ์‹œ์—์„œ `text` State ๋ณ€์ˆ˜๋Š” ๋ฌธ์ž์—ด์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•  ๋•Œ, `handleChange`๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์˜ Input DOM ์š”์†Œ๋กœ๋ถ€ํ„ฐ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ž…๋ ฅ๋œ ๊ฐ’์„ ์ฝ๊ณ  State๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด `setText`๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋”ฐ๋ผ ํ˜„์žฌ์˜ `text`๋ฅผ ์•„๋ž˜์— ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <Sandpack> @@ -536,7 +536,7 @@ export default function MyInput() { #### ์ฒดํฌ๋ฐ•์Šค (๋ถˆ๋ฆฌ์–ธ) {/*checkbox-boolean*/} -์ด ์˜ˆ์‹œ์—์„œ `liked` state ๋ณ€์ˆ˜๋Š” ๋ถˆ๋ฆฌ์–ธ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. input ์š”์†Œ๋ฅผ ํด๋ฆญํ•  ๋•Œ, `setLiked`๊ฐ€ ๋ธŒ๋ผ์šฐ์ € ์ฒดํฌ๋ฐ•์Šค์˜ ์„ ํƒ ์—ฌ๋ถ€์— ๋”ฐ๋ผ `liked` state ๋ณ€์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. `liked`๋Š” ์ฒดํฌ๋ฐ•์Šค ์•„๋ž˜์— ์žˆ๋Š” ๋ฌธ๊ตฌ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. +์ด ์˜ˆ์‹œ์—์„œ `liked` State ๋ณ€์ˆ˜๋Š” ๋ถˆ๋ฆฌ์–ธ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. Input ์š”์†Œ๋ฅผ ํด๋ฆญํ•  ๋•Œ, `setLiked`๊ฐ€ ๋ธŒ๋ผ์šฐ์ € ์ฒดํฌ๋ฐ•์Šค์˜ ์„ ํƒ ์—ฌ๋ถ€์— ๋”ฐ๋ผ `liked` state ๋ณ€์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. `liked`๋Š” ์ฒดํฌ๋ฐ•์Šค ์•„๋ž˜์— ์žˆ๋Š” ๋ฌธ๊ตฌ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. <Sandpack> @@ -572,7 +572,7 @@ export default function MyCheckbox() { #### ์–‘์‹ (๋‘ ๊ฐ€์ง€ ๋ณ€์ˆ˜) {/*form-two-variables*/} -ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ state ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ state ๋ณ€์ˆ˜๋Š” ์™„์ „ํžˆ ๋…๋ฆฝ์ ์ž…๋‹ˆ๋‹ค. +ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ State ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ State ๋ณ€์ˆ˜๋Š” ์™„์ „ํžˆ ๋…๋ฆฝ์ ์ž…๋‹ˆ๋‹ค. <Sandpack> @@ -626,7 +626,7 @@ button { display: block; margin-top: 10px; } - ์ƒˆ๋กœ์šด ๋ฌธ์„œ๊ฐ€ ๋ฒˆ์—ญ๋˜๋„๋ก ์ „ ์„ธ๊ณ„ ์ปค๋ฎค๋‹ˆํ‹ฐ์™€ ํ˜‘์—…ํ•˜๊ธฐ - ์ƒˆ๋กœ์šด ์›น ์‚ฌ์ดํŠธ์— ๋†“์นœ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ํ•˜๊ธฐ (์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ๋ธ”๋กœ๊ทธ๋ฅผ ์œ„ํ•œ RSS) -์ด์ œ [react.dev](https://react.dev/)๊ฐ€ ์ถœ์‹œ๋˜์—ˆ์œผ๋‹ˆ, ์ œ์‚ผ์ž React ๊ต์œก ์ž๋ฃŒ๋ฅผ "๋”ฐ๋ผ์žก๋Š”" ๋ฐ์„œ ๋ฒ—์–ด๋‚˜ ์ƒˆ๋กœ์šด ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ƒˆ ์›น ์‚ฌ์ดํŠธ๋ฅผ ๋”์šฑ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +์ด์ œ [react.dev](https://react.dev/)๊ฐ€ ์ถœ์‹œ๋˜์—ˆ์œผ๋‹ˆ, ์ œ ์‚ผ์ž React ๊ต์œก ์ž๋ฃŒ๋ฅผ "๋”ฐ๋ผ์žก๋Š”" ๋ฐ์„œ ๋ฒ—์–ด๋‚˜ ์ƒˆ๋กœ์šด ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ƒˆ ์›น ์‚ฌ์ดํŠธ๋ฅผ ๋”์šฑ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. React๋ฅผ ๋ฐฐ์šฐ๊ธฐ์— ๊ฐ€์žฅ ์ข‹์€ ์‹œ๊ธฐ๊ฐ€ ์™”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. diff --git a/src/content/reference/react-dom/server/renderToReadableStream.md b/src/content/reference/react-dom/server/renderToReadableStream.md index fca41bb75..24563d4c1 100644 --- a/src/content/reference/react-dom/server/renderToReadableStream.md +++ b/src/content/reference/react-dom/server/renderToReadableStream.md @@ -4,7 +4,7 @@ title: renderToReadableStream <Intro> -`renderToReadableStream`๋Š” [Readable Web Stream.](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)๋ฅผ ์ด์šฉํ•ด React tree๋ฅผ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค. +`renderToReadableStream`๋Š” [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)์„ ์ด์šฉํ•ด React tree๋ฅผ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค. ```js const stream = await renderToReadableStream(reactNode, options?) From 88b50317ac2c53d66cce703e669ce712329c0258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 20:45:30 +0900 Subject: [PATCH 0358/1059] docs: update `react-labs-what-we-have-been-wroking-...-.md` --- ...what-we-have-been-working-on-march-2023.md | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md b/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md index 4ef33b6bc..dcc29aab1 100644 --- a/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md +++ b/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md @@ -19,17 +19,17 @@ React Labs ๊ฒŒ์‹œ๊ธ€์—๋Š” ํ™œ๋ฐœํžˆ ์—ฐ๊ตฌ ๊ฐœ๋ฐœ ์ค‘์ธ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ## React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ {/*react-server-components*/} -React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ(React Server Components, ๋˜๋Š” RSC)๋Š” React ํŒ€์—์„œ ์„ค๊ณ„ํ•œ ์ƒˆ๋กœ์šด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•„ํ‚คํ…์ฒ˜์ž…๋‹ˆ๋‹ค. +React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ<sup>React Server Components, RSC</sup>๋Š” React ํŒ€์—์„œ ์„ค๊ณ„ํ•œ ์ƒˆ๋กœ์šด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•„ํ‚คํ…์ฒ˜์ž…๋‹ˆ๋‹ค. -์šฐ๋ฆฌ๋Š” ๋จผ์ € [์†Œ๊ฐœ ๋ฐœํ‘œ](/blog/2020/12/21/data-fetching-with-react-server-components)์™€ [RFC](https://github.com/reactjs/rfcs/pull/188)์—์„œ RSC์— ๋Œ€ํ•œ ์—ฐ๊ตฌ๋ฅผ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๋‚ด์šฉ์„ ์š”์•ฝํ•˜๋ฉด, ๋ฏธ๋ฆฌ ์‹คํ–‰ํ•˜๊ณ  JavaScript ๋ฒˆ๋“ค์—์„œ ์ œ์™ธํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ์ข…๋ฅ˜์˜ ์ปดํฌ๋„ŒํŠธ์ธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋นŒ๋“œ ์ค‘์— ์‹คํ–‰๋˜์–ด ํŒŒ์ผ ์‹œ์Šคํ…œ์—์„œ ์ฝ๊ฑฐ๋‚˜ ์ •์  ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์„œ๋ฒ„์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์–ด API๋ฅผ ๋นŒ๋“œํ•  ํ•„์š” ์—†์ด ๋ฐ์ดํ„ฐ ๊ณ„์ธต์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. props๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์šฐ๋ฆฌ๋Š” ๋จผ์ € [์†Œ๊ฐœ ๋ฐœํ‘œ](/blog/2020/12/21/data-fetching-with-react-server-components)์™€ [RFC](https://github.com/reactjs/rfcs/pull/188)์—์„œ RSC์— ๋Œ€ํ•œ ์—ฐ๊ตฌ๋ฅผ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๋‚ด์šฉ์„ ์š”์•ฝํ•˜๋ฉด, ๋ฏธ๋ฆฌ ์‹คํ–‰ํ•˜๊ณ  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค์—์„œ ์ œ์™ธํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ์ข…๋ฅ˜์˜ ์ปดํฌ๋„ŒํŠธ์ธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์†Œ๊ฐœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋นŒ๋“œ ์ค‘์— ์‹คํ–‰๋˜์–ด ํŒŒ์ผ ์‹œ์Šคํ…œ์—์„œ ์ฝ๊ฑฐ๋‚˜ ์ •์  ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์„œ๋ฒ„์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์–ด API๋ฅผ ๋นŒ๋“œํ•  ํ•„์š” ์—†์ด ๋ฐ์ดํ„ฐ ๊ณ„์ธต์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Props๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. RSC๋Š” ์„œ๋ฒ„ ์ค‘์‹ฌ์˜ ๋ฉ€ํ‹ฐ ํŽ˜์ด์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฐ„๋‹จํ•œ "์š”์ฒญ/์‘๋‹ต" ๋ฉ˜ํƒˆ ๋ชจ๋ธ์— ํด๋ผ์ด์–ธํŠธ ์ค‘์‹ฌ์˜ ์‹ฑ๊ธ€ ํŽ˜์ด์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์›ํ™œํ•œ ์ƒํ˜ธ์ž‘์šฉ์„ ๊ฒฐํ•ฉํ•˜์—ฌ ์–‘์ชฝ์˜ ์žฅ์ ์„ ๋ชจ๋‘ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ง€๋‚œ ์—…๋ฐ์ดํŠธ ์ดํ›„ ์šฐ๋ฆฌ๋Š” ์ œ์•ˆ์„ ์Šน์ธํ•˜๊ธฐ ์œ„ํ•ด [React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ RFC](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md)๋ฅผ ๋ณ‘ํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค. [React ์„œ๋ฒ„ ๋ชจ๋“ˆ ์ปจ๋ฒค์…˜](https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md) ์ œ์•ˆ๊ณผ ๊ด€๋ จ๋œ ๋‚จ์•„ ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๊ณ , ๋™๋ฃŒ๋“ค๊ณผ `"use client"` ์ปจ๋ฒค์…˜์„ ๋”ฐ๋ฅด๊ธฐ๋กœ ํ•ฉ์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์„œ๋“ค์€ RSC์™€ ํ˜ธํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌํ˜„ ๋ฐฉ์‹์ด ์ง€์›ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๋ช…์„ธ๋กœ๋„ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -๊ฐ€์žฅ ํฐ ๋ณ€๊ฒฝ ์ ์€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ธฐ๋ณธ ๋ฐฉ๋ฒ•์œผ๋กœ [`async` / `await`](https://github.com/reactjs/rfcs/pull/229)๋ฅผ ๋„์ž…ํ–ˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ Promise์˜ ๊ฒฐ๊ณผ๋ฅผ ์ฝ๋Š” ์ƒˆ๋กœ์šด `use` Hook์„ ๋„์ž…ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์„ ์ง€์›ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ๋น„๋ก ํด๋ผ์ด์–ธํŠธ ์ „์šฉ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ž„์˜์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ `async / await`๋ฅผ ์ง€์›ํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ, RSC ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌ์กฐ์™€ ์œ ์‚ฌํ•˜๊ฒŒ ํด๋ผ์ด์–ธํŠธ ์ „์šฉ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•  ๋•Œ๋ฅผ ์œ„ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. +๊ฐ€์žฅ ํฐ ๋ณ€๊ฒฝ ์ ์€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ธฐ๋ณธ ๋ฐฉ๋ฒ•์œผ๋กœ [`async` / `await`](https://github.com/reactjs/rfcs/pull/229)์„ ๋„์ž…ํ–ˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ Promise์˜ ๊ฒฐ๊ณผ๋ฅผ ์ฝ๋Š” ์ƒˆ๋กœ์šด `use` Hook์„ ๋„์ž…ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์„ ์ง€์›ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ๋น„๋ก ํด๋ผ์ด์–ธํŠธ ์ „์šฉ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ž„์˜์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ `async` / `await`์„ ์ง€์›ํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ, RSC ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌ์กฐ์™€ ์œ ์‚ฌํ•˜๊ฒŒ ํด๋ผ์ด์–ธํŠธ ์ „์šฉ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•  ๋•Œ๋ฅผ ์œ„ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. -์ด์ œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ์–ด๋А ์ •๋„ ์ž˜ ์ •๋ฆฌ๋˜์—ˆ์œผ๋ฏ€๋กœ ๋‹ค๋ฅธ ๋ฐฉํ–ฅ์„ ์‚ดํŽด๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณ€๊ฒฝ์„ ์‹คํ–‰ํ•˜๊ณ  ํผ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์˜ ๊ฒฝ๊ณ„๋ฅผ ๋„˜์–ด ์„œ๋ฒ„ ์•ก์…˜ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์›ํ™œํ•œ RPC๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์•ก์…˜์€ ๋˜ํ•œ JavaScript๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์ „์— ์ ์ง„์ ์œผ๋กœ ํ–ฅ์ƒ๋œ ํผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +์ด์ œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ<sup>Fetching</sup>๊ฐ€ ์–ด๋А ์ •๋„ ์ž˜ ์ •๋ฆฌ๋˜์—ˆ์œผ๋ฏ€๋กœ ๋‹ค๋ฅธ ๋ฐฉํ–ฅ์„ ์‚ดํŽด๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณ€๊ฒฝ์„ ์‹คํ–‰ํ•˜๊ณ  ํผ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์˜ ๊ฒฝ๊ณ„๋ฅผ ๋„˜์–ด ์„œ๋ฒ„ ์•ก์…˜ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์›ํ™œํ•œ RPC๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์•ก์…˜์€ ๋˜ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์ „์— ์ ์ง„์ ์œผ๋กœ ํ–ฅ์ƒ๋œ ํผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” [Next.js App ๋ผ์šฐํ„ฐ](/learn/start-a-new-react-project#nextjs-app-router)์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Next.js์—์„œ๋Š” ๋ผ์šฐํ„ฐ์™€ ๊นŠ์€ ๊ฒฐํ•ฉ์„ ํ†ตํ•ด RSC๋ฅผ ๊ธฐ๋ณธ ์š”์†Œ๋กœ ๋ฐ›์•„๋“ค์ด๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋ฐฉ๋ฒ•์ด RSC์™€ ํ˜ธํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์šฐํ„ฐ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋‹™๋‹ˆ๋‹ค. RSC ๋ช…์„ธ์™€ ๊ตฌํ˜„์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์—๋Š” ๋ช…ํ™•ํ•œ ๊ตฌ๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค. React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ํ˜ธํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” React ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋™์ž‘ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ๋ช…์„ธ์ž…๋‹ˆ๋‹ค. @@ -37,9 +37,9 @@ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” [Next.js App ๋ผ์šฐํ„ฐ](/learn/start-a-new-react-pr ## ์—์…‹ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ {/*asset-loading*/} -[Suspense](/reference/react/Suspense)๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๋‚˜ ์ฝ”๋“œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋™์•ˆ ํ™”๋ฉด์— ํ‘œ์‹œํ•  ๋‚ด์šฉ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๋Š” ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋™์•ˆ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ์™€ ์ฝ”๋“œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ผ์šฐํ„ฐ ๋‚ด๋น„๊ฒŒ์ด์…˜ ์ค‘์—์„œ๋„ ์ ์ง„์ ์œผ๋กœ ๋” ๋งŽ์€ ์ฝ˜ํ…์ธ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‚ฌ์šฉ์ž์˜ ๊ด€์ ์—์„œ ์ƒˆ๋กœ์šด ์ฝ˜ํ…์ธ ๊ฐ€ ์ค€๋น„๋˜์—ˆ๋Š”์ง€๋ฅผ ๊ณ ๋ คํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์ด ๋ชจ๋“  ๊ฒƒ์„ ์•Œ๋ ค์ฃผ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” ์Šคํƒ€์ผ์‹œํŠธ, ๊ธ€๊ผด ๋ฐ ์ด๋ฏธ์ง€๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋•Œ๋ฌธ์— UI ์ ํ”„์™€ ์—ฐ์†์ ์ธ ๋ ˆ์ด์•„์›ƒ ์ด๋™์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +[Suspense](/reference/react/Suspense)๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๋‚˜ ์ฝ”๋“œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋™์•ˆ ํ™”๋ฉด์— ํ‘œ์‹œํ•  ๋‚ด์šฉ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๋Š” ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋™์•ˆ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ์™€ ์ฝ”๋“œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ผ์šฐํ„ฐ ๋‚ด๋น„๊ฒŒ์ด์…˜ ์ค‘์—์„œ๋„ ์ ์ง„์ ์œผ๋กœ ๋” ๋งŽ์€ ์ฝ˜ํ…์ธ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‚ฌ์šฉ์ž์˜ ๊ด€์ ์—์„œ ์ƒˆ๋กœ์šด ์ฝ˜ํ…์ธ ๊ฐ€ ์ค€๋น„๋˜์—ˆ๋Š”์ง€๋ฅผ ๊ณ ๋ คํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์ด ๋ชจ๋“  ๊ฒƒ์„ ์•Œ๋ ค์ฃผ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” ์Šคํƒ€์ผ์‹œํŠธ, ๊ธ€๊ผด ๋ฐ ์ด๋ฏธ์ง€๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋•Œ๋ฌธ์— UI ์ ํ”„์™€ ์—ฐ์†์ ์ธ ๋ ˆ์ด์•„์›ƒ ์ด๋™์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์šฐ๋ฆฌ๋Š” Suspense๊ฐ€ ์Šคํƒ€์ผ์‹œํŠธ, ๊ธ€๊ผด ๋ฐ ์ด๋ฏธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ƒ๋ช…์ฃผ๊ธฐ์™€ ์™„์ „ํžˆ ํ†ตํ•ฉ๋˜๋„๋ก ์ž‘์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด React๊ฐ€ ์ฝ˜ํ…์ธ ๊ฐ€ ํ™”๋ฉด์— ํ‘œ์‹œํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋„๋ก ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๋Š” React ์ปดํฌ๋„ŒํŠธ ์ž‘์„ฑ ๋ฐฉ์‹์— ์–ด๋– ํ•œ ๋ณ€๊ฒฝ๋„ ์—†์ด ๋” ์ผ๊ด€๋˜๊ณ  ๋งŒ์กฑ์Šค๋Ÿฌ์šด ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ๊ธ€๊ผด๊ณผ ๊ฐ™์€ ์—์…‹์„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ง์ ‘ ๋ฏธ๋ฆฌ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ˆ˜๋™ ๋ฐฉ๋ฒ•๋„ ์ œ๊ณตํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ €ํฌ๋Š” Suspense๊ฐ€ ์Šคํƒ€์ผ์‹œํŠธ, ๊ธ€๊ผด ๋ฐ ์ด๋ฏธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ƒ๋ช…์ฃผ๊ธฐ์™€ ์™„์ „ํžˆ ํ†ตํ•ฉ๋˜๋„๋ก ์ž‘์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด React์˜ ์ฝ˜ํ…์ธ ๊ฐ€ ํ™”๋ฉด์— ํ‘œ์‹œํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋„๋ก ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๋Š” React ์ปดํฌ๋„ŒํŠธ ์ž‘์„ฑ ๋ฐฉ์‹์— ์–ด๋– ํ•œ ๋ณ€๊ฒฝ๋„ ์—†์ด, ๋” ์ผ๊ด€๋˜๊ณ  ๋งŒ์กฑ์„ ์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ๊ธ€๊ผด๊ณผ ๊ฐ™์€ ์—์…‹์„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ง์ ‘ ๋ฏธ๋ฆฌ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ˆ˜๋™์ ์ธ ๋ฐฉ๋ฒ•๋„ ์ œ๊ณตํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ๋“ค์„ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๊ณง ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ๊ณต์œ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. @@ -49,7 +49,7 @@ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” [Next.js App ๋ผ์šฐํ„ฐ](/learn/start-a-new-react-pr ํ˜„์žฌ ๊ฐœ๋ฐœ์ž๋Š” ๋‘ ๊ฐ€์ง€ ๊ธฐ์ˆ  ์ค‘ ํ•˜๋‚˜์˜ ๋ฐฉ๋ฒ•์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. -ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ `<title>`, `<meta>`, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์•ˆ์˜ ๋‹ค๋ฅธ ํƒœ๊ทธ๋“ค์„ ๋ฌธ์„œ์˜ `<head>`๋กœ ์ด๋™์‹œํ‚ค๋Š” ํŠน๋ณ„ํ•œ ์„œ๋“œํŒŒํ‹ฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์ฃผ์š” ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€๋งŒ, Open Graph ํŒŒ์„œ์™€ ๊ฐ™์ด ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ JavaScript๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ๋ณดํŽธ์ ์œผ๋กœ ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ `<title>`, `<meta>`, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์•ˆ์˜ ๋‹ค๋ฅธ ํƒœ๊ทธ๋“ค์„ ๋ฌธ์„œ์˜ `<head>`๋กœ ์ด๋™์‹œํ‚ค๋Š” ํŠน๋ณ„ํ•œ ์„œ๋“œํŒŒํ‹ฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์ฃผ์š” ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€๋งŒ, Open Graph ํŒŒ์„œ<sup>Parser</sup>์™€ ๊ฐ™์ด ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ๋ณดํŽธ์ ์œผ๋กœ ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ํŽ˜์ด์ง€๋ฅผ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„์–ด ์„œ๋ฒ„ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋จผ์ € ์ฃผ์š” ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•œ ํ›„ ์ด๋Ÿฌํ•œ ๋ชจ๋“  ํƒœ๊ทธ๊ฐ€ ์ˆ˜์ง‘๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ˆ˜์ง‘ํ•œ ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•˜์—ฌ `<head>`๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ `<head>`์™€ ์ฃผ์š” ์ฝ˜ํ…์ธ ๋ฅผ ๋ธŒ๋ผ์šฐ์ €๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ๋ฒ•์€ ์ž˜ ์ž‘๋™ํ•˜์ง€๋งŒ, `<head>`๊ฐ€ ์ „์†ก๋˜๊ธฐ ์ „์— ๋ชจ๋“  ์ฝ˜ํ…์ธ ๊ฐ€ ๋ Œ๋”๋ง ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋ฏ€๋กœ [React 18์˜ Streaming Server Renderer](/reference/react-dom/server/renderToReadableStream)์˜ ์žฅ์ ์„ ํ™œ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. @@ -57,27 +57,27 @@ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” [Next.js App ๋ผ์šฐํ„ฐ](/learn/start-a-new-react-pr ## React ์ตœ์ ํ™” ์ปดํŒŒ์ผ๋Ÿฌ {/*react-optimizing-compiler*/} -์ง€๋‚œ ์—…๋ฐ์ดํŠธ ์ดํ›„ ์šฐ๋ฆฌ๋Š” React์˜ ์ตœ์ ํ™” ์ปดํŒŒ์ผ๋Ÿฌ์ธ [React Forget](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022#react-compiler)์˜ ์„ค๊ณ„๋ฅผ ์ ๊ทน์ ์œผ๋กœ ๋ฐ˜๋ณตํ•˜๋ฉฐ ์ž‘์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์— ์ด๋ฅผ "์ž๋™ memoizing ์ปดํŒŒ์ผ๋Ÿฌ"๋ผ๊ณ  ์–ธ๊ธ‰ํ–ˆ๊ณ , ์–ด๋–ค ์˜๋ฏธ์—์„œ๋Š” ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋ฉด์„œ React์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์„ ๋” ๊นŠ์ด ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. React Forget์„ ์ดํ•ดํ•˜๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ž๋™ *๋ฐ˜์‘์„ฑ* ์ปดํŒŒ์ผ๋Ÿฌ์ž…๋‹ˆ๋‹ค. +์ง€๋‚œ ์—…๋ฐ์ดํŠธ ์ดํ›„ ์šฐ๋ฆฌ๋Š” React์˜ ์ตœ์ ํ™” ์ปดํŒŒ์ผ๋Ÿฌ์ธ [React Forget](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022#react-compiler)์˜ ์„ค๊ณ„๋ฅผ ์ ๊ทน์ ์œผ๋กœ ๋ฐ˜๋ณตํ•˜๋ฉฐ ์ž‘์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์— ์ด๋ฅผ "์ž๋™ Memoizing ์ปดํŒŒ์ผ๋Ÿฌ"๋ผ๊ณ  ์–ธ๊ธ‰ํ–ˆ๊ณ , ์–ด๋–ค ์˜๋ฏธ์—์„œ๋Š” ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋ฉด์„œ React์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์„ ๋” ๊นŠ์ด ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. React Forget์„ ์ดํ•ดํ•˜๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ž๋™ *๋ฐ˜์‘์„ฑ* ์ปดํŒŒ์ผ๋Ÿฌ์ž…๋‹ˆ๋‹ค. -React์˜ ํ•ต์‹ฌ ์•„์ด๋””์–ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ํ˜„์žฌ state์˜ ํ•จ์ˆ˜๋กœ UI๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ˆซ์ž, ๋ฌธ์ž์—ด, ๋ฐฐ์—ด, ๊ฐ์ฒด์™€ ๊ฐ™์€ ์ˆœ์ˆ˜ํ•œ JavaScript์˜ ๊ฐ’๊ณผ if/else, for ๋“ฑ ํ‘œ์ค€ JavaScript ๊ด€์šฉ๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ ๋กœ์ง์„ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ˜ํƒˆ ๋ชจ๋ธ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ state๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค React๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋งํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฐ ๊ฐ„๋‹จํ•œ ๋ฉ˜ํƒˆ ๋ชจ๋ธ๊ณผ JavaScript ์˜๋ฏธ๋ก ์— ๊ฐ€๊น๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด React ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์˜ ์ค‘์š”ํ•œ ์›์น™์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. +React์˜ ํ•ต์‹ฌ ์•„์ด๋””์–ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ํ˜„์žฌ State์˜ ํ•จ์ˆ˜๋กœ UI๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ˆซ์ž, ๋ฌธ์ž์—ด, ๋ฐฐ์—ด, ๊ฐ์ฒด์™€ ๊ฐ™์€ ์ˆœ์ˆ˜ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ฐ’๊ณผ `if`/`else`, `for` ๋“ฑ ํ‘œ์ค€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธํŠธ ๊ด€์šฉ๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ ๋กœ์ง์„ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ˜ํƒˆ ๋ชจ๋ธ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ State๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค React๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋งํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฐ ๊ฐ„๋‹จํ•œ ๋ฉ˜ํƒˆ ๋ชจ๋ธ๊ณผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์˜๋ฏธ๋ก ์— ๊ฐ€๊น๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด React ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์˜ ์ค‘์š”ํ•œ ์›์น™์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. -๋ฌธ์ œ๋Š” React๋Š” ๋„ˆ๋ฌด ๋งŽ์ด ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๋“ฑ ๋•Œ๋•Œ๋กœ *์ง€๋‚˜์น˜๊ฒŒ* ๋ฐ˜์‘์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋กœ JavaScript์—์„œ ๋‘ ๊ฐœ์˜ ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์ด ๋™๋“ฑํ•œ์ง€(๋™์ผํ•œ key์™€ ๊ฐ’์„ ๊ฐ€์กŒ๋Š”์ง€) ๋น„๊ตํ•˜๋Š” ์ €๋ ดํ•œ ๋ฐฉ๋ฒ•์ด ์—†์œผ๋ฏ€๋กœ, ๋ Œ๋”๋ง๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ React๊ฐ€ ์—„๋ฐ€ํ•˜๊ฒŒ ํ•„์š”ํ•œ ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ง€๋‚˜์น˜๊ฒŒ ๋ฐ˜์‘์ ์ด์ง€ ์•Š๋„๋ก ๋ช…์‹œ์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฉ”๋ชจํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. +๋ฌธ์ œ๋Š” React๊ฐ€ ๋„ˆ๋ฌด ์ž์ฃผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๋“ฑ ๋•Œ๋•Œ๋กœ *์ง€๋‚˜์น˜๊ฒŒ* ๋ฐ˜์‘์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋‘ ๊ฐœ์˜ ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์ด ๋™๋“ฑํ•œ์ง€(๋™์ผํ•œ key์™€ ๊ฐ’์„ ๊ฐ€์กŒ๋Š”์ง€) ๋น„๊ตํ•˜๋Š” ์ €๋ ดํ•œ ๋ฐฉ๋ฒ•์ด ์—†์œผ๋ฏ€๋กœ, ๋ Œ๋”๋ง๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ React๊ฐ€ ์—„๋ฐ€ํ•˜๊ฒŒ ํ•„์š”ํ•œ ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ง€๋‚˜์น˜๊ฒŒ ๋ฐ˜์‘์ ์ด์ง€ ์•Š๋„๋ก ๋ช…์‹œ์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฉ”๋ชจํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -React Forget์˜ ๋ชฉํ‘œ๋Š” React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ ๋‹นํ•œ ๋ฐ˜์‘์„ฑ์„ ๊ฐ–๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์˜ค์ง state ๊ฐ’์„ *์˜๋ฏธ ์žˆ๊ฒŒ* ๋ณ€๊ฒฝํ•  ๋•Œ๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ตฌํ˜„์˜ ๊ด€์ ์—์„œ ์ด๋Š” ์ž๋™์œผ๋กœ ๋ฉ”๋ชจํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€๋งŒ, ๋ฐ˜์‘์„ฑ ํ”„๋ ˆ์ด๋ฐ์ด React์™€ Forget์„ ์ดํ•ดํ•˜๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด ๋ณผ ์ˆ˜ ์žˆ๋Š” ํ•˜๋‚˜์˜ ๋ฐฉ๋ฒ•์€ ํ˜„์žฌ์˜ React๊ฐ€ ๊ฐ์ฒด ID๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๋‹ค์‹œ ๋ Œ๋”๋งํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Forget์„ ์‚ฌ์šฉํ•˜๋ฉด React๋Š” ์˜๋ฏธ์ƒ์œผ๋กœ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์ง€๋งŒ, ๊นŠ์€ ๋น„๊ต๋ฅผ ์œ„ํ•œ ๋Ÿฐํƒ€์ž„ ๋น„์šฉ์„ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +React Forget์˜ ๋ชฉํ‘œ๋Š” React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ ๋‹นํ•œ ๋ฐ˜์‘์„ฑ์„ ๊ฐ–๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์˜ค์ง State ๊ฐ’์„ *์˜๋ฏธ ์žˆ๊ฒŒ* ๋ณ€๊ฒฝํ•  ๋•Œ๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ตฌํ˜„์˜ ๊ด€์ ์—์„œ ์ด๋Š” ์ž๋™์œผ๋กœ ๋ฉ”๋ชจํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€๋งŒ, ๋ฐ˜์‘์„ฑ ํ”„๋ ˆ์ด๋ฐ์ด React์™€ Forget์„ ์ดํ•ดํ•˜๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด ๋ณผ ์ˆ˜ ์žˆ๋Š” ํ•˜๋‚˜์˜ ๋ฐฉ๋ฒ•์€ ํ˜„์žฌ์˜ React๊ฐ€ ๊ฐ์ฒด ID๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๋‹ค์‹œ ๋ Œ๋”๋งํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Forget์„ ์‚ฌ์šฉํ•˜๋ฉด React๋Š” ์˜๋ฏธ์ƒ์œผ๋กœ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์ง€๋งŒ, ๊นŠ์€ ๋น„๊ต๋ฅผ ์œ„ํ•œ ๋Ÿฐํƒ€์ž„ ๋น„์šฉ์„ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ตฌ์ฒด์ ์ธ ์ง„ํ–‰ ์ƒํ™ฉ์„ ์ด์•ผ๊ธฐํ•˜์ž๋ฉด, ์ง€๋‚œ ์—…๋ฐ์ดํŠธ ์ดํ›„ ์ปดํŒŒ์ผ๋Ÿฌ ์„ค๊ณ„๋ฅผ ์ž๋™ ๋ฐ˜์‘์„ฑ ๋ฐฉ์‹์— ๋งž์ถ”๊ณ  ๋‚ด๋ถ€์ ์œผ๋กœ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ์–ป์€ ํ”ผ๋“œ๋ฐฑ์„ ํฌํ•จํ•˜๊ธฐ ์œ„ํ•ด ์ƒ๋‹นํžˆ ๋งŽ์€ ๋ฐ˜๋ณต ์ž‘์—…์„ ๊ฐ€์กŒ์Šต๋‹ˆ๋‹ค. ์ž‘๋…„ ๋ง๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ๋ฆฌํŒฉํ† ๋ง์„ ์ง„ํ–‰ํ•œ ํ›„, ์ด์ œ Meta์—์„œ ์ œํ’ˆ ํ™˜๊ฒฝ์˜ ์ œํ•œ๋œ ๋ถ€๋ถ„์—์„œ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ œํ’ˆ ํ™˜๊ฒฝ์—์„œ ๊ฒ€์ฆ์ด ๋๋‚˜๋ฉด ์˜คํ”ˆ์†Œ์Šค๋กœ ๊ณต๊ฐœํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. -๋งˆ์ง€๋ง‰์œผ๋กœ ๋งŽ์€ ์‚ฌ๋žŒ์ด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ๊ด€์‹ฌ์„ ํ‘œํ˜„ํ•ด ์ฃผ์…จ์Šต๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๊ฒ€์ฆํ•˜๊ณ  ์˜คํ”ˆ์†Œ์Šค๋กœ ๊ณต๊ฐœํ•  ๋•Œ ๋” ๋งŽ์€ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‹น์žฅ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. +๋งˆ์ง€๋ง‰์œผ๋กœ, ๋งŽ์€ ๋ถ„๋“ค์ด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ๊ด€์‹ฌ์„ ๊ฐ€์ ธ์ฃผ์…จ์Šต๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๊ฒ€์ฆํ•˜๊ณ  ์˜คํ”ˆ์†Œ์Šค๋กœ ๊ณต๊ฐœํ•  ๋•Œ ๋” ๋งŽ์€ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋‹น์žฅ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -์ปดํŒŒ์ผ๋Ÿฌ์˜ ํ•ต์‹ฌ ๋ถ€๋ถ„์„ Babel๊ณผ ๊ฑฐ์˜ ๋ถ„๋ฆฌํ–ˆ๊ณ , ํ•ต์‹ฌ ์ปดํŒŒ์ผ๋Ÿฌ API๋Š” ์›๋ณธ ์œ„์น˜ ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๋Œ€๋žต ์˜ค๋ž˜๋œ AST๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ ์ƒˆ๋กœ์šด AST๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ €์ˆ˜์ค€์˜ ์˜๋ฏธ ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋งž์ถคํ˜• ์ฝ”๋“œ ํ‘œํ˜„๊ณผ ๋ณ€ํ™˜ ํŒŒ์ดํ”„๋ผ์ธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ๊ณต๊ฐœ ์ธํ„ฐํŽ˜์ด์Šค๋Š” Babel ๋ฐ ๋‹ค๋ฅธ ๋นŒ๋“œ ์‹œ์Šคํ…œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ์„ ์œ„ํ•ด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ ํ•จ์ˆ˜์˜ ์ƒˆ๋กœ์šด ๋ฒ„์ „์„ ์ƒ์„ฑํ•˜๊ณ  ๊ต์ฒดํ•˜๋Š” ๋งค์šฐ ์–‡์€ ๋ž˜ํผ์ธ Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์ปดํŒŒ์ผ๋Ÿฌ์˜ ํ•ต์‹ฌ ๋ถ€๋ถ„์„ Babel๊ณผ ๊ฑฐ์˜ ๋ถ„๋ฆฌํ–ˆ๊ณ , ํ•ต์‹ฌ ์ปดํŒŒ์ผ๋Ÿฌ API๋Š” ์›๋ณธ ์œ„์น˜ ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ (์•ฝ๊ฐ„) ์˜ค๋ž˜๋œ AST๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ ์ƒˆ๋กœ์šด AST๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ €์ˆ˜์ค€์˜ ์˜๋ฏธ ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋งž์ถคํ˜• ์ฝ”๋“œ ํ‘œํ˜„๊ณผ ๋ณ€ํ™˜ ํŒŒ์ดํ”„๋ผ์ธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ๊ณต๊ฐœ ์ธํ„ฐํŽ˜์ด์Šค๋Š” Babel ๋ฐ ๋‹ค๋ฅธ ๋นŒ๋“œ ์‹œ์Šคํ…œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ์„ ์œ„ํ•ด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ ํ•จ์ˆ˜์˜ ์ƒˆ๋กœ์šด ๋ฒ„์ „์„ ์ƒ์„ฑํ•˜๊ณ  ๊ต์ฒดํ•˜๋Š” ๋งค์šฐ ์–‡์€ ๋ž˜ํผ์ธ Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -์ง€๋‚œ ๋ช‡ ๋‹ฌ ๋™์•ˆ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜๋ฉฐ ์กฐ๊ฑด๋ฌธ, ๋ฐ˜๋ณต๋ฌธ, ์žฌํ• ๋‹น, ๋ณ€ํ˜•๊ณผ ๊ฐ™์€ ๋ณต์žก์„ฑ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ•ต์‹ฌ ์ปดํŒŒ์ผ ๋ชจ๋ธ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ JavaScript์—๋Š” if/else, ์‚ผํ•ญ ์—ฐ์‚ฐ์ž, for, for-in, for-of ๋“ฑ ๊ฐ๊ฐ์˜ ๊ธฐ๋Šฅ์„ ํ‘œํ˜„ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ๋ถ€ํ„ฐ ์–ธ์–ด์˜ ์ „์ฒด ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ํ•ต์‹ฌ ๋ชจ๋ธ์„ ๊ฒ€์ฆํ•˜๋Š” ์‹œ์ ์ด ์ง€์—ฐ๋˜์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€์‹ , let/const, if/else, for ๋ฃจํ”„, ๊ฐ์ฒด, ๋ฐฐ์—ด, ์›์‹œ ๊ฐ’, ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋“ฑ ์ž‘์ง€๋งŒ JavaScript ์–ธ์–ด๋ฅผ ๋Œ€ํ‘œํ•˜๋Š” ํ•˜์œ„ ์ง‘ํ•ฉ๋ถ€ํ„ฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•ต์‹ฌ ๋ชจ๋ธ์— ๋Œ€ํ•œ ์ž์‹ ๊ฐ์„ ์–ป๊ณ  ๋‚ด๋ถ€ ์ถ”์ƒํ™”๋ฅผ ๊ฐœ์„ ํ•˜๋ฉด์„œ ์ง€์›ํ•˜๋Š” ์–ธ์–ด์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์„ ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์•„์ง ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋ฌธ๋ฒ•์— ๋Œ€ํ•ด ๋ช…์‹œ์ ์œผ๋กœ ๋กœ๊น… ์ง„๋‹จ ์ •๋ณด๋ฅผ ๋‚จ๊ธฐ๊ณ , ์ง€์›๋˜์ง€ ์•Š๋Š” ์ž…๋ ฅ์— ๋Œ€ํ•œ ์ปดํŒŒ์ผ์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Meta์˜ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•œ ํ›„ ๊ฐ€์žฅ ๋งŽ์ด ์ง€์›๋˜์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ์ด ๋ฌด์—‡์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ๊ธฐ๋Šฅ๋“ค์„ ์šฐ์„ ์œผ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ „์ฒด ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜๋„๋ก ์ ์ง„์ ์œผ๋กœ ํ™•์žฅํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. +์ง€๋‚œ ๋ช‡ ๋‹ฌ ๋™์•ˆ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜๋ฉฐ ์กฐ๊ฑด๋ฌธ, ๋ฐ˜๋ณต๋ฌธ, ์žฌํ• ๋‹น, ๋ณ€ํ˜•๊ณผ ๊ฐ™์€ ๋ณต์žก์„ฑ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ•ต์‹ฌ ์ปดํŒŒ์ผ ๋ชจ๋ธ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—๋Š” if/else, ์‚ผํ•ญ ์—ฐ์‚ฐ์ž, for, for-in, for-of ๋“ฑ ๊ฐ๊ฐ์˜ ๊ธฐ๋Šฅ์„ ํ‘œํ˜„ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ๋ถ€ํ„ฐ ์–ธ์–ด์˜ ์ „์ฒด ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ํ•ต์‹ฌ ๋ชจ๋ธ์„ ๊ฒ€์ฆํ•˜๋Š” ์‹œ์ ์ด ์ง€์—ฐ๋˜์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€์‹ , let/const, if/else, for ๋ฃจํ”„, ๊ฐ์ฒด, ๋ฐฐ์—ด, ์›์‹œ ๊ฐ’, ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋“ฑ ์ž‘์ง€๋งŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์–ธ์–ด๋ฅผ ๋Œ€ํ‘œํ•˜๋Š” ํ•˜์œ„ ์ง‘ํ•ฉ๋ถ€ํ„ฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•ต์‹ฌ ๋ชจ๋ธ์— ๋Œ€ํ•œ ์ž์‹ ๊ฐ์„ ์–ป๊ณ  ๋‚ด๋ถ€ ์ถ”์ƒํ™”๋ฅผ ๊ฐœ์„ ํ•˜๋ฉด์„œ ์ง€์›ํ•˜๋Š” ์–ธ์–ด์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์„ ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์•„์ง ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋ฌธ๋ฒ•์— ๋Œ€ํ•ด ๋ช…์‹œ์ ์œผ๋กœ ๋กœ๊น… ์ง„๋‹จ ์ •๋ณด๋ฅผ ๋‚จ๊ธฐ๊ณ , ์ง€์›๋˜์ง€ ์•Š๋Š” ์ž…๋ ฅ์— ๋Œ€ํ•œ ์ปดํŒŒ์ผ์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Meta์˜ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•œ ํ›„ ๊ฐ€์žฅ ๋งŽ์ด ์ง€์›๋˜์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ์ด ๋ฌด์—‡์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ๊ธฐ๋Šฅ๋“ค์„ ์šฐ์„ ์œผ๋กœ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ „์ฒด ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜๋„๋ก ์ ์ง„์ ์œผ๋กœ ํ™•์žฅํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. -React ์ปดํฌ๋„ŒํŠธ์˜ ์ˆœ์ˆ˜ํ•œ JavaScript๋ฅผ ๋ฐ˜์‘ํ˜•์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ ์ฝ”๋“œ๊ฐ€ ์ •ํ™•ํ•˜๊ฒŒ ๋ฌด์—‡์„ ์›ํ•˜๋Š”์ง€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ์˜๋ฏธ๋ก ์ ์œผ๋กœ ๊นŠ์€ ์ดํ•ด๋ฅผ ํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ ‘๊ทผ๋ฒ•์„ ์ฑ„ํƒํ•จ์œผ๋กœ์จ, ์šฐ๋ฆฌ๋Š” JavaScript ๋‚ด์—์„œ ๋„๋ฉ”์ธ ํŠนํ™” ์–ธ์–ด์— ๊ตญํ•œ๋˜์ง€ ์•Š๊ณ , ์–ธ์–ด์˜ ๋ชจ๋“  ํ‘œํ˜„ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋– ํ•œ ๋ณต์žก๋„์˜ ์ œํ’ˆ ์ฝ”๋“œ๋ผ๋„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ˜์‘์„ฑ์„ ์œ„ํ•œ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +React ์ปดํฌ๋„ŒํŠธ์˜ ์ˆœ์ˆ˜ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฐ˜์‘ํ˜•์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด, ์ฝ”๋“œ๊ฐ€ ์ •ํ™•ํ•˜๊ฒŒ ๋ฌด์—‡์„ ์›ํ•˜๋Š”์ง€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ์˜๋ฏธ๋ก ์ ์œผ๋กœ ๊นŠ์€ ์ดํ•ด๋ฅผ ํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ ‘๊ทผ๋ฒ•์„ ์ฑ„ํƒํ•จ์œผ๋กœ์จ, ์šฐ๋ฆฌ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์—์„œ ๋„๋ฉ”์ธ ํŠนํ™” ์–ธ์–ด์— ๊ตญํ•œ๋˜์ง€ ์•Š๊ณ , ์–ธ์–ด์˜ ๋ชจ๋“  ํ‘œํ˜„ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋– ํ•œ ๋ณต์žก๋„์˜ ์ œํ’ˆ ์ฝ”๋“œ๋ผ๋„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ˜์‘์„ฑ์„ ์œ„ํ•œ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ## ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋”๋ง {/*offscreen-rendering*/} -์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋”๋ง์€ React์— ๋‹ค๊ฐ€์˜ฌ ์ถ”๊ฐ€์ ์ธ ์„ฑ๋Šฅ ๋ถ€๋‹ด ์—†์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ํ™”๋ฉด์„ ๋ Œ๋”๋งํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. [`content-visibility` CSS ํ”„๋กœํผํ‹ฐ](https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility)๋ฅผ DOM ์—˜๋ฆฌ๋จผํŠธ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ React ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ ์ž‘๋™ํ•˜๋Š” ๋ฒ„์ „์œผ๋กœ ์ดํ•ดํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ์—ฐ๊ตฌ ์ค‘์— ์šฐ๋ฆฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. +์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋”๋ง์€ React์— ์ถ”๊ฐ€๋  ์ถ”๊ฐ€์ ์ธ ์„ฑ๋Šฅ ๋ถ€๋‹ด ์—†์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ํ™”๋ฉด์„ ๋ Œ๋”๋งํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. [`content-visibility` CSS ํ”„๋กœํผํ‹ฐ](https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility)๋ฅผ DOM ์—˜๋ฆฌ๋จผํŠธ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ React ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ ์ž‘๋™ํ•˜๋Š” ๋ฒ„์ „์œผ๋กœ ์ดํ•ดํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ์—ฐ๊ตฌ ์ค‘์— ์•„๋ž˜์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. - ๋ผ์šฐํ„ฐ๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ํ™”๋ฉด์„ ์‚ฌ์ „ ๋ Œ๋”๋งํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ–ˆ์„ ๋•Œ ์ฆ‰์‹œ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ํƒญ ์ „ํ™˜ ์ปดํฌ๋„ŒํŠธ๋Š” ์ˆจ๊ฒจ์ง„ ํƒญ์˜ state๋ฅผ ์œ ์ง€ํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ์ง„ํ–‰ ์ƒํ™ฉ์„ ์žƒ์ง€ ์•Š๊ณ  ํƒญ์„ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -86,9 +86,9 @@ React ์ปดํฌ๋„ŒํŠธ์˜ ์ˆœ์ˆ˜ํ•œ JavaScript๋ฅผ ๋ฐ˜์‘ํ˜•์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋Œ€๋ถ€๋ถ„์˜ React ๊ฐœ๋ฐœ์ž๋Š” React์˜ ์˜คํ”„์Šคํฌ๋ฆฐ API์™€ ์ง์ ‘ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€๋Š” ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€์‹ , ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋”๋ง์€ ๋ผ์šฐํ„ฐ๋‚˜ UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๊ฒฐํ•ฉํ•  ๊ฒƒ์ด๋ฉฐ, ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋Š” ์ถ”๊ฐ€์ ์ธ ์ž‘์—… ์—†์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ด์ ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -ํ•ต์‹ฌ์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฉด์„œ ์–ด๋– ํ•œ React ํŠธ๋ฆฌ๋ผ๋„ ์˜คํ”„์Šคํฌ๋ฆฐ์—์„œ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ์˜คํ”„์Šคํฌ๋ฆฐ์—์„œ ๋ Œ๋”๋งํ•  ๋•Œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ณด์ด๊ธฐ ์ „๊นŒ์ง€ ์‹ค์ œ๋กœ *๋งˆ์šดํŠธ*ํ•˜์ง€ ์•Š์œผ๋ฉฐ effect๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋กœ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋‚˜ํƒ€๋‚  ๋•Œ `useEffect`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ„์„ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๋Š” ๊ฒฝ์šฐ, ์‚ฌ์ „ ๋ Œ๋”๋ง์„ ํ•˜๋Š” ๊ฒƒ์ด ๋ถ„์„์˜ ์ •ํ™•๋„๋ฅผ ์†์ƒํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์˜คํ”„์Šคํฌ๋ฆฐ์œผ๋กœ ์ „ํ™˜ํ•  ๋•Œ ๊ทธ ์ปดํฌ๋„ŒํŠธ์˜ effect ๋˜ํ•œ ๋งˆ์šดํŠธ๊ฐ€ ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค. ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋”๋ง์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์€ ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐ€์‹œ์„ฑ์„ ์ „ํ™˜ํ•˜๋ฉด์„œ๋„ ๊ทธ state๋ฅผ ์žƒ์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์— ์žˆ์Šต๋‹ˆ๋‹ค. +ํ•ต์‹ฌ์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฉด์„œ ์–ด๋– ํ•œ React ํŠธ๋ฆฌ๋ผ๋„ ์˜คํ”„์Šคํฌ๋ฆฐ์—์„œ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ์˜คํ”„์Šคํฌ๋ฆฐ์—์„œ ๋ Œ๋”๋งํ•  ๋•Œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ณด์ด๊ธฐ ์ „๊นŒ์ง€ ์‹ค์ œ๋กœ *๋งˆ์šดํŠธ*ํ•˜์ง€ ์•Š์œผ๋ฉฐ Effect๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋กœ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋‚˜ํƒ€๋‚  ๋•Œ `useEffect`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ„์„ ๋กœ๊ทธ๋ฅผ ๋‚จ๊ธฐ๋Š” ๊ฒฝ์šฐ, ์‚ฌ์ „ ๋ Œ๋”๋ง์„ ํ•˜๋Š” ๊ฒƒ์ด ๋ถ„์„์˜ ์ •ํ™•๋„๋ฅผ ์†์ƒํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์˜คํ”„์Šคํฌ๋ฆฐ์œผ๋กœ ์ „ํ™˜ํ•  ๋•Œ ๊ทธ ์ปดํฌ๋„ŒํŠธ์˜ Effect ๋˜ํ•œ ๋งˆ์šดํŠธ ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค. ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋”๋ง์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์€ ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐ€์‹œ์„ฑ์„ ์ „ํ™˜ํ•˜๋ฉด์„œ๋„ ๊ทธ State๋ฅผ ์žƒ์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์— ์žˆ์Šต๋‹ˆ๋‹ค. -์ง€๋‚œ ์—…๋ฐ์ดํŠธ ์ดํ›„ Meta ๋‚ด๋ถ€์—์„œ๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ์™€ iOS์˜ React Native ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‹คํ—˜์ ์ธ ๋ฒ„์ „์˜ ์‚ฌ์ „ ๋ Œ๋”๋ง์„ ํ…Œ์ŠคํŠธํ•˜์˜€์œผ๋ฉฐ, ๊ธ์ •์ ์ธ ์„ฑ๋Šฅ ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋”๋ง์ด Suspense์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹๋„ ๊ฐœ์„ ํ•˜์—ฌ ์˜คํ”„์Šคํฌ๋ฆฐ ํŠธ๋ฆฌ ๋‚ด๋ถ€์—์„œ๋Š” Suspense์˜ ํด๋ฐฑ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚จ์•„ ๋‚จ์•„์žˆ๋Š” ์ž‘์—…์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ œ๊ณตํ•  ๊ธฐ๋ณธ ์š”์†Œ๋ฅผ ๋งˆ๋ฌด๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ฌํ•ด ๋ง ํ…Œ์ŠคํŠธ์™€ ํ”ผ๋“œ๋ฐฑ์„ ์œ„ํ•œ ์‹คํ—˜์ ์ธ API์™€ ํ•จ๊ป˜ RFC๋ฅผ ๊ฒŒ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +์ง€๋‚œ ์—…๋ฐ์ดํŠธ ์ดํ›„ Meta ๋‚ด๋ถ€์—์„œ๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ์™€ iOS์˜ React Native ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‹คํ—˜์ ์ธ ๋ฒ„์ „์˜ ์‚ฌ์ „ ๋ Œ๋”๋ง์„ ํ…Œ์ŠคํŠธํ•˜์˜€์œผ๋ฉฐ, ๊ธ์ •์ ์ธ ์„ฑ๋Šฅ ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์˜คํ”„์Šคํฌ๋ฆฐ ๋ Œ๋”๋ง์ด Suspense์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹๋„ ๊ฐœ์„ ํ•˜์—ฌ ์˜คํ”„์Šคํฌ๋ฆฐ ํŠธ๋ฆฌ ๋‚ด๋ถ€์—์„œ๋Š” Suspense์˜ ํด๋ฐฑ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚จ์•„์žˆ๋Š” ์ž‘์—…์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์ œ๊ณตํ•  ๊ธฐ๋ณธ ์š”์†Œ๋ฅผ ๋งˆ๋ฌด๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ฌํ•ด ๋ง ํ…Œ์ŠคํŠธ์™€ ํ”ผ๋“œ๋ฐฑ์„ ์œ„ํ•œ ์‹คํ—˜์ ์ธ API์™€ ํ•จ๊ป˜ RFC๋ฅผ ๊ฒŒ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ## ํŠธ๋žœ์ง€์…˜ ์ถ”์  {/*transition-tracing*/} From 0a4115472491c3aad43edad625a16be3ad36fbd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 21:20:31 +0900 Subject: [PATCH 0359/1059] docs: update `react-canaries.md` --- src/content/blog/2023/05/03/react-canaries.md | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/content/blog/2023/05/03/react-canaries.md b/src/content/blog/2023/05/03/react-canaries.md index cb1666447..56bc2ef3f 100644 --- a/src/content/blog/2023/05/03/react-canaries.md +++ b/src/content/blog/2023/05/03/react-canaries.md @@ -1,5 +1,5 @@ --- -title: "React Canaries: Meta ์™ธ๋ถ€์—์„œ ์ ์ง„์  ๊ธฐ๋Šฅ ๋กค์•„์›ƒ ํ™œ์„ฑํ™”ํ•˜๊ธฐ" +title: "React Canary: Meta ์™ธ๋ถ€์—์„œ ์ ์ง„์  ๊ธฐ๋Šฅ ๋กค์•„์›ƒ ํ™œ์„ฑํ™”ํ•˜๊ธฐ" author: Dan Abramov, Sophie Alpert, Rick Hanlon, Sebastian Markbage, and Andrew Clark date: 2023/05/03 description: Meta๊ฐ€ ์˜ค๋žซ๋™์•ˆ ๋‚ด๋ถ€์ ์œผ๋กœ ์ตœ์ฒจ๋‹จ ๋ฒ„์ „์˜ React๋ฅผ ์‚ฌ์šฉํ•ด ์˜จ ๊ฒƒ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ, ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์•ˆ์ •๋œ ๋ฒ„์ „์œผ๋กœ ์ถœ์‹œ๋˜๊ธฐ ์ „์— ๋””์ž์ธ์ด ๊ฑฐ์˜ ์™„์„ฑ๋˜๋Š” ์ฆ‰์‹œ ๊ฐœ๋ณ„์ ์ธ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์„ React ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์ œ๊ณตํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” ์ƒˆ๋กœ์šด Canary ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ฐ™์ด ์—„์„ ๋œ ์„ค์ •์„ ํ†ตํ•ด ๊ฐœ๋ณ„ React ๊ธฐ๋Šฅ์˜ ์ฑ„ํƒ์„ React ๋ฆด๋ฆฌ์ฆˆ ์ผ์ •์—์„œ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -17,22 +17,22 @@ Meta๊ฐ€ ์˜ค๋žซ๋™์•ˆ ๋‚ด๋ถ€์ ์œผ๋กœ ์ตœ์ฒจ๋‹จ ๋ฒ„์ „์˜ React๋ฅผ ์‚ฌ์šฉํ•ด ์˜จ --- -## tl;dr {/*tldr*/} +## ์š”์•ฝ {/*tldr*/} -* ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” React์šฉ [Canary ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„](/community/versioning-policy#canary-channel)์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ๊ณต์‹์ ์œผ๋กœ ์ง€์›๋˜๋ฏ€๋กœ ํšŒ๊ท€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์•ˆ์ •๋œ ๋ฆด๋ฆฌ์ฆˆ์˜ ๋ฒ„๊ทธ์™€ ๋น„์Šทํ•œ ์ˆ˜์ค€์œผ๋กœ ๊ธด๊ธ‰ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. -* Canaries๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Semantic Versioning์— ์•ˆ์ •๋œ ๋ฆด๋ฆฌ์ฆˆ์— ์ ์šฉ๋˜๊ธฐ ์ „์— ๊ฐœ๋ณ„์ ์ธ ์ƒˆ๋กœ์šด React ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -* [์‹คํ—˜](/community/versioning-policy#experimental-channel) ์ฑ„๋„๊ณผ ๋‹ฌ๋ฆฌ, React Canaries์—๋Š” ์ฑ„ํƒํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ํ•ฉ๋ฆฌ์ ์œผ๋กœ ํŒ๋‹จ๋˜๋Š” ๊ธฐ๋Šฅ๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๊ณ ์ •๋œ Canary React ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ๋ฒˆ๋“ค๋กœ ๋ฌถ๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. +* ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” React์šฉ [Canary ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„](/community/versioning-policy#canary-channel)์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜๋ฏ€๋กœ ํšŒ๊ท€<sup>Regression</sup> ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์•ˆ์ •๋œ ๋ฆด๋ฆฌ์ฆˆ์˜ ๋ฒ„๊ทธ์™€ ๋น„์Šทํ•œ ์ˆ˜์ค€์œผ๋กœ ๊ธด๊ธ‰ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +* Canary๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Semantic Versioning์˜ ์•ˆ์ •๋œ ๋ฆด๋ฆฌ์ฆˆ์— ์ ์šฉ๋˜๊ธฐ ์ „์— ๊ฐœ๋ณ„์ ์ธ ์ƒˆ๋กœ์šด React ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* [์‹คํ—˜์  ์ฑ„๋„](/community/versioning-policy#experimental-channel)๊ณผ ๋‹ฌ๋ฆฌ, React Canary์—๋Š” ์ฑ„ํƒํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ํ•ฉ๋ฆฌ์ ์œผ๋กœ ํŒ๋‹จ๋˜๋Š” ๊ธฐ๋Šฅ๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๊ณ ์ •๋œ Canary React ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ๋ฒˆ๋“ค๋กœ ๋ฌถ๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. * ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๊ณผ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด Canary ๋ฆด๋ฆฌ์ฆˆ์— ์ ์šฉ๋˜๋ฉด ๋ธ”๋กœ๊ทธ์— ๊ณต์ง€ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -* **์–ธ์ œ๋‚˜ ๊ทธ๋ ‡๋“ฏ์ด React๋Š” ๋ชจ๋“  ์•ˆ์ •๋œ ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•ด Semantic Versioning์„ ๊ณ„์† ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.** +* **์–ธ์ œ๋‚˜ ๊ทธ๋ ‡๋“ฏ์ด React๋Š” ๋ชจ๋“  ์•ˆ์ •๋œ ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•ด Semantic Versioning์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.** ## React ๊ธฐ๋Šฅ์€ ๋ณดํ†ต ์–ด๋–ป๊ฒŒ ๊ฐœ๋ฐœ๋˜๋‚˜์š”? {/*how-react-features-are-usually-developed*/} ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  React ๊ธฐ๋Šฅ์€ ๋™์ผํ•œ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นฉ๋‹ˆ๋‹ค. 1. ์ดˆ๊ธฐ ๋ฒ„์ „์„ ๊ฐœ๋ฐœํ•˜๊ณ  `experimental_` ๋˜๋Š” `unstable_`์ ‘๋‘์‚ฌ๋ฅผ ๋ถ™์ž…๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ `experimental` ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์‹œ์ ์—์„œ ์ด ๊ธฐ๋Šฅ์€ ํฌ๊ฒŒ ๋ณ€๊ฒฝ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. -2. ์ด ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค„ Meta ํŒ€์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ์ด ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ธฐ๋Šฅ์ด ๋ณ€๊ฒฝ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์ด ์•ˆ์ •ํ™”๋จ์— ๋”ฐ๋ผ Meta์˜ ๋” ๋งŽ์€ ํŒ€๊ณผ ํ˜‘๋ ฅํ•˜์—ฌ ์ด ๊ธฐ๋Šฅ์„ ์‹œํ—˜ํ•ด ๋ด…๋‹ˆ๋‹ค. -3. ๊ฒฐ๊ตญ ๋””์ž์ธ์— ์ž์‹ ๊ฐ์ด ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. API ์ด๋ฆ„์—์„œ ์ ‘๋‘์‚ฌ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋Œ€๋ถ€๋ถ„์˜ Meta ์ œํ’ˆ์ด ์‚ฌ์šฉํ•˜๋Š” `main` ๋ธŒ๋žœ์น˜์—์„œ ์ด ๊ธฐ๋Šฅ์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ Meta์˜ ๋ชจ๋“  ํŒ€์ด ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -4. ๋ฐฉํ–ฅ์— ๋Œ€ํ•œ ํ™•์‹ ์ด ์ƒ๊ธฐ๋ฉด ์ƒˆ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ RFC๋„ ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ์‹œ์ ์—์„œ ์šฐ๋ฆฌ๋Š” ์ด ๋””์ž์ธ์ด ๊ด‘๋ฒ”์œ„ํ•œ ์‚ฌ๋ก€์— ์ ํ•ฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ, ๋งˆ์ง€๋ง‰ ์ˆœ๊ฐ„์— ๋ช‡ ๊ฐ€์ง€ ์กฐ์ •์„ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +2. ์ด ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค„ Meta ํŒ€์„ ์ฐพ์Šต๋‹ˆ๋‹ค. ์ด ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ธฐ๋Šฅ์ด ๋ณ€๊ฒฝ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์ด ์•ˆ์ •ํ™”๋จ์— ๋”ฐ๋ผ Meta์˜ ๋” ๋งŽ์€ ํŒ€๊ณผ ํ˜‘๋ ฅํ•˜์—ฌ ์ด ๊ธฐ๋Šฅ์„ ์‹œํ—˜ํ•ด ๋ด…๋‹ˆ๋‹ค. +3. ์ตœ์ข…์ ์œผ๋กœ ์„ค๊ณ„์— ์ž์‹ ๊ฐ์ด ์ƒ๊ธฐ๋ฉด, API ์ด๋ฆ„์—์„œ ์ ‘๋‘์‚ฌ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋Œ€๋ถ€๋ถ„์˜ Meta ์ œํ’ˆ์ด ์‚ฌ์šฉํ•˜๋Š” `main` ๋ธŒ๋žœ์น˜์—์„œ ์ด ๊ธฐ๋Šฅ์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ Meta์˜ ๋ชจ๋“  ํŒ€์ด ์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +4. ๋ฐฉํ–ฅ์— ๋Œ€ํ•œ ํ™•์‹ ์ด ์ƒ๊ธฐ๋ฉด ์ƒˆ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ RFC๋„ ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ์„ค๊ณ„๊ฐ€ ๊ด‘๋ฒ”์œ„ํ•œ ์‚ฌ๋ก€์— ์ ํ•ฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์ด ์‹œ์ ์— ์•Œ๊ณ  ์žˆ์ง€๋งŒ, ๋งˆ์ง€๋ง‰ ์ˆœ๊ฐ„์— ๋ช‡ ๊ฐ€์ง€ ์กฐ์ •์„ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. 5. ์˜คํ”ˆ ์†Œ์Šค ๋ฆด๋ฆฌ์ฆˆ์— ๊ฐ€๊นŒ์›Œ์ง€๋ฉด ํ•ด๋‹น ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์ตœ์ข…์ ์œผ๋กœ ์•ˆ์ •๋œ React ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ํ†ตํ•ด ๊ธฐ๋Šฅ์„ ์ถœ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ํ”Œ๋ ˆ์ด๋ถ์€ ์ง€๊ธˆ๊นŒ์ง€ ์ถœ์‹œ๋œ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ค€๋น„๊ฐ€ ๋œ ์‹œ์ (3๋‹จ๊ณ„)๊ณผ ์˜คํ”ˆ ์†Œ์Šค๋กœ ๊ณต๊ฐœ๋˜๋Š” ์‹œ์ (5๋‹จ๊ณ„) ์‚ฌ์ด์—๋Š” ์ƒ๋‹นํ•œ ์ฐจ์ด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -51,11 +51,11 @@ Meta์—์„œ๋Š” `main` ๋ธŒ๋žœ์น˜์—์„œ React๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ๋งค์ฃผ ํŠน์ • ๊ณ ์ • ์šฐ๋ฆฌ๋Š” ์ด ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ์„ ๋ณ„๋œ ์„ค์ •์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ํ”Œ๋กœ์šฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด React๋ฅผ *๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š”* ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์•ˆ์ •๋œ React ๋ฆด๋ฆฌ์ฆˆ์— ํฌํ•จ๋˜๊ธฐ *์ „์—* React์™€ ๊ด€๋ จ๋œ ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ํ”„๋ ˆ์ž„์›Œํฌ ํ†ตํ•ฉ์—๋งŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ธฐ๋Šฅ์€ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ”„๋ ˆ์ž„์›Œํฌ๋Š” Semantic Versioning์„ ์ค‘๋‹จ์‹œํ‚ค์ง€ ์•Š๊ณ  ์ž์ฒด ๋งˆ์ด๋„ˆ ๋ฒ„์ „์—์„œ ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฆด๋ฆฌ์ฆˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -Canaries ์ฑ„๋„์„ ํ†ตํ•œ ๋กค๋ง ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ํ†ตํ•ด ๋”์šฑ ๊ธด๋ฐ€ํ•œ ํ”ผ๋“œ๋ฐฑ ๋ฃจํ”„๋ฅผ ํ™•๋ณดํ•˜๊ณ  ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ํฌ๊ด„์ ์ธ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์น˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์›Œํฌํ”Œ๋กœ์šฐ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ‘œ์ค€ ์œ„์›ํšŒ์ธ TC39๊ฐ€ [๋ฒˆํ˜ธ๊ฐ€ ๋งค๊ฒจ์ง„ ๋‹จ๊ณ„๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ฒ˜๋ฆฌ](https://tc39.es/process-document/)ํ•˜๋Š” ๋ฐฉ์‹์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด JavaScript ๊ธฐ๋Šฅ์ด ๋ช…์„ธ์˜ ์ผ๋ถ€๋กœ ๊ณต์‹์ ์œผ๋กœ ์Šน์ธ๋˜๊ธฐ ์ „์— ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์ƒˆ๋กœ์šด React ๊ธฐ๋Šฅ์€ React ์•ˆ์ • ๋ฆด๋ฆฌ์ฆˆ์— ํฌํ•จ๋˜๊ธฐ ์ „์— React๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•๋œ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +Canary ์ฑ„๋„์„ ํ†ตํ•œ ๋กค๋ง ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ํ†ตํ•ด ๋”์šฑ ๊ธด๋ฐ€ํ•œ ํ”ผ๋“œ๋ฐฑ ๋ฃจํ”„๋ฅผ ํ™•๋ณดํ•˜๊ณ  ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ํฌ๊ด„์ ์ธ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์น˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์›Œํฌํ”Œ๋กœ์šฐ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ‘œ์ค€ ์œ„์›ํšŒ์ธ TC39๊ฐ€ [๋ฒˆํ˜ธ๊ฐ€ ๋งค๊ฒจ์ง„ ๋‹จ๊ณ„๋กœ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ฒ˜๋ฆฌ](https://tc39.es/process-document/)ํ•˜๋Š” ๋ฐฉ์‹์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋Šฅ์ด ๋ช…์„ธ์˜ ์ผ๋ถ€๋กœ ๊ณต์‹์ ์œผ๋กœ ์Šน์ธ๋˜๊ธฐ ์ „์— ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์ƒˆ๋กœ์šด React ๊ธฐ๋Šฅ์€ React ์•ˆ์ • ๋ฆด๋ฆฌ์ฆˆ์— ํฌํ•จ๋˜๊ธฐ ์ „์— React๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•๋œ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## ์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”? {/*why-not-use-experimental-releases-instead*/} -๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” [Experimental releases](/community/versioning-policy#canary-channel)๋ฅผ ์‚ฌ์šฉ*ํ•  ์ˆ˜* ์žˆ์ง€๋งŒ, ์‹คํ—˜์  API๋Š” ์•ˆ์ •ํ™” ๊ณผ์ •์—์„œ ์ค‘๋Œ€ํ•œ ๋ณ€๊ฒฝ์ด ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ(๋˜๋Š” ์‹ฌ์ง€์–ด ์™„์ „ํžˆ ์ œ๊ฑฐ๋  ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ) ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. Canaries์—๋„ ์‹ค์ˆ˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ(๋‹ค๋ฅธ ๋ฆด๋ฆฌ์ฆˆ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ), ์•ž์œผ๋กœ๋Š” Canaries์— ์ค‘๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฉด ๋ธ”๋กœ๊ทธ์— ๊ณต์ง€ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. Canaries๋Š” Meta๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ์— ๊ฐ€์žฅ ๊ฐ€๊น๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜์ ์œผ๋กœ ๋น„๊ต์  ์•ˆ์ •์ ์ผ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฒ„์ „์„ ๊ณ ์ •*ํ•˜๊ณ * ๊ณ ์ •๋œ ์ปค๋ฐ‹ ์‚ฌ์ด๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ๋Š” GitHub ์ปค๋ฐ‹ ๋กœ๊ทธ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์Šค์บ”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” [์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ](/community/versioning-policy#canary-channel)๋ฅผ ์‚ฌ์šฉ*ํ•  ์ˆ˜* ์žˆ์ง€๋งŒ, ์‹คํ—˜์  API๋Š” ์•ˆ์ •ํ™” ๊ณผ์ •์—์„œ ์ค‘๋Œ€ํ•œ ๋ณ€๊ฒฝ์ด ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ(๋˜๋Š” ์‹ฌ์ง€์–ด ์™„์ „ํžˆ ์ œ๊ฑฐ๋  ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ) ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. Canary์—๋„ ์‹ค์ˆ˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ(๋‹ค๋ฅธ ๋ฆด๋ฆฌ์ฆˆ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ), ์•ž์œผ๋กœ๋Š” Canary์— ์ค‘๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฉด ๋ธ”๋กœ๊ทธ์— ๊ณต์ง€ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. Canary๋Š” Meta๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ์— ๊ฐ€์žฅ ๊ฐ€๊น๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜์ ์œผ๋กœ ๋น„๊ต์  ์•ˆ์ •์ ์ผ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฒ„์ „์„ ๊ณ ์ •*ํ•˜๊ณ * ๊ณ ์ •๋œ ์ปค๋ฐ‹ ์‚ฌ์ด๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ๋Š” GitHub ์ปค๋ฐ‹ ๋กœ๊ทธ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์Šค์บ”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. **ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ฐ™์ด ์—„์„ ๋œ ํ™˜๊ฒฝ ๋ฐ–์—์„œ React๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€๋ถ€๋ถ„ ์‚ฌ๋žŒ์€ Stable ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค.** ํ•˜์ง€๋งŒ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒฝ์šฐ ํŠน์ • ์ปค๋ฐ‹์— ๊ณ ์ •๋œ React์˜ Canary ๋ฒ„์ „์„ ๋ฒˆ๋“ค๋กœ ๋ฌถ์–ด ์›ํ•˜๋Š” ์†๋„๋กœ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์˜ ์žฅ์ ์€ ์ง€๋‚œ ๋ช‡ ๋…„ ๋™์•ˆ React Native๊ฐ€ ํ•ด์™”๋˜ ๋ฐฉ์‹๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ, ์™„์„ฑ๋œ ๊ฐœ๋ณ„ React ๊ธฐ๋Šฅ ๋ฐ ๋ฒ„๊ทธ ์ˆ˜์ •์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋” ์ผ์ฐ, ์ž์ฒด ๋ฆด๋ฆฌ์ฆˆ ์ผ์ •์— ๋งž์ถฐ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹จ์ ์€ ์–ด๋–ค React ์ปค๋ฐ‹์„ ๊ฐ€์ ธ์˜ค๋Š”์ง€ ๊ฒ€ํ† ํ•˜๊ณ  ๋ฆด๋ฆฌ์ฆˆ์— ์–ด๋–ค React ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํฌํ•จ๋˜์—ˆ๋Š”์ง€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ฆฌ๋Š” ์ถ”๊ฐ€์ ์ธ ์ฑ…์ž„์„ ์ ธ์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. @@ -65,27 +65,27 @@ Canaries ์ฑ„๋„์„ ํ†ตํ•œ ๋กค๋ง ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ํ†ตํ•ด ๋”์šฑ ๊ธด๋ฐ€ํ•œ ํ”ผ๋“œ๋ฐฑ Canary ๋ฆด๋ฆฌ์ฆˆ๋Š” ํŠน์ • ์‹œ์ ์— ๋‹ค์Œ ์•ˆ์ •๋œ React ๋ฆด๋ฆฌ์ฆˆ์— ํฌํ•จ๋  ๋‚ด์šฉ์— ๋Œ€ํ•œ ์ตœ์„ ์˜ ์ถ”์ธก์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. -๊ธฐ์กด์—๋Š” ๋ฆด๋ฆฌ์ฆˆ ์ฃผ๊ธฐ๊ฐ€ *๋*๋‚  ๋•Œ(์ฃผ์š” ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ํ•  ๋•Œ)๋งŒ ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ Canary ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” React ์‚ฌ์šฉ ๋ฐฉ์‹์ด ๋˜์—ˆ์œผ๋ฏ€๋กœ, ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๊ณผ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด Canaries์— *์ ์šฉ๋  ๋•Œ* ๋ฐœํ‘œํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ „ํ™˜ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Canary์— ์ถœ์‹œ๋  ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ณ‘ํ•ฉํ•˜๋Š” ๊ฒฝ์šฐ, ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ฝ”๋“œ๋ชจ๋“œ ๋ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ง€์นจ์„ ํฌํ•จํ•˜์—ฌ React ๋ธ”๋กœ๊ทธ์— ์ด์— ๋Œ€ํ•œ ๊ฒŒ์‹œ๋ฌผ์„ ์ž‘์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ, ํ”„๋ ˆ์ž„์›Œํฌ ์ž‘์„ฑ์ž๊ฐ€ ํ•ด๋‹น ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํฌํ•จํ•˜๋„๋ก ๊ณ ์ •๋œ React Canary๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ์ฃผ์š” ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์ž๋ฅด๋Š” ๊ฒฝ์šฐ ๋ฆด๋ฆฌ์ฆˆ ๋…ธํŠธ์—์„œ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ๋กœ ๋งํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, ์•ˆ์ •๋œ ์ฃผ์š” ๋ฒ„์ „์˜ React๊ฐ€ ์ค€๋น„๋˜๋ฉด ์ด๋ฏธ ๊ฒŒ์‹œ๋œ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์— ๋งํฌํ•˜์—ฌ ํŒ€์ด ๋” ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. +๊ธฐ์กด์—๋Š” ๋ฆด๋ฆฌ์ฆˆ ์ฃผ๊ธฐ๊ฐ€ *๋*๋‚  ๋•Œ(์ฃผ์š” ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ํ•  ๋•Œ)๋งŒ ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ Canary ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” React์˜ ์‚ฌ์šฉ ๋ฐฉ์‹์ด ๋˜์—ˆ์œผ๋ฏ€๋กœ, ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๊ณผ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด Canary์— *์ ์šฉ๋  ๋•Œ* ๋ฐœํ‘œํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ „ํ™˜ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Canary์— ์ถœ์‹œ๋  ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ณ‘ํ•ฉํ•˜๋Š” ๊ฒฝ์šฐ, ํ•„์š” ์‹œ ์ฝ”๋“œ๋ชจ๋“œ ๋ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ง€์นจ์„ ํฌํ•จํ•˜์—ฌ React ๋ธ”๋กœ๊ทธ์— ์ด์— ๋Œ€ํ•œ ๊ฒŒ์‹œ๋ฌผ์„ ์ž‘์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ, ํ”„๋ ˆ์ž„์›Œํฌ ์ž‘์„ฑ์ž๊ฐ€ ํ•ด๋‹น ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํฌํ•จํ•˜๋„๋ก ๊ณ ์ •๋œ React Canary๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ์ฃผ์š” ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์ž๋ฅด๋Š” ๊ฒฝ์šฐ ๋ฆด๋ฆฌ์ฆˆ ๋…ธํŠธ์—์„œ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ๋กœ ๋งํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, ์•ˆ์ •๋œ ์ฃผ์š” ๋ฒ„์ „์˜ React๊ฐ€ ์ค€๋น„๋˜๋ฉด ์ด๋ฏธ ๊ฒŒ์‹œ๋œ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์— ๋งํฌํ•˜์—ฌ ํŒ€์ด ๋” ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. -์•„์ง Canaries ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” API๋ผ๋„ Canaries์— ์ถœ์‹œํ•˜๋Š” ๋Œ€๋กœ ๋ฌธ์„œํ™”ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. Canaries์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” API๋Š” ํ•ด๋‹น ํŽ˜์ด์ง€์— ํŠน๋ณ„ ๋ฉ”๋ชจ๋กœ ํ‘œ์‹œ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” [`use`](https://github.com/reactjs/rfcs/pull/229)์™€ ๊ฐ™์€ API์™€ ์ผ๋ถ€ ๋‹ค๋ฅธ API(์˜ˆ์‹œ: `cache` ๋ฐ `createServerContext`)๊ฐ€ ํฌํ•จ๋˜๋ฉฐ, ์ด์— ๋Œ€ํ•œ RFC๋ฅผ ๋ณด๋‚ด๋“œ๋ฆด ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +์•„์ง Canary ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” API๋ผ๋„ Canary์— ์ถœ์‹œํ•˜๋Š” ๋Œ€๋กœ ๋ฌธ์„œํ™”ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. Canary์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” API๋Š” ํ•ด๋‹น ํŽ˜์ด์ง€์— ํŠน๋ณ„ ๋ฉ”๋ชจ๋กœ ํ‘œ์‹œ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” [`use`](https://github.com/reactjs/rfcs/pull/229)์™€ ๊ฐ™์€ API์™€ ์ผ๋ถ€ ๋‹ค๋ฅธ API(์˜ˆ์‹œ: `cache` ๋ฐ `createServerContext`)๊ฐ€ ํฌํ•จ๋˜๋ฉฐ, ์ด์— ๋Œ€ํ•œ RFC๋ฅผ ๋ณด๋‚ด๋“œ๋ฆด ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. -## Canaries๋Š” ๋ฐ˜๋“œ์‹œ ๊ณ ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. {/*canaries-must-be-pinned*/} +## Canary๋Š” ๋ฐ˜๋“œ์‹œ ๊ณ ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. {/*canaries-must-be-pinned*/} -์•ฑ์ด๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ์— Canary ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์ฑ„ํƒํ•˜๊ธฐ๋กœ ํ•œ ๊ฒฝ์šฐ ํ•ญ์ƒ ์‚ฌ์šฉ ์ค‘์ธ Canary์˜ *์ •ํ™•ํ•œ* ๋ฒ„์ „์„ ๊ณ ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Canaries๋Š” ์‚ฌ์ „ ๋ฆด๋ฆฌ์ฆˆ์ด๋ฏ€๋กœ ์—ฌ์ „ํžˆ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์•ฑ์ด๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ์— Canary ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์ฑ„ํƒํ•˜๊ธฐ๋กœ ํ•œ ๊ฒฝ์šฐ ํ•ญ์ƒ ์‚ฌ์šฉ ์ค‘์ธ Canary์˜ *์ •ํ™•ํ•œ* ๋ฒ„์ „์„ ๊ณ ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Canary๋Š” ์‚ฌ์ „ ๋ฆด๋ฆฌ์ฆˆ์ด๋ฏ€๋กœ ์—ฌ์ „ํžˆ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -## ์˜ˆ์‹œ: React Server ์ปดํฌ๋„ŒํŠธ {/*example-react-server-components*/} +## ์˜ˆ์‹œ: React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ {/*example-react-server-components*/} -์ง€๋‚œ [3์›”์— ๋ฐœํ‘œํ–ˆ๋“ฏ์ด](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components) React Server ์ปดํฌ๋„ŒํŠธ ์ปจ๋ฒค์…˜์€ ํ™•์ •๋˜์—ˆ์œผ๋ฉฐ, ์‚ฌ์šฉ์ž ๋Œ€๋ฉด API ๊ณ„์•ฝ๊ณผ ๊ด€๋ จ๋œ ์ค‘๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์—†์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์„œ๋กœ ์–ฝํ˜€ ์žˆ๋Š” ์—ฌ๋Ÿฌ ํ”„๋ ˆ์ž„์›Œํฌ ์ „์šฉ ๊ธฐ๋Šฅ([์—์…‹ ๋กœ๋”ฉ](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#asset-loading)๊ณผ ๊ฐ™์€)์— ๋Œ€ํ•œ ์ž‘์—…์ด ์ง„ํ–‰ ์ค‘์ด๋ฉฐ, ๋” ๋งŽ์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์•„์ง ์•ˆ์ •๋œ ๋ฒ„์ „์˜ React์—์„œ React Server ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ง€์›์„ ๋ฆด๋ฆฌ์ฆˆํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. +์ง€๋‚œ [3์›”์— ๋ฐœํ‘œํ–ˆ๋“ฏ์ด](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components) React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์ปจ๋ฒค์…˜์€ ํ™•์ •๋˜์—ˆ์œผ๋ฉฐ, ์‚ฌ์šฉ์ž ๋Œ€๋ฉด API ๊ณ„์•ฝ๊ณผ ๊ด€๋ จ๋œ ์ค‘๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์—†์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์„œ๋กœ ์–ฝํ˜€ ์žˆ๋Š” ์—ฌ๋Ÿฌ ํ”„๋ ˆ์ž„์›Œํฌ ์ „์šฉ ๊ธฐ๋Šฅ([์—์…‹ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#asset-loading)์™€ ๊ฐ™์€)์— ๋Œ€ํ•œ ์ž‘์—…์ด ์ง„ํ–‰ ์ค‘์ด๋ฉฐ, ๋” ๋งŽ์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์•„์ง ์•ˆ์ •๋œ ๋ฒ„์ „์˜ React์—์„œ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ง€์›์„ ๋ฆด๋ฆฌ์ฆˆํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. -์ฆ‰, React Server ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ”„๋ ˆ์ž„์›Œํฌ์— ์ฑ„ํƒ๋  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์Œ ์ฃผ์š” React ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ๋‚˜์˜ฌ ๋•Œ๊นŒ์ง€ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ด๋ฅผ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ๊ณ ์ •๋œ Canary ๋ฒ„์ „์˜ React๋ฅผ ์ถœ์‹œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. (๋‘ ๊ฐœ์˜ React ๋ณต์‚ฌ๋ณธ์ด ๋ฒˆ๋“ค๋กœ ์ œ๊ณต๋˜๋Š” ๊ฒƒ์„ ํ”ผํ•˜๊ณ ์ž, ์ด๋ฅผ ์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์™€ ํ•จ๊ป˜ ์ œ๊ณตํ•˜๋Š” ๊ณ ์ •๋œ Canary์— `react` ๋ฐ `react-dom`์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ ์šฉํ•˜๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ์ด๋ฅผ ์„ค๋ช…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด๊ฒƒ์ด Next.js App Router๊ฐ€ ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค.) +์ฆ‰, React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ”„๋ ˆ์ž„์›Œํฌ์— ์ฑ„ํƒ๋  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์Œ ์ฃผ์š” React ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ๋‚˜์˜ฌ ๋•Œ๊นŒ์ง€ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ด๋ฅผ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ๊ณ ์ •๋œ Canary ๋ฒ„์ „์˜ React๋ฅผ ์ถœ์‹œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. (๋‘ ๊ฐœ์˜ React ๋ณต์‚ฌ๋ณธ์ด ๋ฒˆ๋“ค๋กœ ์ œ๊ณต๋˜๋Š” ๊ฒƒ์„ ํ”ผํ•˜๊ณ ์ž, ์ด๋ฅผ ์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์™€ ํ•จ๊ป˜ ์ œ๊ณตํ•˜๋Š” ๊ณ ์ •๋œ Canary์— `react` ๋ฐ `react-dom`์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ ์šฉํ•˜๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ์ด๋ฅผ ์„ค๋ช…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด๊ฒƒ์ด Next.js App Router๊ฐ€ ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค.) ## Stable ๋ฐ Canary ๋ฒ„์ „ ๋ชจ๋‘์— ๋Œ€ํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ…Œ์ŠคํŠธํ•˜๊ธฐ {/*testing-libraries-against-both-stable-and-canary-versions*/} -๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๊ฐ€ ๋ชจ๋“  Canary ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์€ ์—„์ฒญ๋‚˜๊ฒŒ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ [3๋…„ ์ „ ๋‹ค์–‘ํ•œ React ์‚ฌ์ „ ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„์„ ์ฒ˜์Œ ๋„์ž…ํ–ˆ์„ ๋•Œ](https://legacy.reactjs.org/blog/2019/10/22/react-release-channels.html)์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๋Š” ์ตœ์‹  Stable ๋ฒ„์ „๊ณผ ์ตœ์‹  Canary ๋ฒ„์ „ *๋ชจ๋‘*์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฐœํ‘œ๋˜์ง€ ์•Š์€ ๋™์ž‘์˜ ๋ณ€ํ™”๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ๊ฒฝ์šฐ, ์ง„๋‹จ์— ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋„๋ก React ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— ๋ฒ„๊ทธ๋ฅผ ์ œ์ถœํ•ด ์ฃผ์„ธ์š”. ์ด ๊ด€ํ–‰์ด ๋„๋ฆฌ ์ฑ„ํƒ๋˜๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ถœ์‹œ๋  ๋•Œ ์šฐ๋ฐœ์ ์ธ ํšŒ๊ท€๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ƒˆ๋กœ์šด ์ฃผ์š” ๋ฒ„์ „์˜ React๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋…ธ๋ ฅ์ด ์ค„์–ด๋“ค ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. +๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๊ฐ€ ๋ชจ๋“  Canary ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์€ ์—„์ฒญ๋‚˜๊ฒŒ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ๊ธฐ๋Œ€ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ [3๋…„ ์ „ ๋‹ค์–‘ํ•œ React ์‚ฌ์ „ ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„์„ ์ฒ˜์Œ ๋„์ž…ํ–ˆ์„ ๋•Œ](https://legacy.reactjs.org/blog/2019/10/22/react-release-channels.html)์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๋Š” ์ตœ์‹  Stable ๋ฒ„์ „๊ณผ ์ตœ์‹  Canary ๋ฒ„์ „ *๋ชจ๋‘*์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ๋ฐœํ‘œ๋˜์ง€ ์•Š์€ ๋™์ž‘์˜ ๋ณ€ํ™”๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ๊ฒฝ์šฐ, ์ง„๋‹จ์— ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋„๋ก React ์ €์žฅ์†Œ์— ๋ฒ„๊ทธ๋ฅผ ์ œ์ถœํ•ด ์ฃผ์„ธ์š”. ์ด ๊ด€ํ–‰์ด ๋„๋ฆฌ ์ฑ„ํƒ๋˜๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ถœ์‹œ๋  ๋•Œ ์šฐ๋ฐœ์ ์ธ ํšŒ๊ท€๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ƒˆ๋กœ์šด ์ฃผ์š” ๋ฒ„์ „์˜ React๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋…ธ๋ ฅ์ด ์ค„์–ด๋“ค ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. <Note> -์—„๋ฐ€ํžˆ ๋งํ•˜๋ฉด, Canary๋Š” *์ƒˆ๋กœ์šด* ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„์ด ์•„๋‹ˆ๋ฉฐ ์ด์ „์—๋Š” Next๋ผ๊ณ  ๋ถˆ๋ €์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Next.js์™€์˜ ํ˜ผ๋™์„ ํ”ผํ•˜๊ณ ์ž ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” React ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์ธ Canaries์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Œ€์น˜๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด *์ƒˆ๋กœ์šด* ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„๋กœ ๋ฐœํ‘œํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +์—„๋ฐ€ํžˆ ๋งํ•˜๋ฉด, Canary๋Š” *์ƒˆ๋กœ์šด* ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„์ด ์•„๋‹ˆ๋ฉฐ ์ด์ „์—๋Š” Next๋ผ๊ณ  ๋ถˆ๋ €์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Next.js์™€์˜ ํ˜ผ๋™์„ ํ”ผํ•˜๊ณ ์ž ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” React ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์ธ Canary์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Œ€์น˜๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด *์ƒˆ๋กœ์šด* ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„๋กœ ๋ฐœํ‘œํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. </Note> From 71c2f315770ef4d4f50e1b1640824bc152df49c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 21:43:31 +0900 Subject: [PATCH 0360/1059] docs: update `react-labs-what-we-have-been-working-on-february-2024.md` --- ...t-we-have-been-working-on-february-2024.md | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 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 f7fea38f1..2fb2cd398 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 @@ -11,7 +11,7 @@ description: React Labs ๊ฒŒ์‹œ๊ธ€์—๋Š” ํ™œ๋ฐœํžˆ ์—ฐ๊ตฌ ๊ฐœ๋ฐœ ์ค‘์ธ ํ”„๋กœ์  <Intro> -React Labs ๊ฒŒ์‹œ๊ธ€์—๋Š” ํ™œ๋ฐœํžˆ ์—ฐ๊ตฌ ๊ฐœ๋ฐœ ์ค‘์ธ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ [์ง€๋‚œ ์—…๋ฐ์ดํŠธ](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023) ์ดํ›„ ์ƒ๋‹นํ•œ ๋ฐœ์ „์„ ์ด๋ฃจ์—ˆ๊ณ , ์ด๋Ÿฌํ•œ ์ง„์ „ ์‚ฌํ•ญ์„ ๊ณต์œ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. +React Labs ๊ฒŒ์‹œ๊ธ€์—๋Š” ํ™œ๋ฐœํžˆ ์—ฐ๊ตฌ ๊ฐœ๋ฐœ ์ค‘์ธ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” [์ง€๋‚œ ์—…๋ฐ์ดํŠธ](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023) ์ดํ›„ ์ƒ๋‹นํ•œ ๋ฐœ์ „์„ ์ด๋ฃจ์—ˆ๊ณ , ์ด๋Ÿฌํ•œ ์ง„์ „ ์‚ฌํ•ญ์„ ๊ณต์œ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. </Intro> @@ -29,22 +29,22 @@ React Conf 2024๊ฐ€ 5์›” 15์ผ๋ถ€ํ„ฐ 16์ผ๊นŒ์ง€ ๋„ค๋ฐ”๋‹ค์ฃผ ํ—จ๋”์Šจ์—์„œ ๊ฐœ React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋” ์ด์ƒ ์—ฐ๊ตฌ ํ”„๋กœ์ ํŠธ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํ˜„์žฌ instagram.com์˜ ํ”„๋กœ๋•์…˜ ๋‹จ๊ณ„์—์„œ ์ž‘๋™ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, Meta์˜ ๋” ๋งŽ์€ ์„œ๋น„์Šค์— ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์ ์šฉํ•˜๊ณ  ์ฒซ ๋ฒˆ์งธ ์˜คํ”ˆ์†Œ์Šค ๋ฐฐํฌ๋ฅผ ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -[์ด์ „ ๊ฒŒ์‹œ๊ธ€](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-optimizing-compiler)์—์„œ ๋…ผ์˜ํ•œ ๋ฐ”์™€ ๊ฐ™์ด, React๋Š” state๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ *์ด๋”ฐ๊ธˆ* ๋„ˆ๋ฌด ๋งŽ์ด ๋‹ค์‹œ ๋ Œ๋”๋ง ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React ์ดˆ๊ธฐ๋ถ€ํ„ฐ ์ด๋Ÿฐ ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ํ•ด๋‹ต์€ ์ˆ˜๋™ memoization์˜€์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ API์—์„œ ์ด๋Š” [`useMemo`](/reference/react/useMemo), [`useCallback`](/reference/react/useCallback), ๊ทธ๋ฆฌ๊ณ  [`memo`](/reference/react/memo) API๋ฅผ ์ ์šฉํ•˜์—ฌ state ๋ณ€๊ฒฝ์— ๋”ฐ๋ฅธ React์˜ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ์–‘์„ ์ˆ˜๋™์œผ๋กœ ์กฐ์ •ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ˆ˜๋™ memoization๋Š” ์ ˆ์ถฉ์•ˆ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ , ์ž˜๋ชป ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šฐ๋ฉฐ, ์ตœ์‹  state๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. +[์ด์ „ ๊ฒŒ์‹œ๊ธ€](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-optimizing-compiler)์—์„œ ๋…ผ์˜ํ•œ ๋ฐ”์™€ ๊ฐ™์ด, React๋Š” State๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ *์ด๋”ฐ๊ธˆ* ๋„ˆ๋ฌด ์ž์ฃผ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React ์ดˆ๊ธฐ๋ถ€ํ„ฐ ์ด๋Ÿฐ ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ํ•ด๋‹ต์€ ์ˆ˜๋™ ๋ฉ”๋ชจ์ด์ œ์ด์…˜<sup>Memoization</sup>์ด์—ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ API์—์„œ ์ด๋Š” [`useMemo`](/reference/react/useMemo), [`useCallback`](/reference/react/useCallback), ๊ทธ๋ฆฌ๊ณ  [`memo`](/reference/react/memo) API๋ฅผ ์ ์šฉํ•˜์—ฌ State ๋ณ€๊ฒฝ์— ๋”ฐ๋ฅธ React์˜ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ์–‘์„ ์ˆ˜๋™์œผ๋กœ ์กฐ์ •ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ˆ˜๋™ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ์ ˆ์ถฉ์•ˆ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ , ์ž˜๋ชป ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šฐ๋ฉฐ, ์ตœ์‹  State๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. -์ˆ˜๋™ memoization๋Š” ํ•ฉ๋ฆฌ์ ์ธ ์ ˆ์ถฉ์•ˆ์ด์ง€๋งŒ, ์šฐ๋ฆฌ๋Š” ๋งŒ์กฑํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๋น„์ „์€ state ๋ณ€๊ฒฝ ์‹œ React๊ฐ€ *ํ•ต์‹ฌ์ ์ธ ๋ฉ˜ํƒˆ ๋ชจ๋ธ์„ ์†์ƒํ•˜์ง€ ์•Š์œผ๋ฉด์„œ* UI์˜ ์ •ํ™•ํ•œ ๋ถ€๋ถ„๋งŒ *์ž๋™์œผ๋กœ* ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” UI๊ฐ€ ํ‘œ์ค€ JavaScript ๊ฐ’๊ณผ ํŒจํ„ด์œผ๋กœ ์ด๋ฃจ์–ด์ง„ state์˜ ๋‹จ์ˆœํ•œ ํ•จ์ˆ˜๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” React์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋ฐ”๋กœ ์ˆ˜๋งŽ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ React์— ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ํ•ต์‹ฌ ์ด์œ ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ React๋ฅผ ์œ„ํ•œ ์ตœ์ ํ™” ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ํˆฌ์žํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค. +์ˆ˜๋™ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ํ•ฉ๋ฆฌ์ ์ธ ์ ˆ์ถฉ์•ˆ์ด์ง€๋งŒ, ๋งŒ์กฑํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๋น„์ „์€ State ๋ณ€๊ฒฝ ์‹œ React๊ฐ€ *ํ•ต์‹ฌ์ ์ธ ๋ฉ˜ํƒˆ ๋ชจ๋ธ์„ ์†์ƒํ•˜์ง€ ์•Š์œผ๋ฉด์„œ* UI์˜ ์ •ํ™•ํ•œ ๋ถ€๋ถ„๋งŒ *์ž๋™์œผ๋กœ* ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” UI๊ฐ€ ํ‘œ์ค€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ’๊ณผ ํŒจํ„ด์œผ๋กœ ์ด๋ฃจ์–ด์ง„ State์˜ ๋‹จ์ˆœํ•œ ํ•จ์ˆ˜๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” React์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋ฐ”๋กœ ์ˆ˜๋งŽ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ React์— ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ํ•ต์‹ฌ ์ด์œ ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ React๋ฅผ ์œ„ํ•œ ์ตœ์ ํ™” ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ํˆฌ์žํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค. -JavaScript๋Š” ๋А์Šจํ•œ ๊ทœ์น™๊ณผ ๋™์ ์ธ ํŠน์ง• ๋•Œ๋ฌธ์— ์ตœ์ ํ™”ํ•˜๊ธฐ์— ๋งค์šฐ ๊นŒ๋‹ค๋กœ์šด ์–ธ์–ด์ž…๋‹ˆ๋‹ค. React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” JavaScript ๊ทœ์น™๊ณผ *ํ•จ๊ป˜* "React ๊ทœ์น™"์„ ๋ชจ๋‘ ๋ชจ๋ธ๋งํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, React ์ปดํฌ๋„ŒํŠธ๋Š” ๋™์ผํ•œ ์ž…๋ ฅ์ด ์ฃผ์–ด์ง€๋ฉด ๋™์ผํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉฑ๋“ฑ์„ฑ์„ ๋งŒ์กฑํ•ด์•ผ ํ•˜๋ฉฐ, props๋‚˜ state๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ทœ์น™์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•˜๊ณ  ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์•ˆ์ „ํ•œ ๊ณต๊ฐ„์„ ๋งŒ๋“ค์–ด ๋‚˜๊ฐ€๋Š” ๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค. +์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋А์Šจํ•œ ๊ทœ์น™๊ณผ ๋™์ ์ธ ํŠน์ง• ๋•Œ๋ฌธ์— ์ตœ์ ํ™”ํ•˜๊ธฐ์— ๋งค์šฐ ๊นŒ๋‹ค๋กœ์šด ์–ธ์–ด์ž…๋‹ˆ๋‹ค. React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ทœ์น™๊ณผ *ํ•จ๊ป˜* "React ๊ทœ์น™"์„ ๋ชจ๋‘ ๋ชจ๋ธ๋งํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, React ์ปดํฌ๋„ŒํŠธ๋Š” ๋™์ผํ•œ ์ž…๋ ฅ์ด ์ฃผ์–ด์ง€๋ฉด ๋™์ผํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉฑ๋“ฑ์„ฑ์„ ๋งŒ์กฑํ•ด์•ผ ํ•˜๋ฉฐ, Props๋‚˜ State๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ทœ์น™์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„๋ฅผ ์ œํ•œํ•˜๊ณ  ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์•ˆ์ „ํ•œ ๊ณต๊ฐ„์„ ๋งŒ๋“ค์–ด ๋‚˜๊ฐ€๋Š” ๋ฐ ๋„์›€์„ ์ค๋‹ˆ๋‹ค. ๋ฌผ๋ก , ๊ฐœ๋ฐœ์ž๋“ค์ด ๊ฐ€๋” ๊ทœ์น™์„ ์•ฝ๊ฐ„ ๋น„ํ‹€ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๋ชฉํ‘œ๋Š” React ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋งŽ์€ ์ฝ”๋“œ์—์„œ ์ฆ‰์‹œ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ฝ”๋“œ๊ฐ€ React ๊ทœ์น™์„ ์—„๊ฒฉํ•˜๊ฒŒ ๋”ฐ๋ฅด๊ณ  ์žˆ๋Š”์ง€ ํƒ์ง€ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋ฉฐ, ์•ˆ์ „ํ•œ ๊ฒฝ์šฐ์—๋Š” ์ปดํŒŒ์ผํ•˜๊ฑฐ๋‚˜ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” ์ปดํŒŒ์ผ์„ ๊ฑด๋„ˆ๋›ธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” Meta์˜ ํฌ๊ณ  ๋‹ค์–‘ํ•œ ์ฝ”๋“œ ๋ฒ ์ด์Šค๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๋ฉฐ ์ด๋Ÿฌํ•œ ์ ‘๊ทผ๋ฒ•์„ ๊ฒ€์ฆํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์‹ ์˜ ์ฝ”๋“œ๊ฐ€ React ๊ทœ์น™์„ ๋”ฐ๋ฅด๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์€ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ, ์šฐ๋ฆฌ๋Š” [Strict Mode๋ฅผ ํ™œ์„ฑํ™”](/reference/react/StrictMode)ํ•˜๊ณ  [React์˜ ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ](/learn/editor-setup#linting)์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋„๊ตฌ๋“ค์€ React ์ฝ”๋“œ์—์„œ์˜ ๋ฏธ๋ฌ˜ํ•œ ์˜ค๋ฅ˜๋ฅผ ์žก๊ณ , ํ˜„์žฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ’ˆ์งˆ์„ ํ–ฅ์ƒํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, React ์ปดํŒŒ์ผ๋Ÿฌ์™€ ๊ฐ™์€ ํ–ฅํ›„ ๋‹ค๊ฐ€์˜ฌ ๊ธฐ๋Šฅ๋“ค์— ๋Œ€๋น„ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ค€๋น„ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋˜ํ•œ React ๊ทœ์น™์— ๋Œ€ํ•œ ํ†ตํ•ฉ ๋ฌธ์„œ์™€ ESLint ํ”Œ๋Ÿฌ๊ทธ์ธ ์—…๋ฐ์ดํŠธ๋ฅผ ์ž‘์—…ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ํŒ€์—์„œ ์ด๋Ÿฌํ•œ ๊ทœ์น™๋“ค์„ ์ดํ•ดํ•˜๊ณ  ์ ์šฉํ•˜์—ฌ ๋”์šฑ ๊ฒฌ๊ณ ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ๋„์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹ค์ œ๋กœ ๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด, [์ง€๋‚œ๊ฐ€์„์— ์ง„ํ–‰ํ•œ ๊ฐ•์—ฐ](https://www.youtube.com/watch?v=qOQClO3g8-Y)์„ ํ™•์ธํ•ด ๋ณด์„ธ์š”. ๊ฐ•์—ฐ ๋‹น์‹œ, ์šฐ๋ฆฌ๋Š” instagram.com์˜ ํ•œ ํŽ˜์ด์ง€์— React ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹œ๋„ํ•œ ์ดˆ๊ธฐ ์‹คํ—˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ดํ›„๋กœ, ์šฐ๋ฆฌ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ instagram.com์˜ ํ”„๋กœ๋•์…˜ ๋‹จ๊ณ„ ์ „๋ฐ˜์— ๊ฑธ์ณ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ €ํฌ ํŒ€์„ ํ™•์žฅํ•˜์—ฌ ๋ฉ”ํƒ€์—์„œ ์ถœ์‹œํ•  ์ถ”๊ฐ€์ ์ธ ์„œ๋น„์Šค์™€ ์˜คํ”ˆ ์†Œ์Šค์˜ ์ถœ์‹œ๋ฅผ ๊ฐ€์†ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ €ํฌ๋Š” ์•ž์œผ๋กœ์˜ ๊ธธ์— ๋Œ€ํ•ด ํฐ ๊ธฐ๋Œ€๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ํ–ฅํ›„ ๋ช‡ ๋‹ฌ ์•ˆ์— ๋” ๋งŽ์€ ์†Œ์‹์„ ๊ณต์œ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹ค์ œ๋กœ ๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด, [์ง€๋‚œ ๊ฐ€์„์— ์ง„ํ–‰ํ•œ ๊ฐ•์—ฐ](https://www.youtube.com/watch?v=qOQClO3g8-Y)์„ ํ™•์ธํ•ด ๋ณด์„ธ์š”. ๊ฐ•์—ฐ ๋‹น์‹œ, ์šฐ๋ฆฌ๋Š” instagram.com์˜ ํ•œ ํŽ˜์ด์ง€์— React ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹œ๋„ํ•œ ์ดˆ๊ธฐ ์‹คํ—˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ดํ›„๋กœ, ์šฐ๋ฆฌ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ instagram.com์˜ ํ”„๋กœ๋•์…˜ ๋‹จ๊ณ„ ์ „๋ฐ˜์— ๊ฑธ์ณ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ €ํฌ ํŒ€์„ ํ™•์žฅํ•˜์—ฌ ๋ฉ”ํƒ€์—์„œ ์ถœ์‹œํ•  ์ถ”๊ฐ€์ ์ธ ์„œ๋น„์Šค์™€ ์˜คํ”ˆ ์†Œ์Šค์˜ ์ถœ์‹œ๋ฅผ ๊ฐ€์†ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ €ํฌ๋Š” ์•ž์œผ๋กœ์˜ ๊ธธ์— ๋Œ€ํ•ด ํฐ ๊ธฐ๋Œ€๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ํ–ฅํ›„ ๋ช‡ ๋‹ฌ ์•ˆ์— ๋” ๋งŽ์€ ์†Œ์‹์„ ๊ณต์œ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ## ์•ก์…˜ {/*actions*/} -์ €ํฌ๋Š” [์ด์ „์—](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components) ์„œ๋ฒ„ ์•ก์…˜์„ ํ†ตํ•œ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋Š” ํ•ด๊ฒฐ์ฑ…์„ ํƒ์ƒ‰ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณ€์ด๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ํผ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์•ก์…˜์„ ๊ฐœ๋ฐœํ•˜๋Š” ๋™์•ˆ, ์ด๋Ÿฌํ•œ API๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ „์šฉ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜๋„๋ก ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. +์ €ํฌ๋Š” [์ด์ „์—](/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components) ์„œ๋ฒ„ ์•ก์…˜์„ ํ†ตํ•œ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋Š” ํ•ด๊ฒฐ์ฑ…์„ ํƒ์ƒ‰ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณ€๊ฒฝ์„ ์‹คํ–‰ํ•˜๊ณ  ํผ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์•ก์…˜์„ ๊ฐœ๋ฐœํ•˜๋Š” ๋™์•ˆ, ์ด๋Ÿฌํ•œ API๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ „์šฉ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜๋„๋ก ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฌํ•œ ๊ด‘๋ฒ”์œ„ํ•œ ๊ธฐ๋Šฅ ๋ชจ์Œ์„ ๋‹จ์ˆœํžˆ "์•ก์…˜"์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์•ก์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ [`<form/>`](/reference/react-dom/components/form)๊ณผ ๊ฐ™์€ DOM ์—˜๋ฆฌ๋จผํŠธ์— ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -55,13 +55,13 @@ JavaScript๋Š” ๋А์Šจํ•œ ๊ทœ์น™๊ณผ ๋™์ ์ธ ํŠน์ง• ๋•Œ๋ฌธ์— ์ตœ์ ํ™”ํ•˜๊ธฐ์— </form> ``` -`์•ก์…˜` ํ•จ์ˆ˜๋Š” ๋™๊ธฐ ๋˜๋Š” ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ํ‘œ์ค€ JavaScript๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜ํ•˜๊ฑฐ๋‚˜, [`'use server'`](/reference/rsc/use-server)๋ผ๋Š” ์ง€์‹œ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„์—์„œ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ก์…˜์„ ์‚ฌ์šฉํ•  ๋•Œ, React๋Š” [`useFormStatus`](/reference/react-dom/hooks/useFormStatus), [`useActionState`](/reference/react/useActionState)์™€ ๊ฐ™์€ hook์„ ์ œ๊ณตํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ œ์ถœ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ํ˜„์žฌ ํผ์˜ state์™€ ์‘๋‹ต์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`action` ํ•จ์ˆ˜๋Š” ๋™๊ธฐ์  ๋˜๋Š” ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ํ‘œ์ค€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜ํ•˜๊ฑฐ๋‚˜, [`'use server'`](/reference/rsc/use-server)๋ผ๋Š” ์ง€์‹œ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„์—์„œ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ก์…˜์„ ์‚ฌ์šฉํ•  ๋•Œ, React๋Š” [`useFormStatus`](/reference/react-dom/hooks/useFormStatus), [`useActionState`](/reference/react/useActionState)์™€ ๊ฐ™์€ Hook์„ ์ œ๊ณตํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ œ์ถœ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ํ˜„์žฌ ํผ์˜ State์™€ ์‘๋‹ต์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๊ธฐ๋ณธ์ ์œผ๋กœ ์•ก์…˜์€ [ํŠธ๋žœ์ง€์…˜](/reference/react/useTransition) ๋‚ด์—์„œ ์ œ์ถœ๋˜์–ด ํ˜„์žฌ ํŽ˜์ด์ง€๊ฐ€ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•˜๋Š” ๋™์•ˆ ์•ก์…˜์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์•ก์…˜์€ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•˜๋ฏ€๋กœ, ํŠธ๋žœ์ง€์…˜ ๋‚ด์—์„œ `async/await`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด `fetch`์™€ ๊ฐ™์€ ๋น„๋™๊ธฐ ์š”์ฒญ์ด ์‹œ์ž‘๋˜๋ฉด ํŠธ๋žœ์ง€์…˜์˜ `isPending` state๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋Œ€๊ธฐ ์ค‘์ธ UI๋ฅผ ํ‘œ์‹œํ•˜๊ณ , ์—…๋ฐ์ดํŠธ๊ฐ€ ์ ์šฉ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ ์ค‘์ธ UI๋ฅผ ๊ณ„์† ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ธฐ๋ณธ์ ์œผ๋กœ ์•ก์…˜์€ [ํŠธ๋žœ์ง€์…˜](/reference/react/useTransition) ๋‚ด์—์„œ ์ œ์ถœ๋˜์–ด ํ˜„์žฌ ํŽ˜์ด์ง€๊ฐ€ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•˜๋Š” ๋™์•ˆ ์•ก์…˜์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์•ก์…˜์€ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•˜๋ฏ€๋กœ, ํŠธ๋žœ์ง€์…˜ ๋‚ด์—์„œ `async`/`await`์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด `fetch`์™€ ๊ฐ™์€ ๋น„๋™๊ธฐ ์š”์ฒญ์ด ์‹œ์ž‘๋˜๋ฉด ํŠธ๋žœ์ง€์…˜์˜ `isPending` State๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋Œ€๊ธฐ ์ค‘์ธ UI๋ฅผ ํ‘œ์‹œํ•˜๊ณ , ์—…๋ฐ์ดํŠธ๊ฐ€ ์ ์šฉ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ ์ค‘์ธ UI๋ฅผ ๊ณ„์† ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์•ก์…˜๊ณผ ํ•จ๊ป˜, ๋‚™๊ด€์  state ์—…๋ฐ์ดํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ [`useOptimistic`](/reference/react/useOptimistic)์ด๋ผ๋Š” ๊ธฐ๋Šฅ์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์ด hook์„ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ข… state๊ฐ€ ์ปค๋ฐ‹๋˜๋ฉด ์ž๋™์œผ๋กœ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๋Š” ์ผ์‹œ์ ์ธ ์—…๋ฐ์ดํŠธ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ก์…˜์˜ ๊ฒฝ์šฐ, ์ œ์ถœ์ด ์„ฑ๊ณต์ ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ์ดํ„ฐ์˜ ์ตœ์ข… state๋ฅผ ๋‚™๊ด€์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์„œ๋ฒ„์—์„œ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ผ๋ฐ˜์ ์ธ `async`/`await` ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘๋™ํ•˜๋ฏ€๋กœ, ํด๋ผ์ด์–ธํŠธ์—์„œ `fetch`๋ฅผ ์‚ฌ์šฉํ•˜๋“  ์„œ๋ฒ„์—์„œ ์„œ๋ฒ„ ์•ก์…˜์„ ์‚ฌ์šฉํ•˜๋“  ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. +์•ก์…˜๊ณผ ํ•จ๊ป˜, ๋‚™๊ด€์  State ์—…๋ฐ์ดํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ [`useOptimistic`](/reference/react/useOptimistic)์ด๋ผ๋Š” ๊ธฐ๋Šฅ์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์ด Hook์„ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ข… State๊ฐ€ ์ปค๋ฐ‹๋˜๋ฉด ์ž๋™์œผ๋กœ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๋Š” ์ผ์‹œ์ ์ธ ์—…๋ฐ์ดํŠธ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ก์…˜์˜ ๊ฒฝ์šฐ, ์ œ์ถœ์ด ์„ฑ๊ณต์ ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ์ดํ„ฐ์˜ ์ตœ์ข… State๋ฅผ ๋‚™๊ด€์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์„œ๋ฒ„์—์„œ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ผ๋ฐ˜์ ์ธ `async`/`await` ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘๋™ํ•˜๋ฏ€๋กœ, ํด๋ผ์ด์–ธํŠธ์—์„œ `fetch`๋ฅผ ์‚ฌ์šฉํ•˜๋“  ์„œ๋ฒ„์—์„œ ์„œ๋ฒ„ ์•ก์…˜์„ ์‚ฌ์šฉํ•˜๋“  ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. -๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ œ์ž‘์ž๋Š” ๊ฐ์ž์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ `useTransition`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ง€์ • `action={fn}` props๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ์˜๋„๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ปดํฌ๋„ŒํŠธ API๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์•ก์…˜ ํŒจํ„ด์„ ์ฑ„ํƒํ•˜์—ฌ React ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ์ผ๊ด€์ ์ธ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ `<Calendar onSelect={eventHandler}>`์™€ ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ, `<Calendar selectAction={action}>`์™€ ๊ฐ™์€ API๋„ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณด์„ธ์š”. +๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ œ์ž‘์ž๋Š” ๊ฐ์ž์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ `useTransition`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ง€์ • `action={fn}` Props๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ์˜๋„๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ปดํฌ๋„ŒํŠธ API๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์•ก์…˜ ํŒจํ„ด์„ ์ฑ„ํƒํ•˜์—ฌ React ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ์ผ๊ด€์ ์ธ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ `<Calendar onSelect={eventHandler}>`์™€ ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ, `<Calendar selectAction={action}>`์™€ ๊ฐ™์€ API๋„ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณด์„ธ์š”. ์šฐ๋ฆฌ๋Š” ์ฒ˜์Œ์— ์„œ๋ฒ„ ์•ก์…˜์„ ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ์‚ฌ์ด ๋ฐ์ดํ„ฐ ์ „์†ก์— ์ค‘์ ์„ ๋‘์—ˆ์ง€๋งŒ, React์˜ ์ฒ ํ•™์€ ๋ชจ๋‘” ํ”Œ๋žซํผ๊ณผ ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ํด๋ผ์ด์–ธํŠธ์˜ ๊ธฐ๋Šฅ์„ ์†Œ๊ฐœํ•œ ๊ฒฝ์šฐ ํ•ด๋‹น ๊ธฐ๋Šฅ์ด ์„œ๋ฒ„์—์„œ๋„ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๊ณ , ๊ทธ ๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ด ์ฒ ํ•™์„ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋˜๋Š” ์œ„์น˜์™€ ๊ด€๊ณ„์—†์ด ์ž‘๋™ํ•˜๋Š” ๋‹จ์ผ API ๋ชจ์Œ์„ ์ƒ์„ฑํ•˜์—ฌ, ์ดํ›„ ๋‹ค๋ฅธ ํ™˜๊ฒฝ์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -75,21 +75,21 @@ Canary๋Š” React์˜ ๊ฐœ๋ฐœ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด์ „์—๋Š” ๊ธฐ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ, ์—์…‹ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ, ๋ฌธ์„œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ฐ ์•ก์…˜ ๋ชจ๋‘ React Canary์— ๋„์ž…๋˜์—ˆ์œผ๋ฉฐ, ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๋ฌธ์„œ๋ฅผ react.dev์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. -- **์ง€์‹œ์–ด**: [`"use client"`](/reference/rsc/use-client)์™€ [`"use server"`](/reference/rsc/use-server)๋Š” ํ’€์Šคํƒ React ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์œ„ํ•ด ์„ค๊ณ„ํ•œ ๋ฒˆ๋“ค๋Ÿฌ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ด๋“ค์€ ๋‘ ํ™˜๊ฒฝ ์‚ฌ์ด์˜ "๋ถ„ํ• ์ "์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. "use client"๋Š” [Astro Islands](https://docs.astro.build/en/concepts/islands/#creating-an-island)์ฒ˜๋Ÿผ ๋ฒˆ๋“ค๋Ÿฌ์— `<script>` ํƒœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด `"use server"`๋Š” [tRPC Mutations](https://trpc.io/docs/concepts)์ฒ˜๋Ÿผ ๋ฒˆ๋“ค๋Ÿฌ์— POST ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. ๋‘ ์ง€์‹œ์–ด๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์ด์–ธํŠธ ์ธก์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์„œ๋ฒ„ ์ธก์˜ ๋กœ์ง๊ณผ ๊ฒฐํ•ฉํ•˜๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- **์ง€์‹œ์–ด**: [`"use client"`](/reference/rsc/use-client)์™€ [`"use server"`](/reference/rsc/use-server)๋Š” ํ’€์Šคํƒ React ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์œ„ํ•ด ์„ค๊ณ„ํ•œ ๋ฒˆ๋“ค๋Ÿฌ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ด๋“ค์€ ๋‘ ํ™˜๊ฒฝ ์‚ฌ์ด์˜ "๋ถ„ํ• ์ "์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. `"use client"`๋Š” [Astro Islands](https://docs.astro.build/en/concepts/islands/#creating-an-island)์ฒ˜๋Ÿผ ๋ฒˆ๋“ค๋Ÿฌ์— `<script>` ํƒœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด `"use server"`๋Š” [tRPC Mutations](https://trpc.io/docs/concepts)์ฒ˜๋Ÿผ ๋ฒˆ๋“ค๋Ÿฌ์— POST ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. ๋‘ ์ง€์‹œ์–ด๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์ด์–ธํŠธ ์ธก์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์„œ๋ฒ„ ์ธก์˜ ๋กœ์ง๊ณผ ๊ฒฐํ•ฉํ•˜๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - **๋ฌธ์„œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ**: ์šฐ๋ฆฌ๋Š” ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ ์–ด๋””์—์„œ๋“  [`<title>`](/reference/react-dom/components/title), [`<meta>`](/reference/react-dom/components/meta) ๋ฐ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ [`<link>`](/reference/react-dom/components/link) ํƒœ๊ทธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋‚ด์žฅ ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์™„์ „ํ•œ ํด๋ผ์ด์–ธํŠธ ์ธก ์ฝ”๋“œ, SSR ๋ฐ RSC๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” [React Helmet](https://github.com/nfl/react-helmet)๊ณผ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ด๋ฏธ ์ œ๊ณตํ•˜๋˜ ๊ธฐ๋Šฅ์„ ๋‚ด์žฅ ์ง€์›์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. -- **์—์…‹ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ**: ์šฐ๋ฆฌ๋Š” Suspense๋ฅผ ์Šคํƒ€์ผ์‹œํŠธ, ํฐํŠธ, ์Šคํฌ๋ฆฝํŠธ์™€ ๊ฐ™์€ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ƒ๋ช…์ฃผ๊ธฐ์™€ ํ†ตํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด React๋Š” ํ‘œ์‹œํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ๊ฒฐ์ •ํ•˜๋Š”๋ฐ [`<style>`](/reference/react-dom/components/style), [`<link>`](/reference/react-dom/components/link) ๋ฐ [`<script>`](/reference/react-dom/components/script)์™€ ๊ฐ™์€ ์—˜๋ฆฌ๋จผํŠธ ๋‚ด๋ถ€์˜ ์ฝ˜ํ…์ธ ๋ฅผ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ `preload`์™€ `preinit`๊ณผ ๊ฐ™์€ [์ƒˆ๋กœ์šด ๋ฆฌ์†Œ์Šค ๋ถˆ๋Ÿฌ์˜ค๊ธฐ API](/reference/react-dom#resource-preloading-apis)๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฆฌ์†Œ์Šค๋ฅผ ์–ธ์ œ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์ดˆ๊ธฐํ™”ํ• ์ง€์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ œ์–ด๊ถŒ์„ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. +- **์—์…‹ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ**: ์šฐ๋ฆฌ๋Š” Suspense๋ฅผ ์Šคํƒ€์ผ์‹œํŠธ, ๊ธ€๊ผด, ์Šคํฌ๋ฆฝํŠธ์™€ ๊ฐ™์€ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ƒ๋ช…์ฃผ๊ธฐ์™€ ํ†ตํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด React๋Š” ํ‘œ์‹œํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ๊ฒฐ์ •ํ•˜๋Š”๋ฐ [`<style>`](/reference/react-dom/components/style), [`<link>`](/reference/react-dom/components/link) ๋ฐ [`<script>`](/reference/react-dom/components/script)์™€ ๊ฐ™์€ ์—˜๋ฆฌ๋จผํŠธ ๋‚ด๋ถ€์˜ ์ฝ˜ํ…์ธ ๋ฅผ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ `preload`์™€ `preinit`๊ณผ ๊ฐ™์€ [์ƒˆ๋กœ์šด ๋ฆฌ์†Œ์Šค ๋ถˆ๋Ÿฌ์˜ค๊ธฐ API](/reference/react-dom#resource-preloading-apis)๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฆฌ์†Œ์Šค๋ฅผ ์–ธ์ œ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์ดˆ๊ธฐํ™”ํ• ์ง€์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ œ์–ด๊ถŒ์„ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. - **์•ก์…˜**: ์•ž์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ, ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๊ฒƒ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์•ก์…˜์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. [`<form/>`](/reference/react-dom/components/form)๊ณผ ๊ฐ™์€ ์—˜๋ฆฌ๋จผํŠธ์— `action`์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, [`useFormStatus`](/reference/react-dom/hooks/useFormStatus)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง„ํ–‰ ์ƒํ™ฉ์— ์ ‘๊ทผํ•˜๊ณ , [`useActionState`](/reference/react/useActionState)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, [`useOptimistic`](/reference/react/useOptimistic)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI๋ฅผ ๋‚™๊ด€์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ด๋Ÿฌํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ์€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋“ค์„ ๊ฐ๊ฐ ์•ˆ์ •์  ์ฑ„๋„์— ๋ฐฐํฌํ•˜๊ธฐ๋Š” ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ํผ state์— ์ ‘๊ทผํ•˜๋Š” ๋ณด์กฐ hook ์—†์ด ์•ก์…˜์„ ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ์€ ์•ก์…˜์˜ ์‹ค์ œ ์œ ์šฉ์„ฑ์„ ์ œํ•œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์•ก์…˜์„ ํ†ตํ•ฉํ•˜์ง€ ์•Š์œผ๋ฉด์„œ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋„์ž…ํ•˜๋ฉด ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ์— ๋ณต์žกํ•ด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ด๋Ÿฌํ•œ ๋ชจ๋“  ๊ธฐ๋Šฅ์€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋“ค์„ ๊ฐ๊ฐ ์•ˆ์ •์  ์ฑ„๋„์— ๋ฐฐํฌํ•˜๊ธฐ๋Š” ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ํผ State์— ์ ‘๊ทผํ•˜๋Š” ๋ณด์กฐ Hook ์—†์ด ์•ก์…˜์„ ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ์€ ์•ก์…˜์˜ ์‹ค์ œ ์œ ์šฉ์„ฑ์„ ์ œํ•œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์•ก์…˜์„ ํ†ตํ•ฉํ•˜์ง€ ์•Š์œผ๋ฉด์„œ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋„์ž…ํ•˜๋ฉด ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ์— ๋ณต์žกํ•ด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ €ํฌ๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ๋“ค์„ ์•ˆ์ •์  ์ฑ„๋„์— ๋ฐฐํฌํ•˜๊ธฐ ์ „์—, ์ด๋“ค์ด ํ•จ๊ป˜ ์ž‘๋™ํ•˜๊ณ  ๊ฐœ๋ฐœ์ž๊ฐ€ ํ”„๋กœ๋•์…˜ ๋‹จ๊ณ„์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ๊ฐ–์ถ”์—ˆ๋Š”์ง€ ๋ณด์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. React Canary๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๋Š” ์ด๋Ÿฐ ๊ธฐ๋Šฅ์„ ๊ฐœ๋ณ„์ ์œผ๋กœ ๊ฐœ๋ฐœํ•˜๊ณ , ์ „์ฒด ๊ธฐ๋Šฅ ๋ชฉ๋ก์ด ์™„์„ฑ๋˜๊ธฐ ์ „๊นŒ์ง€ ์ ์ง„์ ์œผ๋กœ ์•ˆ์ •๋œ API๋ฅผ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ React Canary์— ํฌํ•จ๋œ ๊ธฐ๋Šฅ๋“ค์€ ์™„์„ฑ๋˜์–ด ๋ฐฐํฌํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -## React์˜ ๋‹ค์Œ ์ฃผ์š” ๋ฒ„์ „ {/*the-next-major-version-of-react*/} +## React์˜ ๋‹ค์Œ ๋ฉ”์ด์ € ๋ฒ„์ „ {/*the-next-major-version-of-react*/} ๋ช‡ ๋…„๊ฐ„์˜ ๋ฐ˜๋ณต ์ž‘์—… ๋์—, `react@canary`๊ฐ€ ์ด์ œ `react@latest`๋กœ์˜ ์ถœ์‹œ ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋˜๋Š” ๋ชจ๋“  ํ™˜๊ฒฝ๊ณผ ํ˜ธํ™˜๋˜๋ฉฐ, ํ”„๋กœ๋•์…˜ ๋‹จ๊ณ„์—์„œ ์‚ฌ์šฉ๋˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์—์…‹ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ์™€ ๋ฌธ์„œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋Š” ์ผ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํฐ ๋ณ€ํ™”์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ React์˜ ๋‹ค์Œ ๋ฒ„์ „์€ ์ฃผ์š” ๋ฒ„์ „์ธ **React 19**๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. @@ -105,9 +105,9 @@ Activity๋Š” ์—ฌ์ „ํžˆ ์—ฐ๊ตฌ ์ค‘์ด๋ฉฐ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋…ธ์ถœ * * * -์ด๋ฒˆ ์—…๋ฐ์ดํŠธ ์™ธ์—๋„ ์šฐ๋ฆฌ ํŒ€์€ ์ฝ˜ํผ๋Ÿฐ์Šค์—์„œ ๋ฐœํ‘œํ•˜๊ณ  ํŒŸ์บ์ŠคํŠธ ์ถœ์—ฐ์„ ํ†ตํ•ด ์šฐ๋ฆฌ์˜ ์ž‘์—…์— ๊ด€ํ•ด ์ด์•ผ๊ธฐ๋ฅผ ๋‚˜๋ˆ„๊ณ  ์งˆ๋ฌธ์— ๋‹ต๋ณ€ํ–ˆ์Šต๋‹ˆ๋‹ค. +์ด๋ฒˆ ์—…๋ฐ์ดํŠธ ์™ธ์—๋„ ์šฐ๋ฆฌ ํŒ€์€ ์ปจํผ๋Ÿฐ์Šค์—์„œ ๋ฐœํ‘œํ•˜๊ณ  ํŒŸ์บ์ŠคํŠธ ์ถœ์—ฐ์„ ํ†ตํ•ด ์šฐ๋ฆฌ์˜ ์ž‘์—…์— ๊ด€ํ•ด ์ด์•ผ๊ธฐ๋ฅผ ๋‚˜๋ˆ„๊ณ  ์งˆ๋ฌธ์— ๋‹ต๋ณ€ํ–ˆ์Šต๋‹ˆ๋‹ค. -- [Sathya Gunasekaran](/community/team#sathya-gunasekaran)์€ [React India](https://www.youtube.com/watch?v=kjOacmVsLSE) ์ฝ˜ํผ๋Ÿฐ์Šค์—์„œ React ์ปดํŒŒ์ผ๋Ÿฌ์— ๊ด€ํ•ด ์ด์•ผ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. +- [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 ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ ์•ก์…˜์„ ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์—ˆ๋Š”์ง€์— ๊ด€ํ•œ ๋Œ€์•ˆ์ ์ธ ์—ญ์‚ฌ๋ฅผ ํƒ๊ตฌํ–ˆ์Šต๋‹ˆ๋‹ค. From 9f996d22c81deb800f3dd14ddb5c1b7b7338717e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 22:40:38 +0900 Subject: [PATCH 0361/1059] docs: update `react-19-upgrade-guide` --- src/content/blog/2024/04/25/react-19-upgrade-guide.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/content/blog/2024/04/25/react-19-upgrade-guide.md b/src/content/blog/2024/04/25/react-19-upgrade-guide.md index 44802014e..fbeb80edc 100644 --- a/src/content/blog/2024/04/25/react-19-upgrade-guide.md +++ b/src/content/blog/2024/04/25/react-19-upgrade-guide.md @@ -112,13 +112,8 @@ This will run the following codemods from `react-codemod`: - [`replace-reactdom-render`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-reactdom-render) - [`replace-string-ref`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-string-ref) - [`replace-act-import`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-act-import) -<<<<<<< HEAD - [`replace-use-form-state`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-use-form-state) -- [`prop-types-typescript`](TODO) -======= -- [`replace-use-form-state`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-use-form-state) - [`prop-types-typescript`](https://codemod.com/registry/react-prop-types-typescript) ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc This does not include the TypeScript changes. See [TypeScript changes](#typescript-changes) below. @@ -396,7 +391,7 @@ npx codemod@latest react/19/replace-act-import #### Removed: `ReactDOM.render` {/*removed-reactdom-render*/} -`ReactDOM.render` was deprecated in [March 2022 (v18.0.0)](https://react.dev/blog/2022/03/08/react-18-upgrade-guide). In React 19, we're removing `ReactDOM.render` and you'll need to migrate to using [`ReactDOM.createRoot`](https://react.dev/reference/react-dom/client/createRoot): +`ReactDOM.render` was deprecated in [March 2022 (v18.0.0)](/blog/2022/03/08/react-18-upgrade-guide). In React 19, we're removing `ReactDOM.render` and you'll need to migrate to using [`ReactDOM.createRoot`](/reference/react-dom/client/createRoot): ```js // Before @@ -421,7 +416,7 @@ npx codemod@latest react/19/replace-reactdom-render #### Removed: `ReactDOM.hydrate` {/*removed-reactdom-hydrate*/} -`ReactDOM.hydrate` was deprecated in [March 2022 (v18.0.0)](https://react.dev/blog/2022/03/08/react-18-upgrade-guide). In React 19, we're removing `ReactDOM.hydrate` you'll need to migrate to using [`ReactDOM.hydrateRoot`](https://react.dev/reference/react-dom/client/hydrateRoot), +`ReactDOM.hydrate` was deprecated in [March 2022 (v18.0.0)](/blog/2022/03/08/react-18-upgrade-guide). In React 19, we're removing `ReactDOM.hydrate` you'll need to migrate to using [`ReactDOM.hydrateRoot`](/reference/react-dom/client/hydrateRoot), ```js // Before From 5095e26c18618fe9deaa1c3d858e69801ed96045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 23:01:20 +0900 Subject: [PATCH 0362/1059] docs: update `react-compiler.md` --- src/content/learn/react-compiler.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md index 241611c94..1ac53f74f 100644 --- a/src/content/learn/react-compiler.md +++ b/src/content/learn/react-compiler.md @@ -105,7 +105,7 @@ function TableContainer({ items }) { // ... } ``` -[_React ์ปดํŒŒ์ผ๋Ÿฌ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ์—์„œ ์ด ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”_](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAejQAgFTYHIQAuumAtgqRAJYBeCAJpgEYCemASggIZyGYDCEUgAcqAGwQwANJjBUAdokyEAFlTCZ1meUUxdMcIcIjyE8vhBiYVECAGsAOvIBmURYSonMCAB7CzcgBuCGIsAAowEIhgYACCnFxioQAyXDAA5gixMDBcLADyzvlMAFYIvGAAFACUmMCYaNiYAHStOFgAvk5OGJgAshTUdIysHNy8AkbikrIKSqpaWvqGIiZmhE6u7p7ymAAqXEwSguZcCpKV9VSEFBodtcBOmAYmYHz0XIT6ALzefgFUYKhCJRBAxeLcJIsVIZLI5PKFYplCqVa63aoAbm6u0wMAQhFguwAPPRAQA+YAfL4dIloUmBMlODogDpAA) +[_React ์ปดํŒŒ์ผ๋Ÿฌ ํ”Œ๋ ˆ์ด๊ทธ๋ผ์šด๋“œ์—์„œ ์ด ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”_](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAejQAgFTYHIQAuumAtgqRAJYBeCAJpgEYCemASggIZyGYDCEUgAcqAGwQwANJjBUAdokyEAFlTCZ1meUUxdMcIcIjyE8vhBiYVECAGsAOvIBmURYSonMCAB7CzcgBuCGIsAAowEIhgYACCnFxioQAyXDAA5gixMDBcLADyzvlMAFYIvGAAFACUmMCYaNiYAHStOFgAvk5OGJgAshTUdIysHNy8AkbikrIKSqpaWvqGIiZmhE6u7p7ymAAqXEwSguZcCpKV9VSEFBodtcBOmAYmYHz0XIT6ALzefgFUYKhCJRBAxeLcJIsVIZLI5PKFYplCqVa63aoAbm6u0wMAQhFguwAPPRAQA+YAfL4dIloUmBMlODogDpAA). ๊ทธ๋Ÿฌ๋‚˜ `expensivelyProcessAReallyLargeArrayOfObjects`๊ฐ€ ์‹ค์ œ๋กœ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ํ•จ์ˆ˜๋ผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ React ์™ธ๋ถ€์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜์˜ ๋ณ„๋„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ๊ณ ๋ คํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -349,11 +349,7 @@ React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React์˜ ๋งŽ์€ ๊ทœ์น™์„ ์ •์ ์œผ๋กœ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ ### ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ตœ์ ํ™”๋˜์—ˆ๋Š”์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ์š”? {/*how-do-i-know-my-components-have-been-optimized*/} -<<<<<<< HEAD -[React Devtools](/learn/react-developer-tools) (v5.0+)์—๋Š” React ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋‚ด์žฅ ์ง€์›ํ•˜๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ตœ์ ํ™”๋œ ์ปดํฌ๋„ŒํŠธ ์˜†์— "Memo โœจ" ๋ฐฐ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. -======= -[React DevTools](/learn/react-developer-tools) (v5.0+) and [React Native DevTools](https://reactnative.dev/docs/react-native-devtools) have built-in support for React Compiler and will display a "Memo โœจ" badge next to components that have been optimized by the compiler. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +[React DevTools](/learn/react-developer-tools) (v5.0+)์™€ [React Native DevTools](https://reactnative.dev/docs/react-native-devtools)๋Š” React ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋‚ด์žฅ ์ง€์›ํ•˜๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ตœ์ ํ™”๋œ ์ปดํฌ๋„ŒํŠธ ์˜†์— "Memo โœจ" ๋ฐฐ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ### ์ปดํŒŒ์ผ ํ›„ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ {/*something-is-not-working-after-compilation*/} From 179e0fcf8475ac60984f26419f61c1ec75228d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Tue, 31 Dec 2024 23:19:45 +0900 Subject: [PATCH 0363/1059] docs: resolve conflict in `react-19.md` --- src/content/blog/2024/12/05/react-19.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/content/blog/2024/12/05/react-19.md b/src/content/blog/2024/12/05/react-19.md index 213581816..cc58a1040 100644 --- a/src/content/blog/2024/12/05/react-19.md +++ b/src/content/blog/2024/12/05/react-19.md @@ -330,7 +330,7 @@ We've added two new APIs to `react-dom/static` for static site generation: - [`prerender`](/reference/react-dom/static/prerender) - [`prerenderToNodeStream`](/reference/react-dom/static/prerenderToNodeStream) -These new APIs improve on `renderToString` by waiting for data to load for static HTML generation. They are designed to work with streaming environments like Node.js Streams and Web Streams. For example, in a Web Stream environment, you can prerender a React tree to static HTML with `prerender`: +These new APIs improve on `renderToString` by waiting for data to load for static HTML generation. They are designed to work with streaming environments like Node.js Streams and Web Streams. For example, in a Web Stream environment, you can prerender a React tree to static HTML with `prerender`: ```js import { prerender } from 'react-dom/static'; @@ -362,11 +362,7 @@ React 19 includes all of the React Server Components features included from the #### How do I build support for Server Components? {/*how-do-i-build-support-for-server-components*/} -<<<<<<< HEAD:src/content/blog/2024/04/25/react-19.md -While React Server Components in React 19 are stable and will not break between major versions, the underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x. -======= -While React Server Components in React 19 are stable and will not break between minor versions, the underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc:src/content/blog/2024/12/05/react-19.md +While React Server Components in React 19 are stable and will not break between minor versions, the underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x. To support React Server Components as a bundler or framework, we recommend pinning to a specific React version, or using the Canary release. We will continue working with bundlers and frameworks to stabilize the APIs used to implement React Server Components in the future. From 3a6a612ca776a7bd862055498f2726e1b1e16d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 18:26:06 +0900 Subject: [PATCH 0364/1059] chore: translate `sidebarX.json` --- src/sidebarBlog.json | 2 +- src/sidebarHome.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sidebarBlog.json b/src/sidebarBlog.json index 8ff8995c1..1093aae19 100644 --- a/src/sidebarBlog.json +++ b/src/sidebarBlog.json @@ -4,7 +4,7 @@ "routes": [ { "hasSectionHeader": true, - "sectionHeader": "STAY INFORMED" + "sectionHeader": "์ตœ์‹  ์†Œ์‹" }, { "title": "๋ธ”๋กœ๊ทธ", diff --git a/src/sidebarHome.json b/src/sidebarHome.json index 3b018bcc1..fee1a73d9 100644 --- a/src/sidebarHome.json +++ b/src/sidebarHome.json @@ -4,7 +4,7 @@ "routes": [ { "hasSectionHeader": true, - "sectionHeader": "GET STARTED" + "sectionHeader": "์‹œ์ž‘ํ•˜๊ธฐ" }, { "title": "๋น ๋ฅด๊ฒŒ ์‹œ์ž‘ํ•˜๊ธฐ", @@ -16,7 +16,7 @@ }, { "hasSectionHeader": true, - "sectionHeader": "LEARN REACT" + "sectionHeader": "React ํ•™์Šตํ•˜๊ธฐ" }, { "title": "UI ํ‘œํ˜„ํ•˜๊ธฐ", @@ -76,7 +76,7 @@ }, { "hasSectionHeader": true, - "sectionHeader": "GET INVOLVED" + "sectionHeader": "์ฐธ์—ฌํ•˜๊ธฐ" }, { "title": "React ์ปค๋ฎค๋‹ˆํ‹ฐ", @@ -84,7 +84,7 @@ }, { "hasSectionHeader": true, - "sectionHeader": "STAY INFORMED" + "sectionHeader": "์ตœ์‹  ์†Œ์‹" }, { "title": "React ๋ธ”๋กœ๊ทธ", From f10061da92c872b98aec43910ebafab1767a21ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 18:36:15 +0900 Subject: [PATCH 0365/1059] docs: update `community/index.md` --- src/content/community/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/community/index.md b/src/content/community/index.md index 351b71cd9..7874616ef 100644 --- a/src/content/community/index.md +++ b/src/content/community/index.md @@ -8,17 +8,17 @@ React๋Š” ์ˆ˜๋ฐฑ๋งŒ์˜ ๊ฐœ๋ฐœ์ž๋กœ ๊ตฌ์„ฑ๋œ ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ </Intro> -## ํ–‰๋™ ๊ทœ์น™ {/*code-of-conduct*/} +## ํ–‰๋™ ๊ฐ•๋ น {/*code-of-conduct*/} -React์˜ ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์ฐธ์—ฌํ•˜๊ธฐ ์ „์— [ํ–‰๋™ ๊ทœ์น™์„ ๋ฐ˜๋“œ์‹œ ์ฝ์–ด๋ณด์„ธ์š”.](https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md) ์šฐ๋ฆฌ๋Š” [๊ธฐ์—ฌ์ž ์„œ์•ฝ](https://www.contributor-covenant.org/)์„ ์ฑ„ํƒํ–ˆ๊ณ , ๋ชจ๋“  ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ตฌ์„ฑ์›์ด ์„œ์•ฝ ํฌํ•จ๋œ ์ง€์นจ์„ ์ค€์ˆ˜ํ•  ๊ฒƒ์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. +React ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์ฐธ์—ฌํ•˜๊ธฐ ์ „์— [๋ฐ˜๋“œ์‹œ ํ–‰๋™ ๊ฐ•๋ น์„ ์ฝ์–ด์ฃผ์„ธ์š”](https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md). ์šฐ๋ฆฌ๋Š” [๊ธฐ์—ฌ์ž ์„œ์•ฝ](https://www.contributor-covenant.org/)์„ ์ฑ„ํƒํ–ˆ๊ณ , ๋ชจ๋“  ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ตฌ์„ฑ์›๋“ค์ด ์ง€์นจ์„ ์ค€์ˆ˜ํ•  ๊ฒƒ์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ## Stack Overflow {/*stack-overflow*/} -Stack Overflow๋Š” ์ฝ”๋“œ ์ˆ˜์ค€์˜ ์งˆ๋ฌธ์„ ํ•˜๊ฑฐ๋‚˜ ํŠน์ • ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ ์ž ํ•  ๋•Œ ์œ ์šฉํ•œ ํฌ๋Ÿผ์ž…๋‹ˆ๋‹ค. **reactjs**๋กœ ํƒœ๊ทธ๋œ [๊ธฐ์กด์˜ ์งˆ๋ฌธ์„](https://stackoverflow.com/questions/tagged/reactjs) ์ฝ์–ด๋ณด๊ฑฐ๋‚˜ [์ง์ ‘ ์งˆ๋ฌธํ•˜์„ธ์š”](https://stackoverflow.com/questions/ask?tags=reactjs)! +Stack Overflow๋Š” ์ฝ”๋“œ ๊ด€๋ จ ์งˆ๋ฌธ์„ ํ•˜๊ฑฐ๋‚˜ ํŠน์ • ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ ์ž ํ•  ๋•Œ ์œ ์šฉํ•œ ํฌ๋Ÿผ์ž…๋‹ˆ๋‹ค. **reactjs**๋กœ ํƒœ๊ทธ๋œ [๊ธฐ์กด์˜ ์งˆ๋ฌธ์„](https://stackoverflow.com/questions/tagged/reactjs) ์ฝ์–ด๋ณด๊ฑฐ๋‚˜ [์ง์ ‘ ์งˆ๋ฌธํ•˜์„ธ์š”](https://stackoverflow.com/questions/ask?tags=reactjs)! ## ์ธ๊ธฐ ์žˆ๋Š” ํ† ๋ก  ํฌ๋Ÿผ {/*popular-discussion-forums*/} -React์˜ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•„ํ‚คํ…์ฒ˜, ๊ทธ๋ฆฌ๊ณ  React์˜ ๋ฏธ๋ž˜๋ฅผ ์ฃผ์ œ๋กœ ํ† ๋ก ํ•  ์ˆ˜ ์žˆ๋Š” ๋งŽ์€ ์˜จ๋ผ์ธ ํฌ๋Ÿผ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ ์ˆ˜์ค€์—์„œ ๋‹ตํ•  ์ˆ˜ ์žˆ๋Š” ์งˆ๋ฌธ์ด ์žˆ๋‹ค๋ฉด, ๋Œ€๊ฐœ Stack Overflow๊ฐ€ ๋” ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. +React์˜ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•„ํ‚คํ…์ฒ˜, ๊ทธ๋ฆฌ๊ณ  React์˜ ๋ฏธ๋ž˜๋ฅผ ์ฃผ์ œ๋กœ ํ† ๋ก ํ•  ์ˆ˜ ์žˆ๋Š” ๋งŽ์€ ์˜จ๋ผ์ธ ํฌ๋Ÿผ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ ๋ ˆ๋ฒจ์—์„œ ๋‹ตํ•  ์ˆ˜ ์žˆ๋Š” ์งˆ๋ฌธ์ด ์žˆ๋‹ค๋ฉด, ๋Œ€๊ฐœ Stack Overflow๊ฐ€ ๋” ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” ์ˆ˜์ฒœ ๋ช…์˜ React ์‚ฌ์šฉ์ž๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. From 0fda6a9524e68b3b968e1a3e55ba77b55beac30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 18:50:08 +0900 Subject: [PATCH 0366/1059] docs: update `videos.md` --- src/content/community/videos.md | 34 ++++++++++++++++----------------- src/sidebarCommunity.json | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/content/community/videos.md b/src/content/community/videos.md index fe5b13118..cb14245d9 100644 --- a/src/content/community/videos.md +++ b/src/content/community/videos.md @@ -1,10 +1,10 @@ --- -title: React ์˜์ƒ๋“ค +title: React ์˜์ƒ --- <Intro> -React์™€ React ์—์ฝ”์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ํ† ๋ก ์„ ์œ„ํ•œ ์˜์ƒ๋“ค์ž…๋‹ˆ๋‹ค. +React์™€ React ์ƒํƒœ๊ณ„<sup>Ecosystem</sup>์— ๋Œ€ํ•œ ํ† ๋ก  ์˜์ƒ๋“ค์ž…๋‹ˆ๋‹ค. </Intro> @@ -20,7 +20,7 @@ React์™€ React ์—์ฝ”์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ํ† ๋ก ์„ ์œ„ํ•œ ์˜์ƒ๋“ค์ž…๋‹ˆ๋‹ค. ### ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ React 18 {/*react-18-for-application-developers*/} -React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐ๋ชจ๋Š” ์—ฌ๊ธฐ์—์„œ [Shruti Kapoor](https://twitter.com/shrutikapoor08)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”: +React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐ๋ชจ๋Š” ์—ฌ๊ธฐ์—์„œ [Shruti Kapoor](https://twitter.com/shrutikapoor08)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”. <YouTubeIframe src="https://www.youtube.com/embed/ytudH8je5ko" title="YouTube video player" /> @@ -30,7 +30,7 @@ React 18์—๋Š” Suspense๋ฅผ ์‚ฌ์šฉํ•œ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง ์„ฑ๋Šฅ ๊ฐœ์„  ์‚ฌํ•ญ ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„์˜ React ์ปดํฌ๋„ŒํŠธ์—์„œ HTML์„ ์ƒ์„ฑํ•˜๊ณ  ํ•ด๋‹น HTML์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ŠคํŠธ๋ฆฌ๋ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React 18์—์„œ๋Š” 'Suspense'๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•ฑ์„ ๋” ์ž‘์€ ๋…๋ฆฝ ๋‹จ์œ„๋กœ ๋ถ„ํ•ดํ•˜์—ฌ ๋‚˜๋จธ์ง€ ์•ฑ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ฝ˜ํ…์ธ ๋ฅผ ๋” ๋นจ๋ฆฌ ๋ณด๊ณ  ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์ƒํ˜ธ์ž‘์šฉ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด [Shaundai Person](https://twitter.com/shaundai)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”: +๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด [Shaundai Person](https://twitter.com/shaundai)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”. <YouTubeIframe src="https://www.youtube.com/embed/pj5N-Khihgc" title="YouTube video player" /> @@ -38,7 +38,7 @@ React 18์—๋Š” Suspense๋ฅผ ์‚ฌ์šฉํ•œ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง ์„ฑ๋Šฅ ๊ฐœ์„  ์‚ฌํ•ญ React 18์—์„œ๋Š” ์ „๋ฌธ๊ฐ€, ๊ฐœ๋ฐœ์ž, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ์ž, ๊ต์œก์ž๋“ค๋กœ ๊ตฌ์„ฑ๋œ ํŒจ๋„๊ณผ ํ˜‘๋ ฅํ•˜๊ธฐ ์œ„ํ•ด ์ฒซ ๋ฒˆ์งธ ์›Œํ‚น ๊ทธ๋ฃน์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ•จ๊ป˜ ์ ์ง„์ ์ธ ์ฑ„ํƒ ์ „๋žต์„ ์„ธ์šฐ๊ณ  `useId`, `useSyncExternalStore`, `useInsertionEffect`์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด API๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค. -์ด ์ž‘์—…์— ๋Œ€ํ•œ ๊ฐœ์š”๋Š” [Aakansha' Doshi](https://twitter.com/aakansha1216)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”: +์ด ์ž‘์—…์— ๋Œ€ํ•œ ๊ฐœ์š”๋Š” [Aakansha' Doshi](https://twitter.com/aakansha1216)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”. <YouTubeIframe src="https://www.youtube.com/embed/qn7gRClrC9U" title="YouTube video player" /> @@ -46,38 +46,38 @@ React 18์—์„œ๋Š” ์ „๋ฌธ๊ฐ€, ๊ฐœ๋ฐœ์ž, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ด€๋ฆฌ์ž, ๊ต์œก์ž๋“ค ์ด๋ฒˆ ๋ฆด๋ฆฌ์ฆˆ์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ๋กœ ๊ตฌ์„ฑ๋œ React ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ํŒ€๊ณผ ๊ฐœ๋ฐœ์ž๊ฐ€ React ์•ฑ์„ ๋””๋ฒ„๊น…ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ์ƒˆ๋กœ์šด ํƒ€์ž„๋ผ์ธ ํ”„๋กœํŒŒ์ผ๋Ÿฌ๋„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. -์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ๊ณผ ๋ฐ๋ชจ๋Š” [Brian Vaughn](https://twitter.com/brian_d_vaughn)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”: +์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ๊ณผ ๋ฐ๋ชจ๋Š” [Brian Vaughn](https://twitter.com/brian_d_vaughn)์˜ ๊ฐ•์—ฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”. <YouTubeIframe src="https://www.youtube.com/embed/oxDfrke8rZg" title="YouTube video player" /> ### memo ์—†๋Š” React {/*react-without-memo*/} -๋ฏธ๋ž˜๋ฅผ ๋‚ด๋‹ค๋ณด๋ฉฐ, [Xuan Huang(้ป„็Ž„)](https://twitter.com/Huxpro)์ด ์ž๋™ ๋ฉ”๋ชจํ™” ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ React Labs ์—ฐ๊ตฌ์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ•์—ฐ์—์„œ ์ž์„ธํ•œ ์ •๋ณด์™€ ์ปดํŒŒ์ผ๋Ÿฌ ํ”„๋กœํ† ํƒ€์ž… ๋ฐ๋ชจ๋ฅผ ํ™•์ธํ•˜์„ธ์š”: +๋ฏธ๋ž˜๋ฅผ ๋‚ด๋‹ค๋ณด๋ฉฐ, [Xuan Huang(้ป„็Ž„)](https://twitter.com/Huxpro)์ด ์ž๋™ ๋ฉ”๋ชจํ™” ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ React Labs ์—ฐ๊ตฌ์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ•์—ฐ์—์„œ ์ž์„ธํ•œ ์ •๋ณด์™€ ์ปดํŒŒ์ผ๋Ÿฌ ํ”„๋กœํ† ํƒ€์ž… ๋ฐ๋ชจ๋ฅผ ํ™•์ธํ•˜์„ธ์š”. <YouTubeIframe src="https://www.youtube.com/embed/lGEMwh32soc" title="YouTube video player" /> ### React ๋ฌธ์„œ ๊ธฐ์กฐ์—ฐ์„ค {/*react-docs-keynote*/} -[Rachel Nabors](https://twitter.com/rachelnabors)๊ฐ€ React์˜ ์ƒˆ๋กœ์šด ๋ฌธ์„œ์— ๋Œ€ํ•œ ํˆฌ์ž์— ๋Œ€ํ•œ ๊ธฐ์กฐ์—ฐ์„ค๋กœ React๋กœ ํ•™์Šตํ•˜๊ณ  ๋””์ž์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ•์—ฐ์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค([ํ˜„์žฌ react.dev๋กœ ์ œ๊ณต๋จ](/blog/2023/03/16/introducing-react-dev)): +[Rachel Nabors](https://twitter.com/rachelnabors)๊ฐ€ React์˜ ์ƒˆ ๋ฌธ์„œ์— ๋Œ€ํ•œ ํˆฌ์ž์™€ ๊ด€๋ จํ•œ ๊ธฐ์กฐ์—ฐ์„ค๋กœ React๋กœ ํ•™์Šตํ•˜๊ณ  ๋””์ž์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ•์—ฐ์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ([ํ˜„์žฌ react.dev๋กœ ์ œ๊ณต๋จ](/blog/2023/03/16/introducing-react-dev).) <YouTubeIframe src="https://www.youtube.com/embed/mneDaMYOKP8" title="YouTube video player" /> ### ๊ทธ๋ฆฌ๊ณ ... {/*and-more*/} -**React๋กœ ํ•™์Šตํ•˜๊ณ  ๋””์ž์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ•์—ฐ:** +**React๋กœ ํ•™์Šตํ•˜๊ณ  ์„ค๊ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ•์—ฐ.** * Debbie O'Brien: [์ƒˆ๋กœ์šด React ๋ฌธ์„œ์—์„œ ๋ฐฐ์šด ๊ฒƒ๋“ค](https://youtu.be/-7odLW_hG7s). * Sarah Rainsberger: [๋ธŒ๋ผ์šฐ์ €์—์„œ ํ•™์Šตํ•˜๊ธฐ](https://youtu.be/5X-WEQflCL0). * Linton Ye: [React๋กœ ๋””์ž์ธํ•จ์—์„œ์˜ ROI](https://youtu.be/7cPWmID5XAk). -* Delba de Oliveira: [React๋ฅผ ์ด์šฉํ•œ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ๋†€์ดํ„ฐ](https://youtu.be/zL8cz2W0z34). +* Delba de Oliveira: [React๋ฅผ ์ด์šฉํ•œ ์ƒํ˜ธ์ž‘์šฉ ๋†€์ดํ„ฐ](https://youtu.be/zL8cz2W0z34). -**Relay, React Native, PyTorch ํŒ€์˜ ๊ฐ•์—ฐ:** +**Relay, React Native, PyTorch ํŒ€์˜ ๊ฐ•์—ฐ.** * Robert Balicki: [Relay ๋‹ค์‹œ ์†Œ๊ฐœ](https://youtu.be/lhVGdErZuN4). * Eric Rozell๊ณผ Steven Moyes: [React Native ๋ฐ์Šคํฌํ†ฑ](https://youtu.be/9L4FFrvwJwY). -* Roman Rรคdle: [React Native๋ฅผ ์œ„ํ•œ ์˜จ๋””๋ฐ”์ด์Šค ๋จธ์‹ ๋Ÿฌ๋‹](https://youtu.be/NLj73vrc2I8) +* Roman Rรคdle: [React Native๋ฅผ ์œ„ํ•œ ์˜จ๋””๋ฐ”์ด์Šค ๋จธ์‹ ๋Ÿฌ๋‹](https://youtu.be/NLj73vrc2I8). -**์ ‘๊ทผ์„ฑ, ํˆด๋ง ๋ฐ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฐ•์—ฐ:** +**์ ‘๊ทผ์„ฑ, ํˆด๋ง ๋ฐ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฐ•์—ฐ.** * Daishi Kato: [์™ธ๋ถ€ ์Šคํ† ์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์œ„ํ•œ React 18](https://youtu.be/oPfSC5bQPR8). * Diego Haz: [React 18์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์ถ•ํ•˜๊ธฐ](https://youtu.be/dcm8fjBfro8). @@ -112,12 +112,12 @@ React.js Conf 2016์˜ ์˜์ƒ ํ”Œ๋ ˆ์ด๋ฆฌ์ŠคํŠธ. React.js Conf 2015์˜ ์˜์ƒ ํ”Œ๋ ˆ์ด๋ฆฌ์ŠคํŠธ. <YouTubeIframe title="React.js Conf 2015" src="https://www.youtube-nocookie.com/embed/playlist?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr" /> -### Best Practices ๋‹ค์‹œ ์ƒ๊ฐํ•ด ๋ณด๊ธฐ {/*rethinking-best-practices*/} +### Best Practice ๋‹ค์‹œ ์ƒ๊ฐํ•ด ๋ณด๊ธฐ {/*rethinking-best-practices*/} -JSConf EU 2013์—์„œ Pete Hunt์˜ ๊ฐ•์—ฐ: ํ…œํ”Œ๋ฆฟ ๊ฐœ๋…์„ ๋ฒ„๋ฆฌ๊ณ  JavaScript๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ view๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•, ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์ „์ฒด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ "re-rendering"ํ•˜๋Š” ๋ฐฉ๋ฒ•, DOM ๋ฐ ์ด๋ฒคํŠธ๋ฅผ ๊ฒฝ๋Ÿ‰์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ• ๋“ฑ ์„ธ ๊ฐ€์ง€ ์ฃผ์ œ๋ฅผ ๋‹ค๋ฃจ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. - (2013 - 0h30m). +JSConf EU 2013์—์„œ Pete Hunt์˜ ๊ฐ•์—ฐ. ํ…œํ”Œ๋ฆฟ ๊ฐœ๋…์„ ๋ฒ„๋ฆฌ๊ณ  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ทฐ<sup>View</sup>๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•, ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์ „์ฒด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฆฌ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ๋ฒ•, DOM ๋ฐ ์ด๋ฒคํŠธ๋ฅผ ๊ฒฝ๋Ÿ‰์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ• ๋“ฑ ์„ธ ๊ฐ€์ง€ ์ฃผ์ œ๋ฅผ ๋‹ค๋ฃจ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. (2013 - 0h30m). <YouTubeIframe title="Pete Hunt: React: Rethinking Best Practices - JSConf EU 2013" src="https://www.youtube-nocookie.com/embed/x7cQ3mrcKaY" /> -### React ์†Œ๊ฐœํ•˜๊ธฐ {/*introduction-to-react*/} +### React ์†Œ๊ฐœ {/*introduction-to-react*/} -Facebook Seattle์—์„œ Tom Occhino์™€ Jordan Walke์˜ React ์†Œ๊ฐœ - (2013 - 1h20m). +Facebook Seattle์—์„œ Tom Occhino์™€ Jordan Walke์˜ React ์†Œ๊ฐœ (2013 - 1h20m). <YouTubeIframe title="Tom Occhino and Jordan Walke introduce React at Facebook Seattle" src="https://www.youtube-nocookie.com/embed/XxVg_s8xAms" /> diff --git a/src/sidebarCommunity.json b/src/sidebarCommunity.json index d3a9d8171..3918c05ee 100644 --- a/src/sidebarCommunity.json +++ b/src/sidebarCommunity.json @@ -20,7 +20,7 @@ "path": "/community/meetups" }, { - "title": "React ๋น„๋””์˜ค", + "title": "React ์˜์ƒ", "path": "/community/videos" }, { From b1387b09dafd74764c0788ac9326e2a64824f36b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 19:02:53 +0900 Subject: [PATCH 0367/1059] docs: update `docs-contributors` --- src/content/community/docs-contributors.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/content/community/docs-contributors.md b/src/content/community/docs-contributors.md index b49fefb56..ba1a1c8af 100644 --- a/src/content/community/docs-contributors.md +++ b/src/content/community/docs-contributors.md @@ -4,7 +4,7 @@ title: ๋ฌธ์„œ ๊ธฐ์—ฌ์ž <Intro> -React ๋ฌธ์„œ๋Š” [React ํŒ€](/community/team) ๊ณผ [์™ธ๋ถ€ ๊ธฐ์—ฌ์ž](https://github.com/reactjs/react.dev/graphs/contributors)์— ์˜ํ•ด ์ž‘์„ฑ๋˜๊ณ  ์œ ์ง€๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด ํŽ˜์ด์ง€์—์„œ, ์‚ฌ์ดํŠธ์— ์ƒ๋‹นํ•œ ๊ธฐ์—ฌ๋ฅผ ํ•œ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๊ฐ์‚ฌ๋ฅผ ์ „ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. +React ๋ฌธ์„œ๋Š” [React ํŒ€](/community/team)๊ณผ [์™ธ๋ถ€ ๊ธฐ์—ฌ์ž](https://github.com/reactjs/react.dev/graphs/contributors)์— ์˜ํ•ด ์ž‘์„ฑ๋˜๊ณ  ์œ ์ง€๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด ํŽ˜์ด์ง€์—์„œ, ์‚ฌ์ดํŠธ์— ์ƒ๋‹นํ•œ ๊ธฐ์—ฌ๋ฅผ ํ•œ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๊ฐ์‚ฌ๋ฅผ ์ „ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. </Intro> @@ -39,4 +39,8 @@ React ๋ฌธ์„œ๋Š” [React ํŒ€](/community/team) ๊ณผ [์™ธ๋ถ€ ๊ธฐ์—ฌ์ž](https://git * [Harish Kumar](https://www.strek.in/): ๊ฐœ๋ฐœ๊ณผ ์œ ์ง€๋ณด์ˆ˜ * [Luna Ruan](https://twitter.com/lunaruan): Sandbox ๊ฐœ์„  -์šฐ๋ฆฌ๋Š” ๊ธธ์„ ๋”ฐ๋ผ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•œ ์ˆ˜ ๋งŽ์€ ์•ŒํŒŒ ํ…Œ์Šคํ„ฐ๋“ค๊ณผ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฉค๋ฒ„๋“ค์—๊ฒŒ๋„ ๊ฐ์‚ฌ๋ฅผ ์ „ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. +## ํ•œ๊ตญ์–ด ๋ฒˆ์—ญ {/*korean-translations*/} + +* [๋ฃจ๋ฐ€(LuMir)](https://github.com/lumirlumir): ์‚ฌ์ดํŠธ ๊ฐœ๋ฐœ, ์œ ์ง€๋ณด์ˆ˜, ๋ฒˆ์—ญ ๋“ฑ + +์ €ํฌ์—๊ฒŒ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•œ ์ˆ˜ ๋งŽ์€ ์•ŒํŒŒ ํ…Œ์Šคํ„ฐ๋“ค๊ณผ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฉค๋ฒ„๋“ค์—๊ฒŒ๋„ ๊ฐ์‚ฌ๋ฅผ ์ „ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. From 3e688e338aa33db9d87eeab6af81d4383a8037e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 19:07:23 +0900 Subject: [PATCH 0368/1059] docs: update `acknowledgements.md` --- src/content/community/acknowledgements.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/content/community/acknowledgements.md b/src/content/community/acknowledgements.md index 5726771b3..1f5f4dcf4 100644 --- a/src/content/community/acknowledgements.md +++ b/src/content/community/acknowledgements.md @@ -35,6 +35,7 @@ React๋Š” ์›๋ž˜ [Jordan Walke](https://github.com/jordwalke)์— ์˜ํ•ด ๋งŒ๋“ค์–ด * [Josh Duck](https://github.com/joshduck) * [Joe Critchley](https://github.com/joecritch) * [Jeff Morrison](https://github.com/jeffmo) +* [LuMir](https://github.com/lumirlumir) * [Luna Ruan](https://github.com/lunaruan) * [Kathryn Middleton](https://github.com/kmiddleton14) * [Keyan Zhang](https://github.com/keyz) @@ -59,7 +60,7 @@ React๋Š” ์›๋ž˜ [Jordan Walke](https://github.com/jordwalke)์— ์˜ํ•ด ๋งŒ๋“ค์–ด ์ด ๋ชฉ๋ก์ด ์ „์ฒด ๋ชฉ๋ก์€ ์•„๋‹™๋‹ˆ๋‹ค. -์ˆ˜๋…„๊ฐ„ ์ง€๋„์™€ ์ง€์›์„ ์ฃผ์‹  [Tom Occhino](https://github.com/tomocchino)์™€ [Adam Wolff](https://github.com/wolffiex)์—๊ฒŒ ํŠน๋ณ„ํ•œ ๊ฐ์‚ฌ๋ฅผ ๋“œ๋ฆฝ๋‹ˆ๋‹ค. [React๋ฅผ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋ฒˆ์—ญํ•œ](https://translations.react.dev/) ๋ชจ๋“  ์ž์›๋ด‰์‚ฌ์ž์—๊ฒŒ๋„ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. +์ˆ˜๋…„๊ฐ„ ์ง€๋„์™€ ์ง€์›์„ ์ฃผ์‹  [Tom Occhino](https://github.com/tomocchino)์™€ [Adam Wolff](https://github.com/wolffiex)์—๊ฒŒ ํŠน๋ณ„ํ•œ ๊ฐ์‚ฌ๋ฅผ ๋“œ๋ฆฝ๋‹ˆ๋‹ค. [React๋ฅผ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋ฒˆ์—ญํ•œ](https://translations.react.dev/) [๋ฃจ๋ฐ€(LuMir)](https://github.com/lumirlumir) ๋ฐ ๋ชจ๋“  ์ž์›๋ด‰์‚ฌ์ž์—๊ฒŒ๋„ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ## ํŠน๋ณ„ํ•œ ๊ฐ์‚ฌ ์ธ์‚ฌ {/*additional-thanks*/} From d6deb02fa001bf507b26c16e8a5d68f8982ee80f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 19:40:31 +0900 Subject: [PATCH 0369/1059] docs: update `versioning-policy.md` --- src/content/community/versioning-policy.md | 46 +++++++++++----------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/content/community/versioning-policy.md b/src/content/community/versioning-policy.md index 241619139..3516d5f5e 100644 --- a/src/content/community/versioning-policy.md +++ b/src/content/community/versioning-policy.md @@ -3,19 +3,21 @@ title: ๋ฒ„์ „ ๊ด€๋ฆฌ ์ •์ฑ… --- <Intro> -React์˜ ๋ชจ๋“  ์•ˆ์ •์ ์ธ ๋นŒ๋“œ๋Š” ๋†’์€ ์ˆ˜์ค€์˜ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์น˜๊ณ  ์‹œ๋งจํ‹ฑ ๋ฒ„์ „(semver)์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. React๋Š” ๋˜ํ•œ ์‹คํ—˜์ ์ธ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ดˆ๊ธฐ ํ”ผ๋“œ๋ฐฑ์„ ์žฅ๋ คํ•˜๊ธฐ ์œ„ํ•ด ๋ถˆ์•ˆ์ •ํ•œ ๋ฆด๋ฆฌ์Šค ์ฑ„๋„์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ํŽ˜์ด์ง€์—์„œ๋Š” React ๋ฆด๋ฆฌ์Šค์—์„œ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์— ๊ด€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. +React์˜ ๋ชจ๋“  ์•ˆ์ •์ ์ธ ๋นŒ๋“œ๋Š” ๋†’์€ ์ˆ˜์ค€์˜ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์น˜๊ณ  ์œ ์˜์  ๋ฒ„์ „<sup>Sementic Versioning, semver</sup>์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. React๋Š” ๋˜ํ•œ ์‹คํ—˜์ ์ธ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ดˆ๊ธฐ ํ”ผ๋“œ๋ฐฑ์„ ์žฅ๋ คํ•˜๊ธฐ ์œ„ํ•ด ๋ถˆ์•ˆ์ •ํ•œ ๋ฆด๋ฆฌ์Šค ์ฑ„๋„์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ํŽ˜์ด์ง€์—์„œ๋Š” React ๋ฆด๋ฆฌ์Šค์—์„œ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. </Intro> -์ง€๋‚œ ๋ฒ„์ „์„ ํ™•์ธํ•˜๋ ค๋ฉด, [Versions](/versions) ํŽ˜์ด์ง€๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. +์ง€๋‚œ ๋ฒ„์ „์„ ํ™•์ธํ•˜๋ ค๋ฉด, [React ๋ฒ„์ „](/versions) ํŽ˜์ด์ง€๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”. ## Stable releases {/*stable-releases*/} +Stable React releases (also known as โ€œLatestโ€ release channel) follow [semantic versioning (semver)](https://semver.org/lang/ko/) principles. + ๋ฒ„์ „ ๋ฒˆํ˜ธ **x.y.z**๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. * **์น˜๋ช…์ ์ธ ๋ฒ„๊ทธ ์ˆ˜์ •**์„ ๋ฆด๋ฆฌ์ฆˆํ•  ๋•Œ๋Š” **ํŒจ์น˜ ๋ฆด๋ฆฌ์ฆˆ**๋ฅผ ๋งŒ๋“ค์–ด **z** ์ˆซ์ž๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: 15.6.2์—์„œ 15.6.3์œผ๋กœ) * **์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ**์ด๋‚˜ **์น˜๋ช…์ ์ด์ง€ ์•Š์€ ๋ฒ„๊ทธ ์ˆ˜์ •**์„ ๋ฆด๋ฆฌ์ฆˆํ•  ๋•Œ๋Š” **๋งˆ์ด๋„ˆ ๋ฆด๋ฆฌ์ฆˆ**๋ฅผ ๋งŒ๋“ค์–ด **y** ์ˆซ์ž๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: 15.6.2์—์„œ 15.7.0์œผ๋กœ) -* **breaking changes**๋ฅผ ๋ฆด๋ฆฌ์ฆˆํ•  ๋•Œ๋Š” **๋ฉ”์ด์ € ๋ฆด๋ฆฌ์ฆˆ**๋ฅผ ๋งŒ๋“ค์–ด **x** ์ˆซ์ž๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: 15.6.2์—์„œ 16.0.0์œผ๋กœ) +* **Breaking Change**๋ฅผ ๋ฆด๋ฆฌ์ฆˆํ•  ๋•Œ๋Š” **๋ฉ”์ด์ € ๋ฆด๋ฆฌ์ฆˆ**๋ฅผ ๋งŒ๋“ค์–ด **x** ์ˆซ์ž๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ: 15.6.2์—์„œ 16.0.0์œผ๋กœ) ๋ฉ”์ด์ € ๋ฆด๋ฆฌ์ฆˆ๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํฌํ•จํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์–ด๋–ค ๋ฆด๋ฆฌ์ฆˆ๋“  ๋ฒ„๊ทธ ์ˆ˜์ •์„ ํฌํ•จํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -23,28 +25,28 @@ React์˜ ๋ชจ๋“  ์•ˆ์ •์ ์ธ ๋นŒ๋“œ๋Š” ๋†’์€ ์ˆ˜์ค€์˜ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์น˜๊ณ  ### Breaking Changes {/*breaking-changes*/} -Breaking Changes๋Š” ๋ชจ๋‘์—๊ฒŒ ๋ถˆํŽธํ•˜๊ธฐ์— ์šฐ๋ฆฌ๋Š” ๋ฉ”์ด์ € ๋ฆด๋ฆฌ์ฆˆ์˜ ์ˆ˜๋ฅผ ์ตœ์†Œํ™”ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, React 15๋Š” 2016๋…„ 4์›”์— ๋ฆด๋ฆฌ์ฆˆ๋˜์—ˆ๊ณ , React 16์€ 2017๋…„ 9์›”์— ๋ฆด๋ฆฌ์ฆˆ๋˜์—ˆ๊ณ , React 17์€ 2020๋…„ 10์›”์— ๋ฆด๋ฆฌ์ฆˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +Breaking Changes๋Š” ๋ชจ๋‘์—๊ฒŒ ๋ถˆํŽธํ•˜๊ธฐ์— ์šฐ๋ฆฌ๋Š” ๋ฉ”์ด์ € ๋ฆด๋ฆฌ์ฆˆ์˜ ์ˆ˜๋ฅผ ์ตœ์†Œํ™”ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, React 15๋Š” 2016๋…„ 4์›”์— ๋ฆด๋ฆฌ์ฆˆ, React 16์€ 2017๋…„ 9์›”์— ๋ฆด๋ฆฌ์ฆˆ, React 17์€ 2020๋…„ 10์›”์— ๋ฆด๋ฆฌ์ฆˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์„ ๋งˆ์ด๋„ˆ ๋ฒ„์ „์œผ๋กœ ๋ฆด๋ฆฌ์ฆˆํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋งˆ์ด๋„ˆ ๋ฆด๋ฆฌ์ฆˆ๊ฐ€ ๊ทธ ์ด๋ฆ„์ด ๋œ ์ฃผ๋ชฉ๋ฐ›์„์ง€๋ผ๋„ ์ข…์ข… ๋ฉ”์ด์ € ๋ฆด๋ฆฌ์ฆˆ๋ณด๋‹ค ๋” ํฅ๋ฏธ๋กœ์šฐ๋ฉฐ ๋งค๋ ฅ์ ์ด๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ### ์•ˆ์ •์„ฑ์— ๊ธฐ์—ฌํ•˜๊ธฐ {/*commitment-to-stability*/} -์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ React๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ, ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋…ธ๋ ฅ์„ ์ตœ์†Œํ™”ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ, ์˜ค๋ž˜๋œ API๋ฅผ ๋ณ„๊ฐœ์˜ ํŒจํ‚ค์ง€์— ๋„ฃ๋Š” ํ•œ์ด ์žˆ๋”๋ผ๋„ ์ž‘๋™ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, [๋ฏน์Šค์ธ์€ ๋ช‡ ๋…„ ๋™์•ˆ ๊ถŒ์žฅ๋˜์ง€ ์•Š์•˜์ง€๋งŒ](https://legacy.reactjs.org/blog/2016/07/13/mixins-considered-harmful.html) [`create-react-class`๋ฅผ ํ†ตํ•ด](https://legacy.reactjs.org/docs/react-without-es6.html#mixins) ์ง€๊ธˆ๊นŒ์ง€ ์ง€์›๋˜๊ณ  ์žˆ์œผ๋ฉฐ, ๋งŽ์€ ์ฝ”๋“œ๋ฒ ์ด์Šค๊ฐ€ ์ด๋ฅผ ์•ˆ์ •์ ์ธ ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ๋กœ ๊ณ„์† ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ React๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ, ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋…ธ๋ ฅ์„ ์ตœ์†Œํ™”ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ, ์˜ค๋ž˜๋œ API๋ฅผ ๋ณ„๊ฐœ์˜ ํŒจํ‚ค์ง€์— ๋„ฃ๋Š” ํ•œ์ด ์žˆ๋”๋ผ๋„ ์ž‘๋™ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, [๋ฏน์Šค์ธ<sup>Mixin</sup>์€ ๋ช‡ ๋…„ ๋™์•ˆ ๊ถŒ์žฅ๋˜์ง€ ์•Š์•˜์ง€๋งŒ](https://legacy.reactjs.org/blog/2016/07/13/mixins-considered-harmful.html) [`create-react-class`๋ฅผ ํ†ตํ•ด](https://legacy.reactjs.org/docs/react-without-es6.html#mixins) ์ง€๊ธˆ๊นŒ์ง€ ์ง€์›ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ๋งŽ์€ ์ฝ”๋“œ๋ฒ ์ด์Šค๊ฐ€ ์ด๋ฅผ ์•ˆ์ •์ ์ธ ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ๋กœ ๊ณ„์† ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -100๋งŒ ๋ช… ์ด์ƒ์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ React๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ์ˆ˜๋ฐฑ๋งŒ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ผ๊ด„์ ์œผ๋กœ ์œ ์ง€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์Šค๋ถ ์ฝ”๋“œ๋ฒ ์ด์Šค์—๋งŒ 5๋งŒ๊ฐœ๊ฐ€ ๋„˜๋Š” React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ƒˆ๋กœ์šด React ๋ฒ„์ „์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์„ ๊ฐ€๋Šฅํ•œ ํ•œ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ณผ์ • ์—†์ด ํฐ ๋ณ€ํ™”๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด, ์‚ฌ๋žŒ๋“ค์€ ์˜ค๋ž˜๋œ ๋ฒ„์ „์— ๊ฐ‡ํžˆ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŽ˜์ด์Šค๋ถ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ ๊ณผ์ •์„ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค. 10 ๋ช…์ด ๋˜์ง€ ์•Š๋Š” ์šฐ๋ฆฌ ํŒ€์ด 5๋งŒ ๊ฐœ๊ฐ€ ๋„˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, React๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์ด๋ผ๋ฉด ๋ˆ„๊ตฌ๋‚˜ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ, ์šฐ๋ฆฌ๋Š” ์ปดํฌ๋„ŒํŠธ ๋ฌธ๋ฒ•์„ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ธฐ ์œ„ํ•ด [์ž๋™ํ™”๋œ ๋ช…๋ น๋ฌธ](https://github.com/reactjs/react-codemod)์„ ์ž‘์„ฑํ•˜๊ณ , ์ด๋ฅผ ์˜คํ”ˆ์†Œ์Šค ๋ฆด๋ฆฌ์ฆˆ์— ํฌํ•จํ•ด ๋ชจ๋‘๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. +100๋งŒ ๋ช… ์ด์ƒ์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ React๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ์ˆ˜๋ฐฑ๋งŒ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ผ๊ด„์ ์œผ๋กœ ์œ ์ง€ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์Šค๋ถ ์ฝ”๋“œ๋ฒ ์ด์Šค์—๋งŒ 5๋งŒ๊ฐœ๊ฐ€ ๋„˜๋Š” React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ƒˆ๋กœ์šด React ๋ฒ„์ „์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์„ ๊ฐ€๋Šฅํ•œ ํ•œ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ณผ์ • ์—†์ด ํฐ ๋ณ€ํ™”๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด, ์‚ฌ๋žŒ๋“ค์€ ์˜ค๋ž˜๋œ ๋ฒ„์ „์— ๊ฐ‡ํžˆ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŽ˜์ด์Šค๋ถ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ ๊ณผ์ •์„ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค. 10๋ช…์ด ๋˜์ง€ ์•Š๋Š” ์ €ํฌ ํŒ€์ด 5๋งŒ ๊ฐœ๊ฐ€ ๋„˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, React๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์ด๋ผ๋ฉด ๋ˆ„๊ตฌ๋‚˜ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ, ์šฐ๋ฆฌ๋Š” ์ปดํฌ๋„ŒํŠธ ๋ฌธ๋ฒ•์„ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ธฐ ์œ„ํ•ด [์ž๋™ํ™”๋œ ๋ช…๋ น๋ฌธ](https://github.com/reactjs/react-codemod)์„ ์ž‘์„ฑํ•˜๊ณ , ์ด๋ฅผ ์˜คํ”ˆ์†Œ์Šค ๋ฆด๋ฆฌ์ฆˆ์— ํฌํ•จํ•ด ๋ชจ๋‘๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ### ๊ฒฝ๊ณ ๋ฅผ ํ™œ์šฉํ•œ ์ ์ง„์  ์—…๊ทธ๋ ˆ์ด๋“œ {/*gradual-upgrades-via-warnings*/} -React์˜ ๊ฐœ๋ฐœ ๋นŒ๋“œ์—๋Š” ์œ ์šฉํ•œ ๊ฒฝ๊ณ ๊ฐ€ ๋งŽ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ, ์šฐ๋ฆฌ๋Š” ๋ฏธ๋ž˜์˜ breaking changes๋ฅผ ์œ„ํ•ด ๊ฒฝ๊ณ ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ์•ฑ์— ์ตœ์‹  ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•œ ๊ฒฝ๊ณ ๊ฐ€ ์—†๋‹ค๋ฉด, ๋‹ค์Œ ๋ฉ”์ด์ € ๋ฆด๋ฆฌ์ฆˆ์™€ ํ˜ธํ™˜๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์•ฑ์„ ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ์”ฉ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. +React์˜ ๊ฐœ๋ฐœ ๋นŒ๋“œ์—๋Š” ์œ ์šฉํ•œ ๊ฒฝ๊ณ ๊ฐ€ ๋งŽ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ, ์šฐ๋ฆฌ๋Š” ๋ฏธ๋ž˜์˜ Breaking Change๋ฅผ ์œ„ํ•ด ๊ฒฝ๊ณ ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์„ ๋”ฐ๋ฅด๋ฉด, ์ตœ์‹  ๋ฆด๋ฆฌ์Šค์—์„œ ๊ฒฝ๊ณ ๊ฐ€ ์—†๋Š” ์•ฑ์€ ๋‹ค์Œ ๋ฉ”์ด์ € ๋ฆด๋ฆฌ์Šค์™€ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์•ฑ์„ ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ์”ฉ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. -๊ฐœ๋ฐœ ๋นŒ๋“œ์—์„œ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒฝ๊ณ ๋Š” ์•ฑ์˜ ๋Ÿฐํƒ€์ž„ ๋™์ž‘์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๊ฐœ๋ฐœ ๋นŒ๋“œ์™€ ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ ๊ฐ„ ์•ฑ์ด ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•  ๊ฒƒ์ด๋ผ๋Š” ํ™•์‹ ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- ์œ ์ผํ•œ ์ฐจ์ด์ ์€ ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ์—์„œ ๊ฒฝ๊ณ ๊ฐ€ ์ถœ๋ ฅ๋˜์ง€ ์•Š๊ณ  ๋” ํšจ์œจ์ ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. (๋งŒ์•ฝ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด, ์ด์Šˆ๋ฅผ ์ œ์ถœํ•ด ์ฃผ์„ธ์š”.) +๊ฐœ๋ฐœ ๋นŒ๋“œ์—์„œ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒฝ๊ณ ๋Š” ์•ฑ์˜ ๋Ÿฐํƒ€์ž„ ๋™์ž‘์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๊ฐœ๋ฐœ ๋นŒ๋“œ์™€ ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ ๊ฐ„ ์•ฑ์ด ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•  ๊ฒƒ์ด๋ผ๋Š” ํ™•์‹ ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ ์ผํ•œ ์ฐจ์ด์ ์€ ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ์—์„œ ๊ฒฝ๊ณ ๊ฐ€ ์ถœ๋ ฅ๋˜์ง€ ์•Š๊ณ  ๋” ํšจ์œจ์ ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. (๋งŒ์•ฝ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด, ์ด์Šˆ๋ฅผ ์ œ์ถœํ•ด ์ฃผ์„ธ์š”.) -### ์–ด๋–ค ๊ฒƒ๋“ค์ด breaking change๋กœ ๊ฐ„์ฃผ๋˜๋‚˜์š”? {/*what-counts-as-a-breaking-change*/} +### ์–ด๋–ค ๊ฒƒ๋“ค์ด Breaking Change๋กœ ๊ฐ„์ฃผ๋˜๋‚˜์š”? {/*what-counts-as-a-breaking-change*/} ์ผ๋ฐ˜์ ์œผ๋กœ, ๋‹ค์Œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋“ค์€ ๋ฉ”์ด์ € ๋ฒ„์ „ ๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ *์•Š์Šต๋‹ˆ๋‹ค*. -* **๊ฐœ๋ฐœ ๋นŒ๋“œ ๊ฒฝ๊ณ .** ํ”„๋กœ๋•์…˜ ๋™์ž‘์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์šฐ๋ฆฌ๋Š” ๋ฉ”์ด์ € ๋ฒ„์ „ ์‚ฌ์ด์— ์ƒˆ๋กœ์šด ๊ฒฝ๊ณ ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ๊ฒฝ๊ณ ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์•ž์œผ๋กœ ๋‹ค๊ฐ€์˜ฌ breaking changes์— ๋Œ€ํ•ด ์•ˆ์ •์ ์œผ๋กœ ๊ฒฝ๊ณ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* **๊ฐœ๋ฐœ ๋นŒ๋“œ ๊ฒฝ๊ณ .** ํ”„๋กœ๋•์…˜ ๋™์ž‘์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์šฐ๋ฆฌ๋Š” ๋ฉ”์ด์ € ๋ฒ„์ „ ์‚ฌ์ด์— ์ƒˆ๋กœ์šด ๊ฒฝ๊ณ ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ๊ฒฝ๊ณ ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์•ž์œผ๋กœ ๋‹ค๊ฐ€์˜ฌ Breaking Change์— ๋Œ€ํ•ด ์•ˆ์ •์ ์œผ๋กœ ๊ฒฝ๊ณ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **`unstable_`๋กœ ์‹œ์ž‘ํ•˜๋Š” API.** ์ด API๋“ค์€ ์•„์ง ํ™•์ •๋˜์ง€ ์•Š์€ ์‹คํ—˜์  ๊ธฐ๋Šฅ๋“ค๋กœ์„œ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. `unstable_` ์ ‘๋‘์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋“ค์„ ๋ฆด๋ฆฌ์ฆˆํ•จ์œผ๋กœ์จ, ๋” ๋น ๋ฅด๊ฒŒ ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ๋ฐ˜๋ณตํ•˜๊ณ  ์•ˆ์ •์ ์ธ API์— ๋” ๋น ๋ฅด๊ฒŒ ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -* **Alpha ๋ฒ„์ „๊ณผ ์นด๋‚˜๋ฆฌ ๋ฒ„์ „์˜ React.** ์ด๋ฅธ ์‹œ์ผ ๋‚ด์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด Alpha ๋ฒ„์ „์˜ React๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, Alpha ๊ธฐ๊ฐ„ ๋™์•ˆ ๋ฐฐ์šด ๊ฒƒ์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์ฆˆ ์ด์ „์— API๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Œ์„ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +* **Alpha ๋ฒ„์ „๊ณผ Canary ๋ฒ„์ „์˜ React.** ์ด๋ฅธ ์‹œ์ผ ๋‚ด์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด Alpha ๋ฒ„์ „์˜ React๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, Alpha ๊ธฐ๊ฐ„ ๋™์•ˆ ๋ฐฐ์šด ๊ฒƒ์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์ฆˆ ์ด์ „์— API๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Œ์„ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. * **๋ฌธ์„œํ™”๋˜์ง€ ์•Š์€ API์™€ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ.** `__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`๋‚˜ `__reactInternalInstance$uk43rzhitjg`์™€ ๊ฐ™์€ ๋‚ด๋ถ€ ์†์„ฑ ์ด๋ฆ„์— ์ ‘๊ทผํ•˜๋Š” ๊ฒฝ์šฐ, ์ด์— ๋Œ€ํ•œ ๋ณด์žฅ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋‹น์‹  ์Šค์Šค๋กœ ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ๊ณจ๋จธ๋ฆฌ๋ฅผ ์•“๋Š” ๊ฒƒ์„ ๋ฐ”๋ผ์ง€ ์•Š๊ธฐ์—, ์ด ์ •์ฑ…์€ ์‹ค์šฉ์ ์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ด๋Ÿฌํ•œ ๋ณ€ํ™”๋ฅผ ๋ชจ๋‘ ๋ฉ”์ด์ € ๋ฒ„์ „์œผ๋กœ ๋ฆด๋ฆฌ์ฆˆํ•œ๋‹ค๋ฉด, ๋” ๋งŽ์€ ๋ฉ”์ด์ € ๋ฒ„์ „์„ ๋ฆด๋ฆฌ์ฆˆํ•˜๊ฒŒ ๋˜๊ณ , ๊ถ๊ทน์ ์œผ๋กœ ๋ฒ„์ „ ๊ด€๋ฆฌ์— ๋Œ€ํ•ด ์ปค๋ฎค๋‹ˆํ‹ฐ์— ๋” ๋งŽ์€ ๊ณ ํ†ต์„ ์•ผ๊ธฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋งŒํผ React๋ฅผ ๋น ๋ฅด๊ฒŒ ๊ฐœ์„ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. @@ -63,11 +65,11 @@ React์˜ ๊ฐœ๋ฐœ ๋นŒ๋“œ์—๋Š” ์œ ์šฉํ•œ ๊ฒฝ๊ณ ๊ฐ€ ๋งŽ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ ์ธํ•ด, ํŒจ์น˜ ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ฒ„๊ทธ์™€ ๋ณด์•ˆ ์ทจ์•ฝ์ ์— ๋Œ€ํ•ด์„œ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -๋งŒ์•ฝ ๋ฆด๋ฆฌ์ฆˆ์— ๋‚ด๋ถ€์ ์ธ ๋ฆฌํŒฉํ„ฐ, ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์˜ ๋ณ€๊ฒฝ, ์„ฑ๋Šฅ ๊ฐœ์„ , ์ž‘์€ ๋ฒ„๊ทธ ์ˆ˜์ •๊ณผ ๊ฐ™์€ ํ•„์ˆ˜์ ์ด์ง€ ์•Š์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํฌํ•จ๋œ๋‹ค๋ฉด, ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์—†์–ด๋„ ๋งˆ์ด๋„ˆ ๋ฒ„์ „์„ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค. +๋งŒ์•ฝ ๋ฆด๋ฆฌ์ฆˆ์— ๋‚ด๋ถ€์ ์ธ ๋ฆฌํŒฉํ† ๋ง, ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์˜ ๋ณ€๊ฒฝ, ์„ฑ๋Šฅ ๊ฐœ์„ , ์ž‘์€ ๋ฒ„๊ทธ ์ˆ˜์ •๊ณผ ๊ฐ™์€ ํ•„์ˆ˜์ ์ด์ง€ ์•Š์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํฌํ•จ๋œ๋‹ค๋ฉด, ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์—†์–ด๋„ ๋งˆ์ด๋„ˆ ๋ฒ„์ „์„ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค. ## ๋ชจ๋“  ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„ {/*all-release-channels*/} -React๋Š” ๋ฒ„๊ทธ์˜ ์ œ์ถœ, ํ’€ ๋ฆฌํ€˜์ŠคํŠธ์˜ ์ƒ์„ฑ, [RFC์˜ ์ œ์ถœ](https://github.com/reactjs/rfcs)์„ ์œ„ํ•ด ํ™œ๋ฐœํ•œ ์˜คํ”ˆ์†Œ์Šค ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ํ”ผ๋“œ๋ฐฑ์„ ์žฅ๋ คํ•˜๊ธฐ ์œ„ํ•ด ๋•Œ๋•Œ๋กœ ๋ฆด๋ฆฌ์ฆˆ๋˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๋Š” ํŠน๋ณ„ํ•œ ๋นŒ๋“œ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. +React๋Š” ๋ฒ„๊ทธ ์ œ์ถœ, ํ’€ ๋ฆฌํ€˜์ŠคํŠธ ์ƒ์„ฑ, [RFC ์ œ์ถœ](https://github.com/reactjs/rfcs)์„ ์œ„ํ•ด ํ™œ๋ฐœํ•œ ์˜คํ”ˆ์†Œ์Šค ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ํ”ผ๋“œ๋ฐฑ์„ ์žฅ๋ คํ•˜๊ธฐ ์œ„ํ•ด ๋•Œ๋•Œ๋กœ ๋ฆด๋ฆฌ์ฆˆ๋˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๋Š” ํŠน๋ณ„ํ•œ ๋นŒ๋“œ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. <Note> @@ -77,16 +79,16 @@ React๋Š” ๋ฒ„๊ทธ์˜ ์ œ์ถœ, ํ’€ ๋ฆฌํ€˜์ŠคํŠธ์˜ ์ƒ์„ฑ, [RFC์˜ ์ œ์ถœ](https://g ๊ฐ๊ฐ์˜ React ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„์€ ์„œ๋กœ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -- [**์ตœ์‹  ์ฑ„๋„**](#latest-channel)์€ ์•ˆ์ •์ ์ธ ์‹œ๋งจํ‹ฑ ๋ฒ„์ „ React ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์œ„ํ•œ ์ฑ„๋„์ž…๋‹ˆ๋‹ค. npm์—์„œ React๋ฅผ ์„ค์น˜ํ•  ๋•Œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ์ฑ„๋„์€ ๋‹น์‹ ์ด ์ด๋ฏธ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์ฑ„๋„์ž…๋‹ˆ๋‹ค. **React๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ด ์ฑ„๋„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.** +- [**์ตœ์‹  ์ฑ„๋„**](#latest-channel)์€ ์•ˆ์ •์ ์ธ ์‹œ๋งจํ‹ฑ ๋ฒ„์ „ React ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์œ„ํ•œ ์ฑ„๋„์ž…๋‹ˆ๋‹ค. npm์—์„œ React๋ฅผ ์„ค์น˜ํ•  ๋•Œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ์ฑ„๋„์€ ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด ์ด๋ฏธ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์ฑ„๋„์ž…๋‹ˆ๋‹ค. **React๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ด ์ฑ„๋„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.** - [**์นด๋‚˜๋ฆฌ ์ฑ„๋„**](#canary-channel)์€ React ์ €์žฅ์†Œ์˜ ๋ฉ”์ธ ๋ธŒ๋žœ์น˜๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ๋‹ค์Œ ์‹œ๋งจํ‹ฑ ๋ฒ„์ „ ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์œ„ํ•œ ๋ฆด๋ฆฌ์ฆˆ ํ›„๋ณด๋กœ ๊ฐ„์ฃผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **[ํ”„๋ ˆ์ž„์›Œํฌ๋‚˜ ์—„์„ ๋œ ์„ค์ •์—์„œ ๊ณ ์ • ๋ฒ„์ „์˜ React์™€ ํ•จ๊ป˜ ์ด ์ฑ„๋„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.](/blog/2023/05/03/react-canaries) ๋˜ํ•œ React์™€ ์„œ๋“œํŒŒํ‹ฐ ํ”„๋กœ์ ํŠธ ๊ฐ„์˜ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์นด๋‚˜๋ฆฌ ์ฑ„๋„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** - [**์‹คํ—˜์  ์ฑ„๋„**](#experimental-channel)์€ ์•„์ง ์•ˆ์ •๋œ ๋ฆด๋ฆฌ์ฆˆ์— ํฌํ•จ๋˜์ง€ ์•Š์€ ์‹คํ—˜์ ์ธ API์™€ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ ํ”Œ๋ž˜๊ทธ๋ฅผ ํ™œ์„ฑํ™”ํ•œ ์ฑ„๋กœ ๋ฉ”์ธ ๋ธŒ๋žœ์น˜๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ด ์ฑ„๋„์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆด๋ฆฌ์ฆˆ๋˜๊ธฐ ์ „์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๋ฆด๋ฆฌ์ฆˆ๋Š” npm์— ๊ณต๊ฐœ๋˜์ง€๋งŒ, ์ตœ์‹  ์ฑ„๋„๋งŒ ์‹œ๋งจํ‹ฑ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์ „ ๋ฆด๋ฆฌ์ฆˆ(์นด๋‚˜๋ฆฌ ์ฑ„๋„๊ณผ ์‹คํ—˜์  ์ฑ„๋„)๋Š” ๋ฆด๋ฆฌ์ฆˆ์˜ ๋‚ด์šฉ๊ณผ ์ปค๋ฐ‹ ๋‚ ์งœ์˜ ํ•ด์‹œ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์นด๋‚˜๋ฆฌ ์ฑ„๋„์˜ ๊ฒฝ์šฐ `18.3.0-canary-388686f29-20230503`์ด๊ณ , ์‹คํ—˜์  ์ฑ„๋„์˜ ๊ฒฝ์šฐ `0.0.0-experimental-388686f29-20230503`์ž…๋‹ˆ๋‹ค. -**์ตœ์‹  ์ฑ„๋„๊ณผ ์นด๋‚˜๋ฆฌ ์ฑ„๋„ ๋ชจ๋‘ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•ด ๊ณต์‹์ ์œผ๋กœ ์ง€์›๋˜์ง€๋งŒ, ๊ธฐ๋Œ€ํ•˜๋Š” ๋ฐ”๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค.** +**์ตœ์‹  ์ฑ„๋„๊ณผ ์นด๋‚˜๋ฆฌ ์ฑ„๋„ ๋ชจ๋‘ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜์ง€๋งŒ, ๊ธฐ๋Œ€ํ•˜๋Š” ๋ฐ”๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค.** * ์ตœ์‹  ์ฑ„๋„ ๋ฆด๋ฆฌ์ฆˆ๋Š” ์ „ํ†ต์ ์ธ ์‹œ๋งจํ‹ฑ ๋ฒ„์ „ ๋ชจ๋ธ์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. -* ์นด๋‚˜๋ฆฌ ๋ฆด๋ฆฌ์ฆˆ๋Š” [๊ณ ์ • ๋ฒ„์ „](/blog/2023/05/03/react-canaries)์ด์–ด์•ผ ํ•˜๋ฉฐ, breaking changes๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์ฒด์ ์ธ ๋ฆด๋ฆฌ์ฆˆ ์ผ์ •์— ๋”ฐ๋ผ ์ƒˆ๋กœ์šด React ๊ธฐ๋Šฅ๊ณผ ๋ฒ„๊ทธ ์ˆ˜์ •์„ ์ ์ง„์ ์œผ๋กœ ๋ฆด๋ฆฌ์ฆˆํ•˜๊ณ ์ž ํ•˜๋Š” ์—„์„ ๋œ ์„ค์ •(ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ฐ™์€)์„ ์œ„ํ•ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. +* ์นด๋‚˜๋ฆฌ ๋ฆด๋ฆฌ์ฆˆ๋Š” [๊ณ ์ • ๋ฒ„์ „](/blog/2023/05/03/react-canaries)์ด์–ด์•ผ ํ•˜๋ฉฐ, Breaking Changes๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์ฒด์ ์ธ ๋ฆด๋ฆฌ์ฆˆ ์ผ์ •์— ๋”ฐ๋ผ ์ƒˆ๋กœ์šด React ๊ธฐ๋Šฅ๊ณผ ๋ฒ„๊ทธ ์ˆ˜์ •์„ ์ ์ง„์ ์œผ๋กœ ๋ฆด๋ฆฌ์ฆˆํ•˜๊ณ ์ž ํ•˜๋Š” ์—„์„ ๋œ ์„ค์ •(ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ฐ™์€)์„ ์œ„ํ•ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ๋Š” ํ…Œ์ŠคํŠธ ๋ชฉ์ ์œผ๋กœ๋งŒ ์ œ๊ณต๋˜๋ฉฐ ๋ฆด๋ฆฌ์ฆˆ ๊ฐ„์— ๋™์ž‘์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๋ณด์žฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ์ฑ„๋„ ๋ฆด๋ฆฌ์ฆˆ์— ์‚ฌ์šฉํ•˜๋Š” ์‹œ๋งจํ‹ฑ ๋ฒ„์ „ ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @@ -96,7 +98,7 @@ React๋Š” ๋ฒ„๊ทธ์˜ ์ œ์ถœ, ํ’€ ๋ฆฌํ€˜์ŠคํŠธ์˜ ์ƒ์„ฑ, [RFC์˜ ์ œ์ถœ](https://g ์ตœ์‹  ์ฑ„๋„์€ ์•ˆ์ •๋œ React ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์œ„ํ•œ ์ฑ„๋„์ž…๋‹ˆ๋‹ค. npm์˜ `latest` ํƒœ๊ทธ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ตœ์‹  ์ฑ„๋„์€ ์‹ค์ œ ์‚ฌ์šฉ์ž๋“ค์ด ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋Š” ๋ชจ๋“  React ์•ฑ์— ๋Œ€ํ•œ ๊ถŒ์žฅ ์ฑ„๋„์ž…๋‹ˆ๋‹ค. -**๋งŒ์•ฝ ์–ด๋–ค ์ฑ„๋„์„ ์‚ฌ์šฉํ•ด์•ผ ํ• ์ง€ ๋ถˆํ™•์‹คํ•˜๋‹ค๋ฉด, ์ตœ์‹  ์ฑ„๋„์„ ์‚ฌ์šฉํ•˜์„ธ์š”.** ์ง์ ‘์ ์œผ๋กœ React๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ์ด๋ฏธ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์ฑ„๋„์ž…๋‹ˆ๋‹ค. ์ตœ์‹  ์ฑ„๋„์˜ ์—…๋ฐ์ดํŠธ๋Š” ๋งค์šฐ ์•ˆ์ •์ ์ด๋ผ๊ณ  ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์ฆˆ](#stable-releases)์—์„œ ์„ค๋ช…ํ–ˆ๋“ฏ, ๋ฒ„์ „์€ ์‹œ๋งจํ‹ฑ ๋ฒ„์ „ ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. +**๋งŒ์•ฝ ์–ด๋–ค ์ฑ„๋„์„ ์‚ฌ์šฉํ•ด์•ผ ํ• ์ง€ ๋ถˆํ™•์‹คํ•˜๋‹ค๋ฉด, ์ตœ์‹  ์ฑ„๋„์„ ์‚ฌ์šฉํ•˜์„ธ์š”.** ์ง์ ‘์ ์œผ๋กœ React๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ์ด๋ฏธ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์ฑ„๋„์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ตœ์‹  ์ฑ„๋„์˜ ์—…๋ฐ์ดํŠธ๋Š” ๋งค์šฐ ์•ˆ์ •์ ์ด๋ผ๊ณ  ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์ฆˆ](#stable-releases)์—์„œ ์„ค๋ช…ํ–ˆ๋“ฏ, ๋ฒ„์ „์€ ์‹œ๋งจํ‹ฑ ๋ฒ„์ „ ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ### ์นด๋‚˜๋ฆฌ ์ฑ„๋„ {/*canary-channel*/} @@ -137,11 +139,11 @@ Next.js๋Š” ์ด ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋กœ ์นด๋‚˜๋ฆฌ ์ฑ„๋„๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์‹คํ—˜์  ์ฑ„๋„์€ React ์ €์žฅ์†Œ์˜ ๋ฉ”์ธ ๋ธŒ๋žœ์น˜๋ฅผ ๋”ฐ๋ฅด๋Š” ์‚ฌ์ „ ๋ฆด๋ฆฌ์ฆˆ ์ฑ„๋„์ž…๋‹ˆ๋‹ค. ์นด๋‚˜๋ฆฌ ์ฑ„๋„๊ณผ ๋‹ฌ๋ฆฌ, ์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ์—๋Š” ๋” ๊ด‘๋ฒ”์œ„ํ•œ ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์œ„ํ•ด ์ค€๋น„๋˜์ง€ ์•Š์€ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ๊ณผ API๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. -ํ†ต์ƒ์ ์œผ๋กœ, ์นด๋‚˜๋ฆฌ ์ฑ„๋„์˜ ์—…๋ฐ์ดํŠธ๋Š” ์ƒ์‘ํ•˜๋Š” ์‹คํ—˜์  ์ฑ„๋„์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๋™๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ์†Œ์Šค ๋ฒ„์ „์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์ง€๋งŒ, ๋‹ค๋ฅธ ๊ธฐ๋Šฅ ํ”Œ๋ž˜๊ทธ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ ๋นŒ๋“œ๋ฉ๋‹ˆ๋‹ค. +ํ†ต์ƒ์ ์œผ๋กœ, ์นด๋‚˜๋ฆฌ ์ฑ„๋„์˜ ์—…๋ฐ์ดํŠธ๋Š” ์ƒ์‘ํ•˜๋Š” ์‹คํ—˜์  ์ฑ„๋„์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๋™๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ์†Œ์Šค ๋ฒ„์ „์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์ง€๋งŒ, ๋‹ค๋ฅธ ๊ธฐ๋Šฅ ํ”Œ๋ž˜๊ทธ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค. -์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ๋Š” ์นด๋‚˜๋ฆฌ ์ฑ„๋„์ด๋‚˜ ์ตœ์‹  ์ฑ„๋„ ๋ฆด๋ฆฌ์ฆˆ์™€ ํฌ๊ฒŒ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”.** ์‹คํ—˜์  ์ฑ„๋„์˜ ๋ฆด๋ฆฌ์ฆˆ ์‚ฌ์ด์—๋Š” ์ž์ฃผ breaking changes์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ๋Š” ์นด๋‚˜๋ฆฌ ์ฑ„๋„์ด๋‚˜ ์ตœ์‹  ์ฑ„๋„ ๋ฆด๋ฆฌ์ฆˆ์™€ ํฌ๊ฒŒ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”.** ์‹คํ—˜์  ์ฑ„๋„์˜ ๋ฆด๋ฆฌ์ฆˆ ์‚ฌ์ด์—๋Š” ์ž์ฃผ Breaking Change๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ๋Š” npm์— 'experimental' ํƒœ๊ทธ์™€ ํ•จ๊ป˜ ๊ฒŒ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋ฒ„์ „์€ `0.0.0-experimental-68053d940-20210623`์™€ ๊ฐ™์ด ๋นŒ๋“œ ๋‚ด์šฉ๊ณผ ์ปค๋ฐ‹ ๋‚ ์งœ์˜ ํ•ด์‹œ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. +์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ๋Š” npm์— `experimental` ํƒœ๊ทธ์™€ ํ•จ๊ป˜ ๊ฒŒ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋ฒ„์ „์€ `0.0.0-experimental-68053d940-20210623`์™€ ๊ฐ™์ด ๋นŒ๋“œ ๋‚ด์šฉ๊ณผ ์ปค๋ฐ‹ ๋‚ ์งœ์˜ ํ•ด์‹œ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. #### ์‹คํ—˜์  ๋ฆด๋ฆฌ์ฆˆ์—๋Š” ๋ฌด์—‡์ด ํฌํ•จ๋˜๋‚˜์š”? {/*what-goes-into-an-experimental-release*/} @@ -157,6 +159,6 @@ Next.js๋Š” ์ด ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋กœ ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ๋“ค์€ [RFC](https://github.com/reactjs/rfcs)๊ฐ€ ํ•จ๊ป˜ ์ œ๊ณต๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ƒˆ๋กœ์šด ์‹คํ—˜์  ๊ธฐ๋Šฅ๋“ค์ด ์ค€๋น„๋˜๋ฉด [React ๋ธ”๋กœ๊ทธ](/blog)์— ๊ฒŒ์‹œ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ๋ชจ๋“  ์‹คํ—˜์  ๊ธฐ๋Šฅ๋“ค์„ ๊ณต๊ฐœํ•œ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. +์ƒˆ๋กœ์šด ์‹คํ—˜์  ๊ธฐ๋Šฅ๋“ค์ด ์ค€๋น„๋˜๋ฉด [React ๋ธ”๋กœ๊ทธ](/blog)์— ๊ฒŒ์‹œ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ๋ชจ๋“  ์‹คํ—˜์  ๊ธฐ๋Šฅ๋“ค์„ ๊ณต๊ฐœํ•œ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. -๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ๋ณด๋‹ค ์ž์„ธํ•œ ๋‚ด์šฉ์€ Github ์ €์žฅ์†Œ์˜ [์ปค๋ฐ‹ ๋กœ๊ทธ](https://github.com/facebook/react/commits/main)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ๋ณด๋‹ค ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊นƒํ—ˆ๋ธŒ ์ €์žฅ์†Œ์˜ [์ปค๋ฐ‹ ๋กœ๊ทธ](https://github.com/facebook/react/commits/main)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. From 4a51b083e38fe7d5d6e7e2ca8ed7faab3a367d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 19:46:25 +0900 Subject: [PATCH 0370/1059] docs: update `reference/react/index.md` --- src/content/reference/react/index.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/content/reference/react/index.md b/src/content/reference/react/index.md index 1caced987..e454d60f4 100644 --- a/src/content/reference/react/index.md +++ b/src/content/reference/react/index.md @@ -1,20 +1,20 @@ --- -title: React ์ฐธ์กฐ ๊ฐœ์š” +title: React ์ฐธ๊ณ ์„œ ๊ฐœ์š” --- <Intro> -์ด ์„น์…˜์€ React์™€ ๊ด€๋ จ๋œ ์ž‘์—…์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์ฐธ์กฐ ๋ฌธ์„œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. React์— ๋Œ€ํ•œ ์†Œ๊ฐœ๋Š” [ํ•™์Šต](/learn) ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. +์ด ์„น์…˜์€ React์™€ ๊ด€๋ จ๋œ ์ž‘์—…์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ์ฐธ๊ณ ์„œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. React์— ๋Œ€ํ•œ ์†Œ๊ฐœ๋Š” [ํ•™์Šต](/learn) ์„น์…˜์„ ์ฐธ์กฐํ•˜์„ธ์š”. </Intro> -React ์ฐธ์กฐ ๋ฌธ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์ ์ธ ํ•˜์œ„ ์„น์…˜์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. +React ์ฐธ๊ณ ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์ ์ธ ํ•˜์œ„ ์„น์…˜์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ## React {/*react*/} React์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋Šฅ. -* [Hooks](/reference/react/hooks) - ์ปดํฌ๋„ŒํŠธ์—์„œ ๋‹ค์–‘ํ•œ React ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์„ธ์š”. +* [Hook](/reference/react/hooks) - ์ปดํฌ๋„ŒํŠธ์—์„œ ๋‹ค์–‘ํ•œ React ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์„ธ์š”. * [์ปดํฌ๋„ŒํŠธ](/reference/react/components) - JSX์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด์žฅ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. * [API](/reference/react/apis) - ์ปดํฌ๋„ŒํŠธ ์ •์˜์— ์œ ์šฉํ•œ API๋“ค์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. * [์ง€์‹œ์–ด](/reference/rsc/directives) - React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ ํ˜ธํ™˜๋˜๋Š” ๋ฒˆ๋“ค๋Ÿฌ์—๊ฒŒ ์ง€์‹œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. @@ -23,20 +23,20 @@ React์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋Šฅ. React DOM์€ ๋ธŒ๋ผ์šฐ์ € DOM ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋งŒ ์ง€์›๋˜๋Š” ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์„น์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜๋‰ฉ๋‹ˆ๋‹ค. -* [Hooks](/reference/react-dom/hooks) - ๋ธŒ๋ผ์šฐ์ € DOM ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ Hooks์ž…๋‹ˆ๋‹ค. +* [Hook](/reference/react-dom/hooks) - ๋ธŒ๋ผ์šฐ์ € DOM ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ Hook์ž…๋‹ˆ๋‹ค. * [์ปดํฌ๋„ŒํŠธ](/reference/react-dom/components) - React๋Š” ๋ธŒ๋ผ์šฐ์ € ๋‚ด์žฅ HTML ๋ฐ SVG ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ชจ๋‘ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -* [API](/reference/react-dom) - `react-dom` ํŒจํ‚ค์ง€์—๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋งŒ ์ง€์›๋˜๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. +* [API](/reference/react-dom) - `react-dom` ํŒจํ‚ค์ง€์—๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋งŒ ์ง€์›๋˜๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. * [ํด๋ผ์ด์–ธํŠธ API](/reference/react-dom/client) - `react-dom/client` API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €์—์„œ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * [์„œ๋ฒ„ API](/reference/react-dom/server) - `react-dom/server` API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„์—์„œ React ์ปดํฌ๋„ŒํŠธ๋ฅผ HTML๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ## React์˜ ๊ทœ์น™ {/*rules-of-react*/} -React์—๋Š” ํŒจํ„ด์„ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ํ•˜๋ฉฐ ๊ณ ํ’ˆ์งˆ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ์ผ์ข…์˜ ๊ทœ์น™ ํ˜น์€ ๋ชจ๋ฒ”์ ์ธ ๋ฐฉ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. +React์—๋Š” ํŒจํ„ด ์ดํ•ด๋ฅผ ์‰ฝ๊ฒŒ ํ•˜๋ฉฐ ๊ณ ํ’ˆ์งˆ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ์ผ์ข…์˜ ๊ทœ์น™ ํ˜น์€ ๋ชจ๋ฒ”์ ์ธ ๋ฐฉ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. * [์ปดํฌ๋„ŒํŠธ์™€ Hook์€ ์ˆœ์ˆ˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure) โ€“ ์ˆœ์ˆ˜์„ฑ์€ ์ฝ”๋“œ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•˜๊ณ  ๋””๋ฒ„๊ทธํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋ฉฐ, React๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ปดํฌ๋„ŒํŠธ์™€ Hook์„ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. * [React๊ฐ€ ์ปดํฌ๋„ŒํŠธ์™€ Hook์„ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ์‹](/reference/rules/react-calls-components-and-hooks) โ€“ React๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์ปดํฌ๋„ŒํŠธ์™€ Hook์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. -* [Hook์˜ ๊ทœ์น™](/reference/rules/rules-of-hooks) โ€“ Hook์€ JavaScript ํ•จ์ˆ˜๋กœ ์ •์˜๋˜์ง€๋งŒ ํ˜ธ์ถœ ์œ„์น˜์— ์ œ์•ฝ์ด ์žˆ๋Š” ํŠน๋ณ„ํ•œ ์œ ํ˜•์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ UI ๋กœ์ง์ž…๋‹ˆ๋‹ค. +* [Hook์˜ ๊ทœ์น™](/reference/rules/rules-of-hooks) โ€“ Hook์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜๋กœ ์ •์˜๋˜์ง€๋งŒ ํ˜ธ์ถœ ์œ„์น˜์— ์ œ์•ฝ์ด ์žˆ๋Š” ํŠน๋ณ„ํ•œ ์œ ํ˜•์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ UI ๋กœ์ง์ž…๋‹ˆ๋‹ค. ## ๋ ˆ๊ฑฐ์‹œ API {/*legacy-apis*/} -* [๋ ˆ๊ฑฐ์‹œ API](/reference/react/legacy) - `react` ํŒจํ‚ค์ง€์—์„œ ๋‚ด๋ณด๋‚ธ ๊ฒƒ์ด์ง€๋งŒ ์ƒˆ๋กœ ์ž‘์„ฑ๋˜๋Š” ์ฝ”๋“œ์—์„œ๋Š” ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +* [๋ ˆ๊ฑฐ์‹œ API](/reference/react/legacy) - `react` ํŒจํ‚ค์ง€์—์„œ ๋‚ด๋ณด๋‚ธ ๊ฒƒ์ด์ง€๋งŒ ์ƒˆ๋กœ ์ž‘์„ฑํ•˜๋Š” ์ฝ”๋“œ์—์„œ๋Š” ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. From e28d7a051b1a5f9ef39aed67e65f47386be67316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 19:59:27 +0900 Subject: [PATCH 0371/1059] docs: update `legacy.md` --- src/content/reference/react/index.md | 2 +- src/content/reference/react/legacy.md | 37 ++++++++------------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/content/reference/react/index.md b/src/content/reference/react/index.md index e454d60f4..e8245b21b 100644 --- a/src/content/reference/react/index.md +++ b/src/content/reference/react/index.md @@ -39,4 +39,4 @@ React์—๋Š” ํŒจํ„ด ์ดํ•ด๋ฅผ ์‰ฝ๊ฒŒ ํ•˜๋ฉฐ ๊ณ ํ’ˆ์งˆ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ## ๋ ˆ๊ฑฐ์‹œ API {/*legacy-apis*/} -* [๋ ˆ๊ฑฐ์‹œ API](/reference/react/legacy) - `react` ํŒจํ‚ค์ง€์—์„œ ๋‚ด๋ณด๋‚ธ ๊ฒƒ์ด์ง€๋งŒ ์ƒˆ๋กœ ์ž‘์„ฑํ•˜๋Š” ์ฝ”๋“œ์—์„œ๋Š” ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +* [๋ ˆ๊ฑฐ์‹œ API](/reference/react/legacy) - `react` ํŒจํ‚ค์ง€์—์„œ ๋‚ด๋ณด๋ƒˆ์ง€๋งŒ<sup>Exported</sup> ์ƒˆ๋กœ ์ž‘์„ฑํ•  ์ฝ”๋“œ์—์„œ๋Š” ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. diff --git a/src/content/reference/react/legacy.md b/src/content/reference/react/legacy.md index 9127bae91..b744d8756 100644 --- a/src/content/reference/react/legacy.md +++ b/src/content/reference/react/legacy.md @@ -1,10 +1,10 @@ --- -title: "Legacy React APIs" +title: "Legacy React API" --- <Intro> -์ด API๋Š” `react` ํŒจํ‚ค์ง€์—์„œ ์ถ”์ถœํ–ˆ์ง€๋งŒ ์ƒˆ๋กœ ์ž‘์„ฑํ•  ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ์„ ์ถ”์ฒœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ํ†ตํ•ด ๊ฐ๊ฐ์˜ API ํŽ˜์ด์ง€์—์„œ ์ œ์‹œํ•œ ๋Œ€์•ˆ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”. +์•„๋ž˜ API๋Š” `react` ํŒจํ‚ค์ง€์—์„œ ๋‚ด๋ณด๋ƒˆ์ง€๋งŒ<sup>Exported</sup> ์ƒˆ๋กœ ์ž‘์„ฑํ•  ์ฝ”๋“œ์—์„œ๋Š” ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ํ†ตํ•ด ๊ฐ๊ฐ์˜ API ํŽ˜์ด์ง€์—์„œ ์ œ์‹œํ•œ ๋Œ€์•ˆ์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”. </Intro> @@ -12,42 +12,25 @@ title: "Legacy React APIs" ## Legacy APIs {/*legacy-apis*/} -<<<<<<< HEAD -* [`Children`](/reference/react/Children)์€ `children` prop์œผ๋กœ ๋ฐ›์€ JSX๋ฅผ ์กฐ์ž‘ํ•˜๊ณ  ๋ณ€ํ˜•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [๋Œ€์•ˆ ํ™•์ธํ•˜๊ธฐ](/reference/react/Children#alternatives) -* [`cloneElement`](/reference/react/cloneElement)๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์‹œ์ž‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [๋Œ€์•ˆ ํ™•์ธํ•˜๊ธฐ](/reference/react/cloneElement#alternatives) -* [`Component`](/reference/react/Component)๋Š” Javascript ํด๋ž˜์Šค๋กœ์จ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. [๋Œ€์•ˆ ํ™•์ธํ•˜๊ธฐ](/reference/react/Component#alternatives) +* [`Children`](/reference/react/Children)์€ `children` Prop์œผ๋กœ ๋ฐ›์€ JSX๋ฅผ ์กฐ์ž‘ํ•˜๊ณ  ๋ณ€ํ˜•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [๋Œ€์•ˆ ํ™•์ธํ•˜๊ธฐ](/reference/react/Children#alternatives). +* [`cloneElement`](/reference/react/cloneElement)๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์‹œ์ž‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [๋Œ€์•ˆ ํ™•์ธํ•˜๊ธฐ](/reference/react/cloneElement#alternatives). +* [`Component`](/reference/react/Component)๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค๋กœ์จ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. [๋Œ€์•ˆ ํ™•์ธํ•˜๊ธฐ](/reference/react/Component#alternatives). * [`createElement`](/reference/react/createElement)๋กœ React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ JSX๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -* [`createRef`](/reference/react/createRef)๋Š” ์ž„์˜์˜ ๊ฐ’์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ์ฐธ์กฐ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. [๋Œ€์•ˆ ํ™•์ธํ•˜๊ธฐ](/reference/react/createRef#alternatives) +* [`createRef`](/reference/react/createRef)๋Š” ์ž„์˜์˜ ๊ฐ’์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ์ฐธ์กฐ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. [๋Œ€์•ˆ ํ™•์ธํ•˜๊ธฐ](/reference/react/createRef#alternatives). +* [`forwardRef`](/reference/react/forwardRef) lets your component expose a DOM node to parent component with a [ref](/learn/manipulating-the-dom-with-refs). * [`isValidElement`](/reference/react/isValidElement)๋Š” ๊ฐ’์˜ React ์—˜๋ฆฌ๋จผํŠธ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ [`cloneElement`](/reference/react/cloneElement)์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -* [`PureComponent`](/reference/react/PureComponent)๋Š” [`Component`](/reference/react/Component)์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ, ๋™์ผํ•œ props์˜ ์žฌ๋ Œ๋”๋Š” ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค. [๋Œ€์•ˆ ํ™•์ธํ•˜๊ธฐ](/reference/react/PureComponent#alternatives) -======= -* [`Children`](/reference/react/Children) lets you manipulate and transform the JSX received as the `children` prop. [See alternatives.](/reference/react/Children#alternatives) -* [`cloneElement`](/reference/react/cloneElement) lets you create a React element using another element as a starting point. [See alternatives.](/reference/react/cloneElement#alternatives) -* [`Component`](/reference/react/Component) lets you define a React component as a JavaScript class. [See alternatives.](/reference/react/Component#alternatives) -* [`createElement`](/reference/react/createElement) lets you create a React element. Typically, you'll use JSX instead. -* [`createRef`](/reference/react/createRef) creates a ref object which can contain arbitrary value. [See alternatives.](/reference/react/createRef#alternatives) -* [`forwardRef`](/reference/react/forwardRef) lets your component expose a DOM node to parent component with a [ref.](/learn/manipulating-the-dom-with-refs) -* [`isValidElement`](/reference/react/isValidElement) checks whether a value is a React element. Typically used with [`cloneElement`.](/reference/react/cloneElement) -* [`PureComponent`](/reference/react/PureComponent) is similar to [`Component`,](/reference/react/Component) but it skip re-renders with same props. [See alternatives.](/reference/react/PureComponent#alternatives) ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +* [`PureComponent`](/reference/react/PureComponent)๋Š” [`Component`](/reference/react/Component)์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ, ๋™์ผํ•œ Prop์˜ ์žฌ๋ Œ๋”๋ง์€ ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค. [๋Œ€์•ˆ ํ™•์ธํ•˜๊ธฐ](/reference/react/PureComponent#alternatives). --- ## Removed APIs {/*removed-apis*/} -These APIs were removed in React 19: +์•„๋ž˜ API๋“ค์€ React 19์—์„œ ์ œ๊ฑฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. -<<<<<<< HEAD -์ด API๋Š” ์ถ”ํ›„ React major ๋ฒ„์ „์—์„œ ์ œ๊ฑฐ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. - -</Deprecated> - -* [`createFactory`](/reference/react/createFactory)๋Š” ํŠน์ • ์œ ํ˜•์˜ React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. -======= * [`createFactory`](https://18.react.dev/reference/react/createFactory): use JSX instead. * Class Components: [`static contextTypes`](https://18.react.dev//reference/react/Component#static-contexttypes): use [`static contextType`](#static-contexttype) instead. * Class Components: [`static childContextTypes`](https://18.react.dev//reference/react/Component#static-childcontexttypes): use [`static contextType`](#static-contexttype) instead. * Class Components: [`static getChildContext`](https://18.react.dev//reference/react/Component#getchildcontext): use [`Context.Provider`](/reference/react/createContext#provider) instead. * Class Components: [`static propTypes`](https://18.react.dev//reference/react/Component#static-proptypes): use a type system like [TypeScript](https://www.typescriptlang.org/) instead. * Class Components: [`this.refs`](https://18.react.dev//reference/react/Component#refs): use [`createRef`](/reference/react/createRef) instead. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc + From 74d59fdaa916c5d2c645fea3149d2163c0e42516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 20:25:23 +0900 Subject: [PATCH 0372/1059] docs: update `Children.md` --- src/content/reference/react/Children.md | 60 ++++++++++++------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/content/reference/react/Children.md b/src/content/reference/react/Children.md index d1955b689..470b75c69 100644 --- a/src/content/reference/react/Children.md +++ b/src/content/reference/react/Children.md @@ -4,13 +4,13 @@ title: Children <Pitfall> -`Children`์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์ด์ง€ ์•Š๊ณ  ์ทจ์•ฝํ•œ ์ฝ”๋“œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์•ˆ์„ ์‚ดํŽด๋ณด์„ธ์š”.](#alternatives) +`Children`์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์ด์ง€ ์•Š๊ณ  ๋ถˆ์•ˆ์ •ํ•œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์•ˆ์„ ์‚ดํŽด๋ณด์„ธ์š”.](#alternatives) </Pitfall> <Intro> -`Children`์„ ์‚ฌ์šฉํ•ด์„œ [`children` prop](/learn/passing-props-to-a-component#passing-jsx-as-children)๋กœ ๋ฐ›์€ JSX๋ฅผ ์กฐ์ž‘ํ•˜๊ณ  ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`Children`์„ ์‚ฌ์šฉํ•ด์„œ [`children` Prop](/learn/passing-props-to-a-component#passing-jsx-as-children)๋กœ ๋ฐ›์€ JSX๋ฅผ ์กฐ์ž‘ํ•˜๊ณ  ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js const mappedChildren = Children.map(children, child => @@ -46,11 +46,11 @@ function RowList({ children }) { } ``` -[์•„๋ž˜ ์˜ˆ์‹œ ๋ณด๊ธฐ](#counting-children) +[์•„๋ž˜ ์˜ˆ์‹œ ๋ณด๊ธฐ](#counting-children). #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*children-count-parameters*/} -* `children`: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ [`children` prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์˜ ๊ฐ’. +* `children`: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ [`children` Prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์˜ ๊ฐ’. #### ๋ฐ˜ํ™˜๊ฐ’ {/*children-count-returns*/} @@ -58,7 +58,7 @@ function RowList({ children }) { #### ์ฃผ์˜ ์‚ฌํ•ญ {/*children-count-caveats*/} -- ๋นˆ ๋…ธ๋“œ(`null`, `undefined` ํ˜น์€ Boolean), ๋ฌธ์ž์—ด, ์ˆซ์ž, [React ์—˜๋ฆฌ๋จผํŠธ](/reference/react/createElement)๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐ์—ด ์ž์ฒด๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ ๋ฐฐ์—ด์˜ ์ž์‹ ์š”์†Œ๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. **React ์—˜๋ฆฌ๋จผํŠธ์˜ ํ•˜์œ„ ์š”์†Œ๋Š” ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** React ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์œผ๋ฉฐ ์ž์‹ ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. [Fragments](/reference/react/Fragment) ์—ญ์‹œ ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +- ๋นˆ ๋…ธ๋“œ(`null`, `undefined` ํ˜น์€ Boolean), ๋ฌธ์ž์—ด, ์ˆซ์ž, [React ์—˜๋ฆฌ๋จผํŠธ](/reference/react/createElement)๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐ์—ด ์ž์ฒด๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ ๋ฐฐ์—ด์˜ ์ž์‹ ์š”์†Œ๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. **React ์—˜๋ฆฌ๋จผํŠธ์˜ ํ•˜์œ„ ์š”์†Œ๋Š” ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** React ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์œผ๋ฉฐ ์ž์‹ ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. [Fragment](/reference/react/Fragment) ์—ญ์‹œ ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. --- @@ -78,11 +78,11 @@ function SeparatorList({ children }) { // ... ``` -[์•„๋ž˜ ์˜ˆ์‹œ ๋ณด๊ธฐ](#running-some-code-for-each-child) +[์•„๋ž˜ ์˜ˆ์‹œ ๋ณด๊ธฐ](#running-some-code-for-each-child). #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*children-foreach-parameters*/} -* `children`: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ [`children` prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์˜ ๊ฐ’. +* `children`: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ [`children` Prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์˜ ๊ฐ’. * `fn`: [๋ฐฐ์—ด์˜`forEach` ๋ฉ”์„œ๋“œ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) ์ฝœ๋ฐฑ์ฒ˜๋Ÿผ ๊ฐ ์ž์‹ ์š”์†Œ์—์„œ ์‹คํ–‰ํ•  ํ•จ์ˆ˜. ์ž์‹ ์š”์†Œ๋ฅผ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ, ์ธ๋ฑ์Šค๋ฅผ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค๋Š” 0์—์„œ ์‹œ์ž‘ํ•ด์„œ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. * **optional** `thisArg`: `fn` ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์‚ฌ์šฉ๋  [`this`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)์˜ ๊ฐ’. ์ƒ๋žต ์‹œ `undefined`๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. @@ -116,11 +116,11 @@ function RowList({ children }) { } ``` -[์•„๋ž˜ ์˜ˆ์‹œ ๋ณด๊ธฐ](#transforming-children) +[์•„๋ž˜ ์˜ˆ์‹œ ๋ณด๊ธฐ](#transforming-children). #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*children-map-parameters*/} -* `children`: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ [`children` prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์˜ ๊ฐ’. +* `children`: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ [`children` Prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์˜ ๊ฐ’. * `fn`: [๋ฒ ์—ด์˜ `map` ๋ฉ”์„œ๋“œ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) ์ฝœ๋ฐฑ๊ฐ™์€ ๋งคํ•‘ ํ•จ์ˆ˜. ์ž์‹ ์š”์†Œ๋ฅผ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ, ์ธ๋ฑ์Šค๋ฅผ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค๋Š” 0์—์„œ ์‹œ์ž‘ํ•ด์„œ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋Š” ๋นˆ ๋…ธ๋“œ(`null`, `undefined` ํ˜น์€ Boolean), ๋ฌธ์ž์—ด, ์ˆซ์ž, React ์—˜๋ฆฌ๋จผํŠธ ํ˜น์€ ๋‹ค๋ฅธ React ๋…ธ๋“œ์˜ ๋ฐฐ์—ด๊ณผ ๊ฐ™์€ React ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. * **optional** `thisArg`: `fn` ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์‚ฌ์šฉ๋  [`this`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)์˜ ๊ฐ’. ์ƒ๋žต์‹œ `undefined`๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. @@ -151,12 +151,12 @@ function Box({ children }) { #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*children-only-parameters*/} -* `children`: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ [`children` prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์˜ ๊ฐ’. +* `children`: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ [`children` Prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์˜ ๊ฐ’. #### ๋ฐ˜ํ™˜๊ฐ’ {/*children-only-returns*/} `children`์ด [์œ ํšจํ•œ ์—˜๋ฆฌ๋จผํŠธ](/reference/react/isValidElement)๋ผ๋ฉด ๊ทธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด, ์—๋Ÿฌ๋ฅผ throwํ•ฉ๋‹ˆ๋‹ค. +๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด, ์—๋Ÿฌ๋ฅผ ๋˜์ง‘๋‹ˆ๋‹ค. #### ์ฃผ์˜ ์‚ฌํ•ญ {/*children-only-caveats*/} @@ -179,7 +179,7 @@ export default function ReversedList({ children }) { #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*children-toarray-parameters*/} -* `children`: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ [`children` prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์˜ ๊ฐ’. +* `children`: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ [`children` Prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์˜ ๊ฐ’. #### ๋ฐ˜ํ™˜๊ฐ’ {/*children-toarray-returns*/} @@ -188,7 +188,7 @@ export default function ReversedList({ children }) { #### ์ฃผ์˜ ์‚ฌํ•ญ {/*children-toarray-caveats*/} -- ๋นˆ ๋…ธ๋“œ(`null`, `undefined`, ํ˜น์€ Booleans)๋Š” ๋ฐ˜ํ™˜๋œ ๋ฐฐ์—ด์—์„œ ์ƒ๋žต๋ฉ๋‹ˆ๋‹ค. **๋ฐ˜ํ™˜๋œ ์—˜๋ฆฌ๋จผํŠธ์˜ key๋Š” ๊ธฐ์กด ์—˜๋ฆฌ๋จผํŠธ์˜ key, ์ค‘์ฒฉ ์ˆ˜์ค€๊ณผ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐ๋˜๋ฏ€๋กœ** ๋ฐฐ์—ด์„ ํ‰๋ฉดํ™”ํ•˜๋”๋ผ๋„ ๋™์ž‘์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +- ๋นˆ ๋…ธ๋“œ(`null`, `undefined`, ํ˜น์€ Boolean)๋Š” ๋ฐ˜ํ™˜๋œ ๋ฐฐ์—ด์—์„œ ์ƒ๋žต๋ฉ๋‹ˆ๋‹ค. **๋ฐ˜ํ™˜๋œ ์—˜๋ฆฌ๋จผํŠธ์˜ key๋Š” ๊ธฐ์กด ์—˜๋ฆฌ๋จผํŠธ์˜ key, ์ค‘์ฒฉ ์ˆ˜์ค€๊ณผ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐ๋˜๋ฏ€๋กœ** ๋ฐฐ์—ด์„ ํ‰๋ฉดํ™”ํ•˜๋”๋ผ๋„ ๋™์ž‘์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. --- @@ -196,7 +196,7 @@ export default function ReversedList({ children }) { ### `children` ๋ณ€ํ™˜ํ•˜๊ธฐ {/*transforming-children*/} -`Children.map`์€ [`children` prop๋กœ ๋ฐ›์€](/learn/passing-props-to-a-component#passing-jsx-as-children) JSX๋ฅผ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +`Children.map`์€ [`children` Prop๋กœ ๋ฐ›์€](/learn/passing-props-to-a-component#passing-jsx-as-children) JSX๋ฅผ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ```js {6,10} import { Children } from 'react'; @@ -214,7 +214,7 @@ function RowList({ children }) { } ``` -์œ„ ์˜ˆ์‹œ์—์„œ `RowList`๋Š” ๋ชจ๋“  ์ž์‹ ์š”์†Œ๋ฅผ `<div className="Row">`๋กœ ๊ฐ์‹ธ์ค๋‹ˆ๋‹ค. ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ `RowList`์— ์„ธ ๊ฐœ์˜ `<p>` ํƒœ๊ทธ๋ฅผ `children` prop๋กœ ๋„˜๊ฒจ์ค€๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. +์œ„ ์˜ˆ์‹œ์—์„œ `RowList`๋Š” ๋ชจ๋“  ์ž์‹ ์š”์†Œ๋ฅผ `<div className="Row">`๋กœ ๊ฐ์‹ธ์ค๋‹ˆ๋‹ค. ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ `RowList`์— ์„ธ ๊ฐœ์˜ `<p>` ํƒœ๊ทธ๋ฅผ `children` Prop๋กœ ๋„˜๊ฒจ์ค€๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ```js <RowList> @@ -293,11 +293,11 @@ export default function RowList({ children }) { <DeepDive> -#### `children` prop๋Š” ์™œ ํ•ญ์ƒ ๋ฐฐ์—ด์ด ์•„๋‹Œ๊ฐ€์š”? {/*why-is-the-children-prop-not-always-an-array*/} +#### `children` Prop๋Š” ์™œ ํ•ญ์ƒ ๋ฐฐ์—ด์ด ์•„๋‹Œ๊ฐ€์š”? {/*why-is-the-children-prop-not-always-an-array*/} -React์—์„œ `children` prop๋Š” *๋ถˆ๋ถ„๋ช…ํ•œ* ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋กœ ์ทจ๊ธ‰๋ฉ๋‹ˆ๋‹ค. `children`์ด ๊ตฌ์กฐํ™”๋œ ๋ฐฉ์‹์— ์˜์กดํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ๋ณ€ํ™˜ํ•˜๊ฑฐ๋‚˜ ํ•„ํ„ฐ๋งํ•˜๊ฑฐ๋‚˜ ๊ฐœ์ˆ˜๋ฅผ ์„ธ๊ธฐ ์œ„ํ•ด์„œ๋Š” `Children` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +React์—์„œ `children` Prop๋Š” *๋ถˆ๋ถ„๋ช…ํ•œ* ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋กœ ์ทจ๊ธ‰๋ฉ๋‹ˆ๋‹ค. `children`์ด ๊ตฌ์กฐํ™”๋œ ๋ฐฉ์‹์— ์˜์กดํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ๋ณ€ํ™˜ํ•˜๊ฑฐ๋‚˜ ํ•„ํ„ฐ๋งํ•˜๊ฑฐ๋‚˜ ๊ฐœ์ˆ˜๋ฅผ ์„ธ๊ธฐ ์œ„ํ•ด์„œ๋Š” `Children` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -์‹ค์ œ๋กœ `children` ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐฐ์—ด๋กœ ํ‘œํ˜„๋˜๊ณ ๋Š” ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งŒ์•ฝ ํ•˜๋‚˜์˜ ์ž์‹๋งŒ ์žˆ๋‹ค๋ฉด React๋Š” ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฐ์—ด์„ ์ถ”๊ฐ€๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `children` prop์— ์ง์ ‘ ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ  `Children` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์‹ค์ œ๋กœ React๊ฐ€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ–ˆ๋”๋ผ๋„ ์ฝ”๋“œ๋Š” ๊นจ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +์‹ค์ œ๋กœ `children` ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐฐ์—ด๋กœ ํ‘œํ˜„๋˜๊ณ ๋Š” ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งŒ์•ฝ ํ•˜๋‚˜์˜ ์ž์‹๋งŒ ์žˆ๋‹ค๋ฉด React๋Š” ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฐ์—ด์„ ์ถ”๊ฐ€๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `children` Prop์— ์ง์ ‘ ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ  `Children` ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์‹ค์ œ๋กœ React๊ฐ€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ–ˆ๋”๋ผ๋„ ์ฝ”๋“œ๋Š” ๊นจ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `children`์ด ๋ฐฐ์—ด์ด๋”๋ผ๋„ `Children.map`์„ ์œ ์šฉํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `Children.map`์€ ๋ฐ˜ํ™˜๋œ ์—˜๋ฆฌ๋จผํŠธ์˜ [key](/learn/rendering-lists#keeping-list-items-in-order-with-key)๋ฅผ ์ „๋‹ฌ๋ฐ›์€ `children`์˜ key์™€ ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์œ„ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ๊ฐ์‹ธ์ง€๋”๋ผ๋„ ์›๋ณธ JSX ์ž์‹ ์š”์†Œ๋Š” key๋ฅผ ์žƒ์–ด๋ฒ„๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @@ -305,12 +305,12 @@ React์—์„œ `children` prop๋Š” *๋ถˆ๋ถ„๋ช…ํ•œ* ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋กœ ์ทจ๊ธ‰๋ฉ๋‹ˆ <Pitfall> -`children` ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋Š” JSX๋กœ ์ „๋‹ฌ๋œ ์ปดํฌ๋„ŒํŠธ์˜ **๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `RowList`๊ฐ€ ๋ฐ›์€ `children`์—๋Š” ์„ธ ๊ฐœ๊ฐ€ ์•„๋‹Œ ๋‘ ๊ฐœ์˜ ์•„์ดํ…œ๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. +`children` ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋Š” JSX๋กœ ์ „๋‹ฌ๋œ ์ปดํฌ๋„ŒํŠธ์˜ **๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.** ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `RowList`๊ฐ€ ๋ฐ›์€ `children`์—๋Š” ์„ธ ๊ฐœ๊ฐ€ ์•„๋‹Œ ๋‘ ๊ฐœ์˜ ์•„์ดํ…œ๋งŒ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. 1. `<p>This is the first item.</p>` 2. `<MoreRows />` -๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ๋Š” ๋‘ ๊ฐœ์˜ ๋ž˜ํผ๋งŒ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. +๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ๋Š” ๋‘ ๊ฐœ์˜ ๋ž˜ํผ๋งŒ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. <Sandpack> @@ -492,7 +492,7 @@ export default function RowList({ children }) { ### `children` ๋ฐฐ์—ด๋กœ ๋ณ‘ํ•ฉํ•˜๊ธฐ {/*converting-children-to-an-array*/} -`Children.toArray(children)`๋Š” `children` ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ผ๋ฐ˜์ ์ธ JavaScript ๋ฐฐ์—ด๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•ด์„œ [`filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), [`sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort), [`reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)์™€ ๊ฐ™์€ ๋ฐฐ์—ด์˜ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`Children.toArray(children)`๋Š” `children` ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ผ๋ฐ˜์ ์ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐฐ์—ด๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•ด์„œ [`filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), [`sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort), [`reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)์™€ ๊ฐ™์€ ๋ฐฐ์—ด์˜ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <Sandpack> @@ -540,7 +540,7 @@ export default function ReversedList({ children }) { import { Children } from 'react'; ``` -์†Œ๋ฌธ์ž `c`์ธ [`children`prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์™€ ํ˜ผ๋™ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. [`children`prop](/learn/passing-props-to-a-component#passing-jsx-as-children)๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ด๊ณ  ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. +์†Œ๋ฌธ์ž `c`์ธ [`children` Prop](/learn/passing-props-to-a-component#passing-jsx-as-children)์™€ ํ˜ผ๋™ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. [`children` Prop](/learn/passing-props-to-a-component#passing-jsx-as-children)๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ด๊ณ  ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. </Note> @@ -679,9 +679,9 @@ export function Row({ children }) { --- -### prop๋กœ ๊ฐ์ฒด ๋ฐฐ์—ด ๋ฐ›๊ธฐ {/*accepting-an-array-of-objects-as-a-prop*/} +### Prop๋กœ ๊ฐ์ฒด ๋ฐฐ์—ด ๋ฐ›๊ธฐ {/*accepting-an-array-of-objects-as-a-prop*/} -prop๋กœ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `RowList`๋Š” `rows` ๋ฐฐ์—ด์„ prop๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. +Prop๋กœ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `RowList`๋Š” `rows` ๋ฐฐ์—ด์„ Prop๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. <Sandpack> @@ -730,9 +730,9 @@ export function RowList({ rows }) { </Sandpack> -`rows`๋Š” ์ผ๋ฐ˜์ ์ธ JavaScript ๋ฐฐ์—ด์ด๊ธฐ ๋•Œ๋ฌธ์—, `RowList` ์ปดํฌ๋„ŒํŠธ๋Š” [`map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)๊ณผ ๊ฐ™์€ ๋‚ด์žฅ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`rows`๋Š” ์ผ๋ฐ˜์ ์ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐฐ์—ด์ด๊ธฐ ๋•Œ๋ฌธ์—, `RowList` ์ปดํฌ๋„ŒํŠธ๋Š” [`map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)๊ณผ ๊ฐ™์€ ๋‚ด์žฅ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ด ํŒจํ„ด์€ ๊ตฌ์กฐํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž์‹ ์š”์†Œ์™€ ํ•จ๊ป˜ ์ „๋‹ฌํ•  ๋•Œ ๋” ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `TabSwitcher` ์ปดํฌ๋„ŒํŠธ๋Š” `tabs` prop๋กœ ๊ฐ์ฒด ๋ฐฐ์—ด์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. +์ด ํŒจํ„ด์€ ๊ตฌ์กฐํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž์‹ ์š”์†Œ์™€ ํ•จ๊ป˜ ์ „๋‹ฌํ•  ๋•Œ ๋” ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `TabSwitcher` ์ปดํฌ๋„ŒํŠธ๋Š” `tabs` Prop๋กœ ๊ฐ์ฒด ๋ฐฐ์—ด์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. <Sandpack> @@ -794,7 +794,7 @@ JSX๋กœ ์ž์‹ ์š”์†Œ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ์™€ ๋‹ฌ๋ฆฌ ์ด๋Ÿฐ ๋ฐฉ์‹์€ ๊ฐ ์•„์ดํ…œ --- -### ๋ Œ๋”๋ง prop๋กœ ๋ Œ๋”๋ง ์ปค์Šคํ…€ํ•˜๊ธฐ {/*calling-a-render-prop-to-customize-rendering*/} +### ๋ Œ๋”๋ง Prop๋กœ ๋ Œ๋”๋ง ์ปค์Šคํ…€ํ•˜๊ธฐ {/*calling-a-render-prop-to-customize-rendering*/} ๋ชจ๋“  ๊ฐœ๋ณ„ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด JSX๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋Œ€์‹  JSX๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ํ•„์š”ํ•  ๋•Œ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `App` ์ปดํฌ๋„ŒํŠธ๋Š” `renderContent` ํ•จ์ˆ˜๋ฅผ `TabSwitcher` ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. `TabSwitcher` ์ปดํฌ๋„ŒํŠธ๋Š” ์„ ํƒ๋œ ํƒญ์— ๋Œ€ํ•ด์„œ๋งŒ `renderContent`๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. @@ -845,10 +845,10 @@ export default function TabSwitcher({ tabIds, getHeader, renderContent }) { </Sandpack> -`renderContent`์™€ ๊ฐ™์ด ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ผ๋ถ€๋ฅผ ์–ด๋–ป๊ฒŒ ๋ Œ๋”๋งํ• ์ง€ ์ •์˜ํ•˜๋Š” prop๋ฅผ *๋ Œ๋”๋ง prop*๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํŠน๋ณ„ํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‹จ์ง€ ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜์˜ prop์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. +`renderContent`์™€ ๊ฐ™์ด ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ผ๋ถ€๋ฅผ ์–ด๋–ป๊ฒŒ ๋ Œ๋”๋งํ• ์ง€ ์ •์˜ํ•˜๋Š” Prop๋ฅผ *๋ Œ๋”๋ง Prop*๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํŠน๋ณ„ํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‹จ์ง€ ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜์˜ Prop์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. -๋ Œ๋”๋ง props๋Š” ํ•จ์ˆ˜์ด๋ฏ€๋กœ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `RowList` ์ปดํฌ๋„ŒํŠธ๋Š” ๊ฐ row์˜ `id`์™€ `index`๋ฅผ `renderRow`์— ๋ Œ๋”๋ง prop๋กœ ์ „๋‹ฌํ•˜๊ณ , `index`๊ฐ€ ์ง์ˆ˜์ธ row๋ฅผ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค. +๋ Œ๋”๋ง Prop์€์€ ํ•จ์ˆ˜์ด๋ฏ€๋กœ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์•„๋ž˜ ์˜ˆ์‹œ์—์„œ `RowList` ์ปดํฌ๋„ŒํŠธ๋Š” ๊ฐ row์˜ `id`์™€ `index`๋ฅผ `renderRow`์— ๋ Œ๋”๋ง Prop๋กœ ์ „๋‹ฌํ•˜๊ณ , `index`๊ฐ€ ์ง์ˆ˜์ธ row๋ฅผ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค. <Sandpack> From 91664e9f39767d6de2df6789e6120930b1e3d805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 20:28:39 +0900 Subject: [PATCH 0373/1059] docs: update `cloneElement.md` --- src/content/reference/react/cloneElement.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/reference/react/cloneElement.md b/src/content/reference/react/cloneElement.md index 99cc1c514..980478fd8 100644 --- a/src/content/reference/react/cloneElement.md +++ b/src/content/reference/react/cloneElement.md @@ -4,7 +4,7 @@ title: cloneElement <Pitfall> -`cloneElement`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํ”ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ถˆ์•ˆ์ •ํ•œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [์ผ๋ฐ˜์ ์ธ ๋Œ€์•ˆ์„ ํ™•์ธํ•˜์„ธ์š”.](#alternatives) +`cloneElement`์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์ด์ง€ ์•Š๊ณ  ๋ถˆ์•ˆ์ •ํ•œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์•ˆ์„ ์‚ดํŽด๋ณด์„ธ์š”.](#alternatives) </Pitfall> @@ -554,9 +554,9 @@ button { --- -### Custom Hook์œผ๋กœ ๋กœ์ง ์ถ”์ถœํ•˜๊ธฐ {/*extracting-logic-into-a-custom-hook*/} +### ์ปค์Šคํ…€ Hook์œผ๋กœ ๋กœ์ง ์ถ”์ถœํ•˜๊ธฐ {/*extracting-logic-into-a-custom-hook*/} -๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์œผ๋กœ๋Š” ์ž์ฒด hook์„ ํ†ตํ•ด "๋น„์‹œ๊ฐ์ ์ธ" ๋กœ์ง์„ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  hook์— ์˜ํ•ด์„œ ๋ฐ˜ํ™˜๋œ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋งํ•  ๋‚ด์šฉ์„ ์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด `useList` ๊ฐ™์€ custom hook์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์œผ๋กœ๋Š” ์ž์ฒด hook์„ ํ†ตํ•ด "๋น„์‹œ๊ฐ์ ์ธ" ๋กœ์ง์„ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  hook์— ์˜ํ•ด์„œ ๋ฐ˜ํ™˜๋œ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋งํ•  ๋‚ด์šฉ์„ ์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด `useList` ๊ฐ™์€ ์ปค์Šคํ…€ hook์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js import { useState } from 'react'; From bea2d127bb71e2bbf74143fb6841585d8425afeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 21:03:24 +0900 Subject: [PATCH 0374/1059] docs: update `Component.md` --- src/content/reference/react/Component.md | 109 +---------------------- 1 file changed, 3 insertions(+), 106 deletions(-) diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index e405966ec..8bb096417 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -50,11 +50,7 @@ class Greeting extends Component { ### `context` {/*context*/} -<<<<<<< HEAD -ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ [context](/learn/passing-data-deeply-with-context)๋Š” `this.context`๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [`static contextType`](#static-contexttype)(modern) ๋˜๋Š” [`static contextTypes`](#static-contexttypes)(deprecated)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ *์–ด๋–ค* context๋ฅผ ๋ฐ›๊ธธ ์›ํ•˜๋Š”์ง€ ์ง€์ •ํ•ด์•ผ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -======= -The [context](/learn/passing-data-deeply-with-context) of a class component is available as `this.context`. It is only available if you specify *which* context you want to receive using [`static contextType`](#static-contexttype). ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ [context](/learn/passing-data-deeply-with-context)๋Š” `this.context`๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [`static contextType`](#static-contexttype)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ *์–ด๋–ค* context๋ฅผ ๋ฐ›์„์ง€ ์ง€์ •ํ•ด์•ผ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ context๋งŒ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -109,21 +105,6 @@ class Greeting extends Component { --- -<<<<<<< HEAD -### `refs` {/*refs*/} - -<Deprecated> - -์ด API๋Š” React์˜ ํ–ฅํ›„ ์ฃผ์š” ๋ฒ„์ „์—์„œ ์ œ๊ฑฐ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. [๋Œ€์‹  `createRef`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.](/reference/react/createRef) - -</Deprecated> - -์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ [legacy string refs](https://ko.reactjs.org/docs/refs-and-the-dom.html#legacy-api-string-refs)์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ---- - -======= ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ### `state` {/*state*/} ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ state๋Š” `this.state`๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `state` ํ•„๋“œ๋Š” ๋ฐ˜๋“œ์‹œ ๊ฐ์ฒด์—ฌ์•ผํ•ฉ๋‹ˆ๋‹ค. state๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. state๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ์ƒˆ state๋กœ `setState`๋ฅผ ํ˜ธ์ถœํ•˜์„ธ์š”. @@ -501,21 +482,6 @@ class ChatRoom extends Component { --- -<<<<<<< HEAD -### `getChildContext()` {/*getchildcontext*/} - -<Deprecated> - -์ด API๋Š” ํ–ฅํ›„ React์˜ ์ฃผ์š” ๋ฒ„์ „์—์„œ ์ œ๊ฑฐ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. [๋Œ€์‹  `Context.Provider`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.](/reference/react/createContext#provider) - -</Deprecated> - -์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ œ๊ณตํ•˜๋Š” [legacy context](https://ko.reactjs.org/docs/legacy-context.html)์— ๋Œ€ํ•œ ๊ฐ’์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ---- - -======= ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ### `getSnapshotBeforeUpdate(prevProps, prevState)` {/*getsnapshotbeforeupdate*/} `getSnapshotBeforeUpdate`๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด React๊ฐ€ DOM์„ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ๋ฐ”๋กœ ์ „์— ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž ์žฌ์ ์œผ๋กœ ๋ณ€๊ฒฝ๋˜๊ธฐ ์ „์— DOM์—์„œ ์ผ๋ถ€ ์ •๋ณด(์˜ˆ: ์Šคํฌ๋กค ์œ„์น˜)๋ฅผ ์บก์ฒ˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ƒ๋ช…์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ชจ๋“  ๊ฐ’์€ [`componentDidUpdate`](#componentdidupdate)์— ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. @@ -746,15 +712,9 @@ class Rectangle extends Component { #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*shouldcomponentupdate-parameters*/} -<<<<<<< HEAD - `nextProps`: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋งํ•  ๋‹ค์Œ props์ž…๋‹ˆ๋‹ค. `nextProps`์™€ [`this.props`](#props)๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋ฌด์—‡์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. - `nextState`: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋งํ•  ๋‹ค์Œ state์ž…๋‹ˆ๋‹ค. `nextState`์™€ [`this.state`](#props)๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋ฌด์—‡์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. -- `nextContext`: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋งํ•  ๋‹ค์Œ context์ž…๋‹ˆ๋‹ค. `nextContext`๋ฅผ [`this.context`](#context)์™€ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. [`static contextType`](#static-contexttype)(modern) ๋˜๋Š” [`static contextTypes`](#static-contexttypes)(legacy)๋ฅผ ์ง€์ •ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -======= -- `nextProps`: The next props that the component is about to render with. Compare `nextProps` to [`this.props`](#props) to determine what changed. -- `nextState`: The next state that the component is about to render with. Compare `nextState` to [`this.state`](#props) to determine what changed. -- `nextContext`: The next context that the component is about to render with. Compare `nextContext` to [`this.context`](#context) to determine what changed. Only available if you specify [`static contextType`](#static-contexttype). ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +- `nextContext`: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋งํ•  ๋‹ค์Œ context์ž…๋‹ˆ๋‹ค. `nextContext`๋ฅผ [`this.context`](#context)์™€ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. [`static contextType`](#static-contexttype)(modern)์„ ์ง€์ •ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #### ๋ฐ˜ํ™˜๊ฐ’ {/*shouldcomponentupdate-returns*/} @@ -828,13 +788,8 @@ React์— ์žฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ์Œ์„ ์•Œ๋ฆฌ๋ ค๋ฉด `false`๋ฅผ ๋ฐ˜ํ™˜ #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*unsafe_componentwillreceiveprops-parameters*/} -<<<<<<< HEAD - `nextProps`: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ›์œผ๋ ค๋Š” ๋‹ค์Œ props์ž…๋‹ˆ๋‹ค. `nextProps`์™€ [`this.props`](#props)๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋ฌด์—‡์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. -- `nextContext`: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ณต๊ธ‰์ž(provider)๋กœ๋ถ€ํ„ฐ ๋ฐ›์œผ๋ ค๋Š” ๋‹ค์Œ props์ž…๋‹ˆ๋‹ค. `nextContext`๋ฅผ [`this.context`](#context)์™€ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. [`static contextType`](#static-contexttype)(modern) ๋˜๋Š” [`static contextTypes`](#static-contexttypes)(legacy)๋ฅผ ์ง€์ •ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -======= -- `nextProps`: The next props that the component is about to receive from its parent component. Compare `nextProps` to [`this.props`](#props) to determine what changed. -- `nextContext`: The next context that the component is about to receive from the closest provider. Compare `nextContext` to [`this.context`](#context) to determine what changed. Only available if you specify [`static contextType`](#static-contexttype). ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +- `nextContext`: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ณต๊ธ‰์ž(provider)๋กœ๋ถ€ํ„ฐ ๋ฐ›์œผ๋ ค๋Š” ๋‹ค์Œ props์ž…๋‹ˆ๋‹ค. `nextContext`๋ฅผ [`this.context`](#context)์™€ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. [`static contextType`](#static-contexttype)(modern)์„ ์ง€์ •ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #### ๋ฐ˜ํ™˜๊ฐ’ {/*unsafe_componentwillreceiveprops-returns*/} @@ -899,33 +854,6 @@ React์— ์žฌ๋ Œ๋”๋ง์„ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ์Œ์„ ์•Œ๋ฆฌ๋ ค๋ฉด `false`๋ฅผ ๋ฐ˜ํ™˜ --- -<<<<<<< HEAD -### `static childContextTypes` {/*static-childcontexttypes*/} - -<Deprecated> - -์ด API๋Š” ํ–ฅํ›„ React์˜ ์ฃผ์š” ๋ฒ„์ „์—์„œ ์ œ๊ฑฐ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. [๋Œ€์‹  `static contextType`์„ ์‚ฌ์šฉํ•˜์„ธ์š”.](#static-contexttype) - -</Deprecated> - -์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ œ๊ณตํ•˜๋Š” [legacy context](https://ko.reactjs.org/docs/legacy-context.html)๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ---- - -### `static contextTypes` {/*static-contexttypes*/} - -<Deprecated> - -์ด API๋Š” ํ–ฅํ›„ React์˜ ์ฃผ์š” ๋ฒ„์ „์—์„œ ์ œ๊ฑฐ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. [๋Œ€์‹  `static contextType`์„ ์‚ฌ์šฉํ•˜์„ธ์š”.](#static-contexttype) - -</Deprecated> - -์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ์šฉํ•  [legacy context](https://ko.reactjs.org/docs/legacy-context.html)๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ---- - -======= ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ### `static contextType` {/*static-contexttype*/} ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ [`this.context`](#context-instance-field) ๋ฅผ ์ฝ์œผ๋ ค๋ฉด ์ฝ์–ด์•ผ ํ•˜๋Š” context๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `static contextType`์œผ๋กœ ์ง€์ •ํ•˜๋Š” context๋Š” ์ด์ „์— [`createContext`](/reference/react/createContext)๋กœ ์ƒ์„ฑํ•œ ๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. @@ -1000,37 +928,6 @@ class Button extends Component { --- -<<<<<<< HEAD -### `static propTypes` {/*static-proptypes*/} - -[`prop-types`](https://www.npmjs.com/package/prop-types) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ `static propTypes`๋ฅผ ์ •์˜ํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ—ˆ์šฉ๋˜๋Š” props์˜ ์œ ํ˜•์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์œ ํ˜•์€ ๋ Œ๋”๋ง ์ค‘๊ณผ ๊ฐœ๋ฐœ ์ค‘์—๋งŒ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค. - -```js -import PropTypes from 'prop-types'; - -class Greeting extends React.Component { - static propTypes = { - name: PropTypes.string - }; - - render() { - return ( - <h1>Hello, {this.props.name}</h1> - ); - } -} -``` - -<Note> - -๋Ÿฐํƒ€์ž„์— prop ํƒ€์ž…์„ ํ™•์ธํ•˜๋Š” ๋Œ€์‹  [TypeScript](https://www.typescriptlang.org/ko/)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. - -</Note> - ---- - -======= ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ### `static getDerivedStateFromError(error)` {/*static-getderivedstatefromerror*/} `static getDerivedStateFromError`๋ฅผ ์ •์˜ํ•˜๋ฉด ๋ Œ๋”๋ง ๋„์ค‘ ์ž์‹ ์ปดํฌ๋„ŒํŠธ(๋ฉ€๋ฆฌ ๋–จ์–ด์ง„ ์ž์‹ ํฌํ•จ)๊ฐ€ ์—๋Ÿฌ๋ฅผ throw ํ•  ๋•Œ React๊ฐ€ ์ด๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด UI๋ฅผ ์ง€์šฐ๋Š” ๋Œ€์‹  ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. From 59a0958c38b607196326e1bf56ea2de5c872b448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 21:12:30 +0900 Subject: [PATCH 0375/1059] docs: resolve conflict in `createElement.md` --- src/content/reference/react/createElement.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/content/reference/react/createElement.md b/src/content/reference/react/createElement.md index 4e5531cc0..594101b1c 100644 --- a/src/content/reference/react/createElement.md +++ b/src/content/reference/react/createElement.md @@ -48,17 +48,10 @@ function Greeting({ name }) { `createElement`๋Š” ์•„๋ž˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๋Š” React ์—˜๋ฆฌ๋จผํŠธ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -<<<<<<< HEAD * `type`: ์ „๋‹ฌ๋ฐ›์€ `type`. -* `props`: `ref`์™€ `key`๋ฅผ ์ œ์™ธํ•œ ์ „๋‹ฌ๋ฐ›์€ `props`. `type`์ด ๋ ˆ๊ฑฐ์‹œ `type.defaultProps`๋ฅผ ๊ฐ€์ง€๋Š” ์ปดํฌ๋„ŒํŠธ๋ผ๋ฉด, ๋ˆ„๋ฝ๋˜๊ฑฐ๋‚˜ ์ •์˜๋˜์ง€ ์•Š์€ `props`๋Š” `type.defaultProps` ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. +* `props`: `ref`์™€ `key`๋ฅผ ์ œ์™ธํ•œ ์ „๋‹ฌ๋ฐ›์€ `props`. * `ref`: ์ „๋‹ฌ๋ฐ›์€ `ref`. ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ `null`. * `key`: ์ „๋‹ฌ๋ฐ›์€ `key`๋ฅผ ๊ฐ•์ œ ๋ณ€ํ™˜ํ•œ ๋ฌธ์ž์—ด. ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ `null`. -======= -* `type`: The `type` you have passed. -* `props`: The `props` you have passed except for `ref` and `key`. -* `ref`: The `ref` you have passed. If missing, `null`. -* `key`: The `key` you have passed, coerced to a string. If missing, `null`. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ์ผ๋ฐ˜์ ์œผ๋กœ ์—˜๋ฆฌ๋จผํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ˜ํ™˜๋˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์—˜๋ฆฌ๋จผํŠธ์˜ ์ž์‹์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์—˜๋ฆฌ๋จผํŠธ์˜ ํ”„๋กœํผํ‹ฐ์—๋Š” ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์—˜๋ฆฌ๋จผํŠธ ์ƒ์„ฑ ํ›„์—๋Š” ๋ชจ๋“  ์—˜๋ฆฌ๋จผํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋Œ€ํ•˜๊ณ  ๋ Œ๋”๋ง๋งŒ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. From 44d14e019bedaf9c4c9ed20fb485c966d91e4176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 21:14:19 +0900 Subject: [PATCH 0376/1059] docs: update `createRef.md` --- src/content/reference/react/createRef.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/createRef.md b/src/content/reference/react/createRef.md index 4821c862a..56b580caa 100644 --- a/src/content/reference/react/createRef.md +++ b/src/content/reference/react/createRef.md @@ -60,7 +60,7 @@ createRef`๋Š” ๋‹จ์ผ ์†์„ฑ์„ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. --- -## ์‚ฌ์šฉ {/*usage*/} +## ์‚ฌ์šฉ๋ฒ• {/*usage*/} ### ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ ref ์„ ์–ธํ•˜๊ธฐ {/*declaring-a-ref-in-a-class-component*/} From 9e1559b4ee40a26cb6d4f8db857633ee6343d25a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 21:20:51 +0900 Subject: [PATCH 0377/1059] docs: update `forwardRef.md` --- src/content/reference/react/forwardRef.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/forwardRef.md b/src/content/reference/react/forwardRef.md index da74210a0..fc6fffa90 100644 --- a/src/content/reference/react/forwardRef.md +++ b/src/content/reference/react/forwardRef.md @@ -12,7 +12,7 @@ In React 19, `forwardRef` is no longer necessary. Pass `ref` as a prop instead. <Intro> -`forwardRef` ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ [ref.](/learn/manipulating-the-dom-with-refs)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ DOM ๋…ธ๋“œ๋ฅผ ๋…ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`forwardRef`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ [ref](/learn/manipulating-the-dom-with-refs)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ DOM ๋…ธ๋“œ๋ฅผ ๋…ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js const SomeComponent = forwardRef(render) From 8a927c128f6ed030052c9bf76025d7bd10c75c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Wed, 1 Jan 2025 21:39:35 +0900 Subject: [PATCH 0378/1059] refactor: translate `<RSC>` callout component --- src/components/MDX/ExpandableCallout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MDX/ExpandableCallout.tsx b/src/components/MDX/ExpandableCallout.tsx index b4239fbb5..dd7199d15 100644 --- a/src/components/MDX/ExpandableCallout.tsx +++ b/src/components/MDX/ExpandableCallout.tsx @@ -76,7 +76,7 @@ const variantMap = { 'linear-gradient(rgba(249, 247, 243, 0), rgba(249, 247, 243, 1)', }, rsc: { - title: 'React Server Components', + title: 'React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ', Icon: null, containerClasses: 'bg-blue-10 dark:bg-blue-60 dark:bg-opacity-20', textColor: 'text-blue-50 dark:text-blue-40', From 4a8c0ad915892f2a21da4ea2557a203989831fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Thu, 2 Jan 2025 00:46:13 +0900 Subject: [PATCH 0379/1059] docs: update `server-components.md` --- .../reference/rsc/server-components.md | 39 +++++++------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/content/reference/rsc/server-components.md b/src/content/reference/rsc/server-components.md index ab92d673e..c152b8427 100644 --- a/src/content/reference/rsc/server-components.md +++ b/src/content/reference/rsc/server-components.md @@ -1,10 +1,5 @@ --- -<<<<<<< HEAD -title: React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ -canary: true -======= -title: Server Components ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +title: ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ --- <RSC> @@ -27,20 +22,16 @@ Server Components are for use in [React Server Components](/learn/start-a-new-re #### ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง€์›ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋‚˜์š”? {/*how-do-i-build-support-for-server-components*/} -<<<<<<< HEAD -React 19์˜ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์•ˆ์ •์ ์ด๋ฉฐ ๋ฉ”์ด์ €(Major) ๋ฒ„์ „ ๊ฐ„์—๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๋ฒˆ๋“ค๋Ÿฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ณธ API๋Š” ์‹œ๋งจํ‹ฑ ๋ฒ„์ „(semver)์„ ๋”ฐ๋ฅด์ง€ ์•Š์œผ๋ฉฐ React 19.x์˜ ๋งˆ์ด๋„ˆ(Minor) ๋ฒ„์ „ ๊ฐ„์— ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -======= -While React Server Components in React 19 are stable and will not break between minor versions, the underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +React 19์˜ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์•ˆ์ •์ ์ด๋ฉฐ ๋งˆ์ด๋„ˆ(Minor) ๋ฒ„์ „ ๊ฐ„์—๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๋ฒˆ๋“ค๋Ÿฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ณธ API๋Š” ์‹œ๋งจํ‹ฑ ๋ฒ„์ „(semver)์„ ๋”ฐ๋ฅด์ง€ ์•Š์œผ๋ฉฐ React 19.x์˜ ๋งˆ์ด๋„ˆ(Minor) ๋ฒ„์ „ ๊ฐ„์— ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฒˆ๋“ค๋Ÿฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ์ง€์›ํ•˜๋ ค๋ฉด, ํŠน์ • React ๋ฒ„์ „์— ๊ณ ์ •ํ•˜๊ฑฐ๋‚˜ Canary ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ํ–ฅํ›„ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” API๋ฅผ ์•ˆ์ •ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ฒˆ๋“ค๋Ÿฌ ๋ฐ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ณ„์† ํ˜‘๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. </Note> ### ์„œ๋ฒ„ ์—†์ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉํ•˜๊ธฐ {/*server-components-without-a-server*/} -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋นŒ๋“œ ์‹œ๊ฐ„์— ํŒŒ์ผ ์‹œ์Šคํ…œ์—์„œ ์ฝ๊ฑฐ๋‚˜ ์ •์  ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์›น ์„œ๋ฒ„๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ฝ˜ํ…์ธ  ๊ด€๋ฆฌ ์‹œ์Šคํ…œ(CMS)์—์„œ ์ •์  ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์‹ถ์„ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋นŒ๋“œ ์‹œ๊ฐ„์— ํŒŒ์ผ ์‹œ์Šคํ…œ์„ ์ฝ๊ฑฐ๋‚˜ ์ •์  ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์›น ์„œ๋ฒ„๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ฝ˜ํ…์ธ  ๊ด€๋ฆฌ ์‹œ์Šคํ…œ<sup>CMS</sup>์—์„œ ์ •์  ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์‹ถ์„ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์—†์ด ํด๋ผ์ด์–ธํŠธ์—์„œ ์ •์  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ผ๋ฐ˜์ ์ธ ํŒจํ„ด์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์—†์ด ํด๋ผ์ด์–ธํŠธ์—์„œ Effect๋ฅผ ์‚ฌ์šฉํ•ด ์ •์  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ผ๋ฐ˜์ ์ธ ํŒจํ„ด์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js // bundle.js import marked from 'marked'; // 35.9K (11.2K gzipped) @@ -67,7 +58,7 @@ app.get(`/api/content/:page`, async (req, res) => { }); ``` -์ด ํŒจํ„ด์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ •์  ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด ํŽ˜์ด์ง€๊ฐ€ ๋กœ๋“œ๋œ ํ›„ ์ถ”๊ฐ€ 75K (gzipped) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ํŒŒ์‹ฑํ•ด์•ผ ํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ๋‘ ๋ฒˆ์งธ ์š”์ฒญ์„ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์ด ํŒจํ„ด์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ •์  ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด ํŽ˜์ด์ง€๊ฐ€ ๋กœ๋“œ๋œ ํ›„ ์ถ”๊ฐ€ 75K (gzipped) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ํŒŒ์‹ฑํ•ด์•ผ ํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ ๋‘ ๋ฒˆ์งธ ์š”์ฒญ์„ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฌํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋นŒ๋“œ ์‹œ๊ฐ„์— ํ•œ ๋ฒˆ๋งŒ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -83,7 +74,7 @@ async function Page({page}) { } ``` -๋ Œ๋”๋ง๋œ ์ถœ๋ ฅ์€ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง(SSR)์„ ํ†ตํ•ด HTML๋กœ ๋ณ€ํ™˜๋˜์–ด CDN์— ์—…๋กœ๋“œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์ด ๋กœ๋“œ๋  ๋•Œ, ํด๋ผ์ด์–ธํŠธ๋Š” ๊ธฐ์กด์˜ `Page` ์ปดํฌ๋„ŒํŠธ๋‚˜ ๋งˆํฌ๋‹ค์šด ๋ Œ๋”๋ง์„ ์œ„ํ•œ ๊ณ ๋น„์šฉ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ณด์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๋Š” ๋ Œ๋”๋ง๋œ ์ถœ๋ ฅ๋งŒ ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +๋ Œ๋”๋ง๋œ ์ถœ๋ ฅ์€ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง<sup>SSR</sup>์„ ํ†ตํ•ด HTML๋กœ ๋ณ€ํ™˜๋˜์–ด CDN์— ์—…๋กœ๋“œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์ด ๋กœ๋“œ๋  ๋•Œ, ํด๋ผ์ด์–ธํŠธ๋Š” ๊ธฐ์กด์˜ `Page` ์ปดํฌ๋„ŒํŠธ๋‚˜ ๋งˆํฌ๋‹ค์šด ๋ Œ๋”๋ง์„ ์œ„ํ•œ ๊ณ ๋น„์šฉ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ณด์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๋Š” ๋ Œ๋”๋ง๋œ ์ถœ๋ ฅ๋งŒ ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ```js <div><!-- html for markdown --></div> @@ -108,9 +99,9 @@ async function Page({page}) { </Note> ### ์„œ๋ฒ„์™€ ํ•จ๊ป˜ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉํ•˜๊ธฐ {/*server-components-with-a-server*/} -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์›น ์„œ๋ฒ„์—์„œ ํŽ˜์ด์ง€ ์š”์ฒญ ์‹œ ์‹คํ–‰๋  ์ˆ˜๋„ ์žˆ์–ด, API๋ฅผ ๊ตฌ์ถ•ํ•  ํ•„์š” ์—†์ด ๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด๋“ค์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฒˆ๋“ค๋ง๋˜๊ธฐ ์ „์— ๋ Œ๋”๋ง๋˜๋ฉฐ, ๋ฐ์ดํ„ฐ์™€ JSX๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์— props๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์›น ์„œ๋ฒ„์—์„œ ํŽ˜์ด์ง€ ์š”์ฒญ ์‹œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์–ด, API๋ฅผ ๊ตฌ์ถ•ํ•  ํ•„์š” ์—†์ด ๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋“ค์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฒˆ๋“ค๋ง๋˜๊ธฐ ์ „์— ๋ Œ๋”๋ง๋˜๋ฉฐ, ๋ฐ์ดํ„ฐ์™€ JSX๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์— Props๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์—†์ด ํด๋ผ์ด์–ธํŠธ์—์„œ ๋™์  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ผ๋ฐ˜์ ์ธ ํŒจํ„ด์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์—†์ด ํด๋ผ์ด์–ธํŠธ์—์„œ Effect๋ฅผ ์‚ฌ์šฉํ•ด ๋™์  ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ผ๋ฐ˜์ ์ธ ํŒจํ„ด์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ```js // bundle.js @@ -192,7 +183,7 @@ async function Author({id}) { </div> ``` -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋ฒ„์—์„œ ๋‹ค์‹œ ํŽ˜์นญํ•จ์œผ๋กœ์จ ๋ฐ์ดํ„ฐ์— ์•ก์„ธ์Šคํ•˜๊ณ  ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์—ฌ ๋™์ ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ƒˆ๋กœ์šด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•„ํ‚คํ…์ฒ˜๋Š” ์„œ๋ฒ„ ์ค‘์‹ฌ์˜ ๋‹ค์ค‘ ํŽ˜์ด์ง€ ์•ฑ(Server-Centric Multi-Page Apps)์˜ ๊ฐ„๋‹จํ•œ "request/response" ๋ชจ๋ธ๊ณผ ํด๋ผ์ด์–ธํŠธ ์ค‘์‹ฌ์˜ ๋‹จ์ผ ํŽ˜์ด์ง€ ์•ฑ(Client-Centric Single-Page Apps)์˜ ์›ํ™œํ•œ ์ƒํ˜ธ์ž‘์šฉ์„ ๊ฒฐํ•ฉํ•˜์—ฌ ๋‘ ๊ฐ€์ง€์˜ ์žฅ์ ์„ ๋ชจ๋‘ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋ฒ„์—์„œ ๋‹ค์‹œ ํŽ˜์นญํ•จ์œผ๋กœ์จ ๋ฐ์ดํ„ฐ์— ์•ก์„ธ์Šคํ•˜๊ณ  ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์—ฌ ๋™์ ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ƒˆ๋กœ์šด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•„ํ‚คํ…์ฒ˜๋Š” ์„œ๋ฒ„ ์ค‘์‹ฌ์˜ ๋‹ค์ค‘ ํŽ˜์ด์ง€ ์•ฑ(Server-Centric Multi-Page Apps)์˜ ๊ฐ„๋‹จํ•œ "request/response" ๋ชจ๋ธ๊ณผ ํด๋ผ์ด์–ธํŠธ ์ค‘์‹ฌ์˜ ๋‹จ์ผ ํŽ˜์ด์ง€ ์•ฑ(Client-Centric Single-Page Apps)์˜ ์›ํ™œํ•œ ์ƒํ˜ธ์ž‘์šฉ์„ ๊ฒฐํ•ฉํ•˜์—ฌ ๋‘ ๊ฐ€์ง€ ์žฅ์ ์„ ๋ชจ๋‘ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ### ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ์ƒํ˜ธ์ž‘์šฉ ์ถ”๊ฐ€ํ•˜๊ธฐ {/*adding-interactivity-to-server-components*/} @@ -202,18 +193,14 @@ async function Author({id}) { #### ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ง€์‹œ์–ด๋Š” ์—†์Šต๋‹ˆ๋‹ค. {/*there-is-no-directive-for-server-components*/} -<<<<<<< HEAD -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” `"use server"`๋กœ ํ‘œ์‹œ๋œ๋‹ค๋Š” ์˜คํ•ด๊ฐ€ ์žˆ์ง€๋งŒ, ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ง€์‹œ์–ด๋Š” ์—†์Šต๋‹ˆ๋‹ค. `"use server"` ์ง€์‹œ์–ด๋Š” ์„œ๋ฒ„ ์•ก์…˜์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -======= -A common misunderstanding is that Server Components are denoted by `"use server"`, but there is no directive for Server Components. The `"use server"` directive is used for Server Functions. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” `"use server"`๋กœ ํ‘œ์‹œ๋œ๋‹ค๋Š” ์˜คํ•ด๊ฐ€ ์žˆ์ง€๋งŒ, ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ์ง€์‹œ์–ด๋Š” ์—†์Šต๋‹ˆ๋‹ค. `"use server"` ์ง€์‹œ์–ด๋Š” ์„œ๋ฒ„ ํ•จ์ˆ˜์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ [์ง€์‹œ์–ด](/reference/rsc/directives)๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. </Note> -๋‹ค์Œ ์˜ˆ์‹œ์—์„œ๋Š” `Notes` ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ `expanded` ์ƒํƒœ๋ฅผ ํ† ๊ธ€ํ•˜๋Š” `Expandable` ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. +๋‹ค์Œ ์˜ˆ์‹œ์—์„œ๋Š” `Notes` ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ State๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ `expanded` ์ƒํƒœ๋ฅผ ํ† ๊ธ€ํ•˜๋Š” `Expandable` ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ```js // Server Component import Expandable from './Expandable'; @@ -250,7 +237,7 @@ export default function Expandable({children}) { } ``` -์ด ์˜ˆ์‹œ๋Š” ๋จผ์ € `Notes`๋ฅผ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ Œ๋”๋งํ•œ ๋‹ค์Œ ๋ฒˆ๋“ค๋Ÿฌ์— `Expandable` ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฒˆ๋“ค์„ ์ƒ์„ฑํ•˜๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ ์ถœ๋ ฅ์„ props๋กœ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +์ด ์˜ˆ์‹œ๋Š” ๋จผ์ € `Notes`๋ฅผ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ Œ๋”๋งํ•œ ๋‹ค์Œ ๋ฒˆ๋“ค๋Ÿฌ์— `Expandable` ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฒˆ๋“ค์„ ์ƒ์„ฑํ•˜๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ ์ถœ๋ ฅ์„ Props๋กœ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ```js <head> @@ -272,7 +259,7 @@ export default function Expandable({children}) { ### ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ๊ป˜ ๋น„๋™๊ธฐ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉํ•˜๊ธฐ {/*async-components-with-server-components*/} -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” `async`์™€ `await`์„ ์‚ฌ์šฉํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ ์ปดํฌ๋„ŒํŠธ์—์„œ `await`์„ ์‚ฌ์šฉํ•  ๋•Œ, React๋Š” ๋ Œ๋”๋ง์„ ์ง€์—ฐ(Suspend)ํ•˜๊ณ  Promise๊ฐ€ ํ•ด๊ฒฐ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋ Œ๋”๋ง์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์˜ ๊ฒฝ๊ณ„๋ฅผ ๋„˜์–ด ๋™์ž‘ํ•˜๋ฉฐ, Suspense์— ๋Œ€ํ•œ ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” `async`์™€ `await`์„ ์‚ฌ์šฉํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ ์ปดํฌ๋„ŒํŠธ์—์„œ `await`์„ ์‚ฌ์šฉํ•  ๋•Œ, React๋Š” ๋ Œ๋”๋ง์„ ์ง€์—ฐ<sup>Suspend</sup>ํ•˜๊ณ  Promise๊ฐ€ ํ•ด๊ฒฐ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋ Œ๋”๋ง์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์˜ ๊ฒฝ๊ณ„๋ฅผ ๋„˜์–ด ๋™์ž‘ํ•˜๋ฉฐ, Suspense์— ๋Œ€ํ•œ ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ์„œ๋ฒ„์—์„œ Promise๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์—์„œ ์ด๋ฅผ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. From e27c132ebee1a7f82197dba1f1f7aa84b67e849b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Thu, 2 Jan 2025 01:44:02 +0900 Subject: [PATCH 0380/1059] docs: update `server-functions.md` --- src/content/reference/rsc/server-actions.md | 212 ------------------ src/content/reference/rsc/server-functions.md | 83 +++---- src/sidebarHome.json | 6 +- src/sidebarReference.json | 10 +- 4 files changed, 50 insertions(+), 261 deletions(-) delete mode 100644 src/content/reference/rsc/server-actions.md diff --git a/src/content/reference/rsc/server-actions.md b/src/content/reference/rsc/server-actions.md deleted file mode 100644 index b8914e705..000000000 --- a/src/content/reference/rsc/server-actions.md +++ /dev/null @@ -1,212 +0,0 @@ ---- -title: ์„œ๋ฒ„ ์•ก์…˜ -canary: true ---- - -<Intro> - -์„œ๋ฒ„ ์•ก์…˜(Server Action)์„ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„œ๋ฒ„์—์„œ ์‹คํ–‰๋˜๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -</Intro> - -<InlineToc /> - -<Note> - -#### ์„œ๋ฒ„ ์•ก์…˜์„ ์ง€์›ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋‚˜์š”? {/*how-do-i-build-support-for-server-actions*/} - -React 19์˜ ์„œ๋ฒ„ ์•ก์…˜์€ ์•ˆ์ •์ ์ด๋ฉฐ ๋ฉ”์ด์ €(Major) ๋ฒ„์ „ ๊ฐ„์—๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๋ฒˆ๋“ค๋Ÿฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์„œ๋ฒ„ ์•ก์…˜์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ณธ API๋Š” ์‹œ๋งจํ‹ฑ ๋ฒ„์ „(semver)์„ ๋”ฐ๋ฅด์ง€ ์•Š์œผ๋ฉฐ React 19.x์˜ ๋งˆ์ด๋„ˆ(Minor) ๋ฒ„์ „ ๊ฐ„์— ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -์„œ๋ฒ„ ์•ก์…˜์„ ๋ฒˆ๋“ค๋Ÿฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ์ง€์›ํ•˜๋ ค๋ฉด, ํŠน์ • React ๋ฒ„์ „์— ๊ณ ์ •ํ•˜๊ฑฐ๋‚˜ Canary ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ํ–ฅํ›„ ์„œ๋ฒ„ ์•ก์…˜์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” API๋ฅผ ์•ˆ์ •ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ฒˆ๋“ค๋Ÿฌ ๋ฐ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ณ„์† ํ˜‘๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. - -</Note> - -์„œ๋ฒ„ ์•ก์…˜์ด `"use server"` ์ง€์‹œ์–ด๋กœ ์ •์˜๋˜๋ฉด, ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ž๋™์œผ๋กœ ์„œ๋ฒ„ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํ•ด๋‹น ์ฐธ์กฐ๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, React๋Š” ์„œ๋ฒ„์— ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ผ๋Š” ์š”์ฒญ(Request)์„ ๋ณด๋‚ด๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - -์„œ๋ฒ„ ์•ก์…˜์€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒ์„ฑํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์— props๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ฐ€์ ธ์™€์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. - -### ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์„œ๋ฒ„ ์•ก์…˜ ๋งŒ๋“ค๊ธฐ {/*creating-a-server-action-from-a-server-component*/} - -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” `"use server"` ์ง€์‹œ์–ด๋กœ ์„œ๋ฒ„ ์•ก์…˜์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -```js [[2, 7, "'use server'"], [1, 5, "createNoteAction"], [1, 12, "createNoteAction"]] -// Server Component -import Button from './Button'; - -function EmptyNote () { - async function createNoteAction() { - // Server Action - 'use server'; - - await db.notes.create(); - } - - return <Button onClick={createNoteAction}/>; -} -``` - -React๊ฐ€ `EmptyNote` ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ, `createNoteAction` ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ทธ ์ฐธ์กฐ๋ฅผ `Button` ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด, React๋Š” ์ œ๊ณต๋œ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด `createNoteAction` ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ์„œ๋ฒ„์— ์š”์ฒญ(Request)์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. - -```js {5} -"use client"; - -export default function Button({onClick}) { - console.log(onClick); - // {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'} - return <button onClick={() => onClick()}>Create Empty Note</button> -} -``` - -์ž์„ธํ•œ ๋‚ด์šฉ์€ [`"use server"`](/reference/rsc/use-server) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. - -### ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์„œ๋ฒ„ ์•ก์…˜ ๊ฐ€์ ธ์˜ค๊ธฐ {/*importing-server-actions-from-client-components*/} - -ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” `"use server"` ์ง€์‹œ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŒŒ์ผ์—์„œ ์„œ๋ฒ„ ์•ก์…˜์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -```js [[1, 3, "createNoteAction"]] -"use server"; - -export async function createNoteAction() { - await db.notes.create(); -} - -``` - -๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ `EmptyNote` ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋นŒ๋“œํ•  ๋•Œ, ๋ฒˆ๋“ค์—์„œ `createNoteAction` ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด, React๋Š” ์ œ๊ณต๋œ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด `createNoteAction` ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ์„œ๋ฒ„์— ์š”์ฒญ(Request)์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. - -```js [[1, 2, "createNoteAction"], [1, 5, "createNoteAction"], [1, 7, "createNoteAction"]] -"use client"; -import {createNoteAction} from './actions'; - -function EmptyNote() { - console.log(createNoteAction); - // {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'} - return <button onClick={createNoteAction} /> -} -``` - -์ž์„ธํ•œ ๋‚ด์šฉ์€ [`"use server"`](/reference/rsc/use-server) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. - -### ์•ก์…˜์œผ๋กœ ์„œ๋ฒ„ ์•ก์…˜ ๊ตฌ์„ฑํ•˜๊ธฐ {/*composing-server-actions-with-actions*/} - -์„œ๋ฒ„ ์•ก์…˜์€ ํด๋ผ์ด์–ธํŠธ์˜ ์•ก์…˜(Action)๊ณผ ํ•จ๊ป˜ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -```js [[1, 3, "updateName"]] -"use server"; - -export async function updateName(name) { - if (!name) { - return {error: 'Name is required'}; - } - await db.users.updateName(name); -} -``` - -```js [[1, 3, "updateName"], [1, 13, "updateName"], [2, 11, "submitAction"], [2, 23, "submitAction"]] -"use client"; - -import {updateName} from './actions'; - -function UpdateName() { - const [name, setName] = useState(''); - const [error, setError] = useState(null); - - const [isPending, startTransition] = useTransition(); - - const submitAction = async () => { - startTransition(async () => { - const {error} = await updateName(name); - if (!error) { - setError(error); - } else { - setName(''); - } - }) - } - - return ( - <form action={submitAction}> - <input type="text" name="name" disabled={isPending}/> - {state.error && <span>Failed: {state.error}</span>} - </form> - ) -} -``` - -์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ์˜ ์•ก์…˜์œผ๋กœ ๋ž˜ํ•‘ํ•˜์—ฌ ์„œ๋ฒ„ ์•ก์…˜์˜ `isPending` ์ƒํƒœ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -์ž์„ธํ•œ ๋‚ด์šฉ์€ [`<form>` ์™ธ๋ถ€์—์„œ ์„œ๋ฒ„ ์•ก์…˜ ํ˜ธ์ถœํ•˜๊ธฐ](/reference/rsc/use-server#calling-a-server-action-outside-of-form) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. - -### ์„œ๋ฒ„ ์•ก์…˜์„ ์‚ฌ์šฉํ•œ ํผ ์•ก์…˜ {/*form-actions-with-server-actions*/} - -์„œ๋ฒ„ ์•ก์…˜์€ React 19์˜ ์ƒˆ๋กœ์šด ํผ(Form) ๊ธฐ๋Šฅ๊ณผ ํ•จ๊ป˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. - -์„œ๋ฒ„ ์•ก์…˜์„ ํผ์— ์ „๋‹ฌํ•˜์—ฌ ํผ์„ ์„œ๋ฒ„์— ์ž๋™์œผ๋กœ ์ œ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - - -```js [[1, 3, "updateName"], [1, 7, "updateName"]] -"use client"; - -import {updateName} from './actions'; - -function UpdateName() { - return ( - <form action={updateName}> - <input type="text" name="name" /> - </form> - ) -} -``` - -ํผ ์ œ์ถœ์ด ์„ฑ๊ณตํ•˜๋ฉด, React๋Š” ์ž๋™์œผ๋กœ ํผ์„ ์žฌ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. `useActionState`๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋Œ€๊ธฐ(Pending) ์ƒํƒœ ํ˜น์€ ๋งˆ์ง€๋ง‰ ์‘๋‹ต(Response)์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜, ์ ์ง„์  ํ–ฅ์ƒ์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -์ž์„ธํ•œ ๋‚ด์šฉ์€ [์„œ๋ฒ„ ์•ก์…˜ ํ˜•์‹](/reference/rsc/use-server#server-actions-in-forms) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. - -### `useActionState`๋ฅผ ์‚ฌ์šฉํ•œ ์„œ๋ฒ„ ์•ก์…˜ {/*server-actions-with-use-action-state*/} - -์•ก์…˜ ๋Œ€๊ธฐ(Pending) ์ƒํƒœ์™€ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐ˜ํ™˜๋œ ์‘๋‹ต(Response)์— ์ ‘๊ทผํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์—๋Š” `useActionState`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„ ์•ก์…˜์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -```js [[1, 3, "updateName"], [1, 6, "updateName"], [2, 6, "submitAction"], [2, 9, "submitAction"]] -"use client"; - -import {updateName} from './actions'; - -function UpdateName() { - const [state, submitAction, isPending] = useActionState(updateName, {error: null}); - - return ( - <form action={submitAction}> - <input type="text" name="name" disabled={isPending}/> - {state.error && <span>Failed: {state.error}</span>} - </form> - ); -} -``` - -์„œ๋ฒ„ ์•ก์…˜๊ณผ ํ•จ๊ป˜ `useActionState`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, React๋Š” Hydration์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „์— ์ž…๋ ฅ๋œ ํผ ์ œ์ถœ์„ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์‚ฌ์šฉ์ž๋Š” ์•ฑ์ด Hydration ๋˜๊ธฐ ์ „์—๋„ ์•ฑ๊ณผ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -์ž์„ธํ•œ ๋‚ด์šฉ์€ [`useActionState`](/reference/react/useActionState) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. - -### `useActionState`๋ฅผ ํ†ตํ•œ ์ ์ง„์  ํ–ฅ์ƒ {/*progressive-enhancement-with-useactionstate*/} - -์„œ๋ฒ„ ์•ก์…˜์€ `useActionState`์˜ ์„ธ ๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ํ†ตํ•œ ์ ์ง„์  ํ–ฅ์ƒ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. - -```js [[1, 3, "updateName"], [1, 6, "updateName"], [2, 6, "/name/update"], [3, 6, "submitAction"], [3, 9, "submitAction"]] -"use client"; - -import {updateName} from './actions'; - -function UpdateName() { - const [, submitAction] = useActionState(updateName, null, `/name/update`); - - return ( - <form action={submitAction}> - ... - </form> - ); -} -``` - -<CodeStep step={2}>permalink</CodeStep>๊ฐ€ `useActionState`์— ์ œ๊ณต๋  ๋•Œ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค์ด ๋กœ๋“œ๋˜๊ธฐ ์ „์— ํผ์ด ์ œ์ถœ๋˜๋ฉด React๋Š” ์ œ๊ณต๋œ URL๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•ฉ๋‹ˆ๋‹ค. - -์ž์„ธํ•œ ๋‚ด์šฉ์€ [`useActionState`](/reference/react/useActionState) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. diff --git a/src/content/reference/rsc/server-functions.md b/src/content/reference/rsc/server-functions.md index 74aab615c..3d4e22fe0 100644 --- a/src/content/reference/rsc/server-functions.md +++ b/src/content/reference/rsc/server-functions.md @@ -1,5 +1,5 @@ --- -title: Server Functions +title: ์„œ๋ฒ„ ํ•จ์ˆ˜ --- <RSC> @@ -12,7 +12,7 @@ Server Functions are for use in [React Server Components](/learn/start-a-new-rea <Intro> -Server Functions allow Client Components to call async functions executed on the server. +์„œ๋ฒ„ ํ•จ์ˆ˜<sup>Server Functions</sup>๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„œ๋ฒ„์—์„œ ์‹คํ–‰๋˜๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. </Intro> @@ -20,58 +20,58 @@ Server Functions allow Client Components to call async functions executed on the <Note> -#### How do I build support for Server Functions? {/*how-do-i-build-support-for-server-functions*/} +#### ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋‚˜์š”? {/*how-do-i-build-support-for-server-functions*/} -While Server Functions in React 19 are stable and will not break between minor versions, the underlying APIs used to implement Server Functions in a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x. +React 19์˜ ์„œ๋ฒ„ ํ•จ์ˆ˜๋Š” ์•ˆ์ •์ ์ด๋ฉฐ ๋งˆ์ด๋„ˆ<sup>Minor</sup> ๋ฒ„์ „ ๊ฐ„์—๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๋ฒˆ๋“ค๋Ÿฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ณธ API๋Š” ์‹œ๋งจํ‹ฑ ๋ฒ„์ „(semver)์„ ๋”ฐ๋ฅด์ง€ ์•Š์œผ๋ฉฐ React 19.x์˜ ๋งˆ์ด๋„ˆ<sup>Minor</sup> ๋ฒ„์ „ ๊ฐ„์— ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -To support Server Functions as a bundler or framework, we recommend pinning to a specific React version, or using the Canary release. We will continue working with bundlers and frameworks to stabilize the APIs used to implement Server Functions in the future. +์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ๋ฒˆ๋“ค๋Ÿฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ์ง€์›ํ•˜๋ ค๋ฉด, ํŠน์ • React ๋ฒ„์ „์— ๊ณ ์ •ํ•˜๊ฑฐ๋‚˜ Canary ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ํ–ฅํ›„ ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” API๋ฅผ ์•ˆ์ •ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ฒˆ๋“ค๋Ÿฌ ๋ฐ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ณ„์† ํ˜‘๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. </Note> -When a Server Functions is defined with the [`"use server"`](/reference/rsc/use-server) directive, your framework will automatically create a reference to the server function, and pass that reference to the Client Component. When that function is called on the client, React will send a request to the server to execute the function, and return the result. +์„œ๋ฒ„ ํ•จ์ˆ˜๊ฐ€ [`"use server"`](/reference/rsc/use-server) ์ง€์‹œ์–ด๋กœ ์ •์˜๋˜๋ฉด, ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ž๋™์œผ๋กœ ์„œ๋ฒ„ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํ•ด๋‹น ์ฐธ์กฐ๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, React๋Š” ์„œ๋ฒ„์— ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ผ๋Š” ์š”์ฒญ<sup>Request</sup>์„ ๋ณด๋‚ด๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -Server Functions can be created in Server Components and passed as props to Client Components, or they can be imported and used in Client Components. +์„œ๋ฒ„ ํ•จ์ˆ˜๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒ์„ฑํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์— Props๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ฐ€์ ธ์™€์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. -## Usage {/*usage*/} +## ์‚ฌ์šฉ๋ฒ• {/*usage*/} -### Creating a Server Function from a Server Component {/*creating-a-server-function-from-a-server-component*/} +### ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์„œ๋ฒ„ ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ {/*creating-a-server-function-from-a-server-component*/} -Server Components can define Server Functions with the `"use server"` directive: +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” `"use server"` ์ง€์‹œ์–ด๋กœ ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -```js [[2, 7, "'use server'"], [1, 5, "createNoteAction"], [1, 12, "createNoteAction"]] +```js [[2, 7, "'use server'"], [1, 5, "createNote"], [1, 12, "createNote"]] // Server Component import Button from './Button'; function EmptyNote () { - async function createNoteAction() { + async function createNote() { // Server Function 'use server'; - + await db.notes.create(); } - return <Button onClick={createNoteAction}/>; + return <Button onClick={createNote}/>; } ``` -When React renders the `EmptyNote` Server Function, it will create a reference to the `createNoteAction` function, and pass that reference to the `Button` Client Component. When the button is clicked, React will send a request to the server to execute the `createNoteAction` function with the reference provided: +React๊ฐ€ `EmptyNote` ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ, `createNote` ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ทธ ์ฐธ์กฐ๋ฅผ `Button` ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด, React๋Š” ์ œ๊ณต๋œ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด `createNote` ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ์„œ๋ฒ„์— ์š”์ฒญ<sup>Request</sup>์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ```js {5} "use client"; -export default function Button({onClick}) { - console.log(onClick); +export default function Button({onClick}) { + console.log(onClick); // {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'} return <button onClick={() => onClick()}>Create Empty Note</button> } ``` -For more, see the docs for [`"use server"`](/reference/rsc/use-server). +์ž์„ธํ•œ ๋‚ด์šฉ์€ [`"use server"`](/reference/rsc/use-server) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. -### Importing Server Functions from Client Components {/*importing-server-functions-from-client-components*/} +### ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์„œ๋ฒ„ ํ•จ์ˆ˜ ๊ฐ€์ ธ์˜ค๊ธฐ {/*importing-server-functions-from-client-components*/} -Client Components can import Server Functions from files that use the `"use server"` directive: +ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” `"use server"` ์ง€์‹œ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŒŒ์ผ์—์„œ ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js [[1, 3, "createNote"]] "use server"; @@ -82,10 +82,11 @@ export async function createNote() { ``` -When the bundler builds the `EmptyNote` Client Component, it will create a reference to the `createNoteAction` function in the bundle. When the `button` is clicked, React will send a request to the server to execute the `createNoteAction` function using the reference provided: +๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ `EmptyNote` ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋นŒ๋“œํ•  ๋•Œ, ๋ฒˆ๋“ค์—์„œ `createNote` ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด, React๋Š” ์ œ๊ณต๋œ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด `createNote` ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ์„œ๋ฒ„์— ์š”์ฒญ<sup>Request</sup>์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. -```js [[1, 2, "createNote"], [1, 5, "createNote"], [1, 7, "createNote"]] +```js [[1, 3, "createNote"], [1, 6, "createNote"], [1, 8, "createNote"]] "use client"; + import {createNote} from './actions'; function EmptyNote() { @@ -95,11 +96,11 @@ function EmptyNote() { } ``` -For more, see the docs for [`"use server"`](/reference/rsc/use-server). +์ž์„ธํ•œ ๋‚ด์šฉ์€ [`"use server"`](/reference/rsc/use-server) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. -### Server Functions with Actions {/*server-functions-with-actions*/} +### ์•ก์…˜์œผ๋กœ ์„œ๋ฒ„ ํ•จ์ˆ˜ ๊ตฌ์„ฑํ•˜๊ธฐ {/*server-functions-with-actions*/} -Server Functions can be called from Actions on the client: +์„œ๋ฒ„ ํ•จ์ˆ˜๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์•ก์…˜<sup>Action</sup>๊ณผ ํ•จ๊ป˜ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js [[1, 3, "updateName"]] "use server"; @@ -133,7 +134,7 @@ function UpdateName() { } }) } - + return ( <form action={submitAction}> <input type="text" name="name" disabled={isPending}/> @@ -143,15 +144,15 @@ function UpdateName() { } ``` -This allows you to access the `isPending` state of the Server Function by wrapping it in an Action on the client. +์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ์˜ ์•ก์…˜์œผ๋กœ ๋ž˜ํ•‘ํ•˜์—ฌ ์„œ๋ฒ„ ํ•จ์ˆ˜์˜ `isPending` ์ƒํƒœ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For more, see the docs for [Calling a Server Function outside of `<form>`](/reference/rsc/use-server#calling-a-server-function-outside-of-form) +์ž์„ธํ•œ ๋‚ด์šฉ์€ [`<form>` ์™ธ๋ถ€์—์„œ ์„œ๋ฒ„ ํ•จ์ˆ˜ ํ˜ธ์ถœํ•˜๊ธฐ](/reference/rsc/use-server#calling-a-server-action-outside-of-form) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. -### Server Functions with Form Actions {/*using-server-functions-with-form-actions*/} +### ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ํผ ์•ก์…˜ {/*using-server-functions-with-form-actions*/} -Server Functions work with the new Form features in React 19. +์„œ๋ฒ„ ํ•จ์ˆ˜๋Š” React 19์˜ ์ƒˆ๋กœ์šด ํผ<sup>Form</sup> ๊ธฐ๋Šฅ๊ณผ ํ•จ๊ป˜ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. -You can pass a Server Function to a Form to automatically submit the form to the server: +์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํผ์— ์ „๋‹ฌํ•˜์—ฌ ํผ์„ ์„œ๋ฒ„์— ์ž๋™์œผ๋กœ ์ œ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js [[1, 3, "updateName"], [1, 7, "updateName"]] @@ -168,13 +169,13 @@ function UpdateName() { } ``` -When the Form submission succeeds, React will automatically reset the form. You can add `useActionState` to access the pending state, last response, or to support progressive enhancement. +ํผ ์ œ์ถœ์ด ์„ฑ๊ณตํ•˜๋ฉด, React๋Š” ์ž๋™์œผ๋กœ ํผ์„ ์žฌ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. `useActionState`๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋Œ€๊ธฐ<sup>Pending</sup> ์ƒํƒœ ํ˜น์€ ๋งˆ์ง€๋ง‰ ์‘๋‹ต<sup>Response</sup>์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜, ์ ์ง„์  ํ–ฅ์ƒ์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For more, see the docs for [Server Functions in Forms](/reference/rsc/use-server#server-functions-in-forms). +์ž์„ธํ•œ ๋‚ด์šฉ์€ [ํผ<sup>Form</sup>์—์„œ์˜ ์„œ๋ฒ„ ํ•จ์ˆ˜](/reference/rsc/use-server#server-functions-in-forms) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. -### Server Functions with `useActionState` {/*server-functions-with-use-action-state*/} +### `useActionState`๋ฅผ ์‚ฌ์šฉํ•œ ์„œ๋ฒ„ ํ•จ์ˆ˜ {/*server-functions-with-use-action-state*/} -You can call Server Functions with `useActionState` for the common case where you just need access to the action pending state and last returned response: +์•ก์…˜ ๋Œ€๊ธฐ<sup>Pending</sup> ์ƒํƒœ์™€ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐ˜ํ™˜๋œ ์‘๋‹ต<sup>Response</sup>์— ์ ‘๊ทผํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์—๋Š” `useActionState`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js [[1, 3, "updateName"], [1, 6, "updateName"], [2, 6, "submitAction"], [2, 9, "submitAction"]] "use client"; @@ -193,13 +194,13 @@ function UpdateName() { } ``` -When using `useActionState` with Server Functions, React will also automatically replay form submissions entered before hydration finishes. This means users can interact with your app even before the app has hydrated. +์„œ๋ฒ„ ํ•จ์ˆ˜ ํ•จ๊ป˜ `useActionState`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, React๋Š” Hydration์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „์— ์ž…๋ ฅ๋œ ํผ ์ œ์ถœ์„ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์‚ฌ์šฉ์ž๋Š” ์•ฑ์ด Hydration ๋˜๊ธฐ ์ „์—๋„ ์•ฑ๊ณผ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -For more, see the docs for [`useActionState`](/reference/react-dom/hooks/useFormState). +์ž์„ธํ•œ ๋‚ด์šฉ์€ [`useActionState`](/reference/react/useActionState) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. -### Progressive enhancement with `useActionState` {/*progressive-enhancement-with-useactionstate*/} +### `useActionState`๋ฅผ ํ†ตํ•œ ์ ์ง„์  ํ–ฅ์ƒ {/*progressive-enhancement-with-useactionstate*/} -Server Functions also support progressive enhancement with the third argument of `useActionState`. +์„œ๋ฒ„ ํ•จ์ˆ˜๋Š” `useActionState`์˜ ์„ธ ๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ํ†ตํ•œ ์ ์ง„์  ํ–ฅ์ƒ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ```js [[1, 3, "updateName"], [1, 6, "updateName"], [2, 6, "/name/update"], [3, 6, "submitAction"], [3, 9, "submitAction"]] "use client"; @@ -217,6 +218,6 @@ function UpdateName() { } ``` -When the <CodeStep step={2}>permalink</CodeStep> is provided to `useActionState`, React will redirect to the provided URL if the form is submitted before the JavaScript bundle loads. +<CodeStep step={2}>permalink</CodeStep>๊ฐ€ `useActionState`์— ์ œ๊ณต๋  ๋•Œ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค์ด ๋กœ๋“œ๋˜๊ธฐ ์ „์— ํผ์ด ์ œ์ถœ๋˜๋ฉด React๋Š” ์ œ๊ณต๋œ URL๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•ฉ๋‹ˆ๋‹ค. -For more, see the docs for [`useActionState`](/reference/react-dom/hooks/useFormState). +์ž์„ธํ•œ ๋‚ด์šฉ์€ [`useActionState`](/reference/react/useActionState) ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. diff --git a/src/sidebarHome.json b/src/sidebarHome.json index fee1a73d9..e986ce6e8 100644 --- a/src/sidebarHome.json +++ b/src/sidebarHome.json @@ -23,11 +23,11 @@ "path": "/learn/describing-the-ui" }, { - "title": "์ƒํ˜ธ์ž‘์šฉ์„ฑ ๋”ํ•˜๊ธฐ", + "title": "์ƒํ˜ธ์ž‘์šฉ ์ถ”๊ฐ€ํ•˜๊ธฐ", "path": "/learn/adding-interactivity" }, { - "title": "State ๋‹ค๋ฃจ๊ธฐ", + "title": "State ๊ด€๋ฆฌํ•˜๊ธฐ", "path": "/learn/managing-state" }, { @@ -39,7 +39,7 @@ "sectionHeader": "REACT API" }, { - "title": "ํ›…", + "title": "Hook", "path": "/reference/react" }, { diff --git a/src/sidebarReference.json b/src/sidebarReference.json index 2e9dfe1eb..d97cbc749 100644 --- a/src/sidebarReference.json +++ b/src/sidebarReference.json @@ -11,7 +11,7 @@ "path": "/reference/react" }, { - "title": "Hooks", + "title": "Hook", "path": "/reference/react/hooks", "routes": [ { @@ -155,7 +155,7 @@ "sectionHeader": "react-dom@{{version}}" }, { - "title": "Hooks", + "title": "Hook", "path": "/reference/react-dom/hooks", "routes": [ { @@ -293,7 +293,7 @@ ] }, { - "title": "Static APIs", + "title": "์ •์  API", "path": "/reference/react-dom/static", "routes": [ { @@ -337,8 +337,8 @@ "path": "/reference/rsc/server-components" }, { - "title": "์„œ๋ฒ„ ์•ก์…˜", - "path": "/reference/rsc/server-actions" + "title": "์„œ๋ฒ„ ํ•จ์ˆ˜", + "path": "/reference/rsc/server-functions" }, { "title": "์ง€์‹œ์–ด", From 44b4a7f10dab56a538cc33da662123379a4427d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Thu, 2 Jan 2025 01:46:47 +0900 Subject: [PATCH 0381/1059] docs: resolve conflict in `directives.md` --- src/content/reference/rsc/directives.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/content/reference/rsc/directives.md b/src/content/reference/rsc/directives.md index a5f4256a3..9fb85de18 100644 --- a/src/content/reference/rsc/directives.md +++ b/src/content/reference/rsc/directives.md @@ -1,19 +1,10 @@ --- -<<<<<<< HEAD title: "์ง€์‹œ์–ด" -canary: true -======= -title: Directives ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc --- <RSC> -<<<<<<< HEAD -์ด ์ง€์‹œ์–ด๋Š” [React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜](/learn/start-a-new-react-project#bleeding-edge-react-frameworks) ์ด์™€ ํ˜ธํ™˜๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. -======= Directives are for use in [React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc </RSC> From afd8b82f9fb6bccd660d1ec756044deb038325ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Thu, 2 Jan 2025 21:04:16 +0900 Subject: [PATCH 0382/1059] docs: update `use-client.md` --- src/content/reference/rsc/use-client.md | 95 ++++++++----------------- 1 file changed, 31 insertions(+), 64 deletions(-) diff --git a/src/content/reference/rsc/use-client.md b/src/content/reference/rsc/use-client.md index 75c19d276..448860414 100644 --- a/src/content/reference/rsc/use-client.md +++ b/src/content/reference/rsc/use-client.md @@ -1,23 +1,13 @@ --- title: "'use client'" -<<<<<<< HEAD titleForTitleTag: "'use client' ์ง€์‹œ์–ด" -canary: true -======= -titleForTitleTag: "'use client' directive" ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc --- <RSC> -<<<<<<< HEAD -`'use client'`๋Š” [React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉ](/learn/start-a-new-react-project#bleeding-edge-react-frameworks)ํ•˜๊ฑฐ๋‚˜ ๊ทธ์™€ ํ˜ธํ™˜๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค ๋•Œ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. -</Canary> -======= `'use client'` is for use with [React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). </RSC> ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc <Intro> @@ -51,13 +41,13 @@ export default function RichTextEditor({ timestamp, text }) { } ``` -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ `'use client'`๋ผ๊ณ  ํ‘œ์‹œ๋œ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๋ฉด [ํ˜ธํ™˜๋˜๋Š” ๋ฒˆ๋“ค๋Ÿฌ](/learn/start-a-new-react-project#bleeding-edge-react-frameworks)๋Š” import๋ฅผ ์„œ๋ฒ„ ์‹คํ–‰ ์ฝ”๋“œ์™€ ํด๋ผ์ด์–ธํŠธ ์‹คํ–‰ ์ฝ”๋“œ ์‚ฌ์ด์˜ ๊ฒฝ๊ณ„๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ `'use client'`๋ผ ํ‘œ์‹œ๋œ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๋ฉด [ํ˜ธํ™˜๋˜๋Š” ๋ฒˆ๋“ค๋Ÿฌ](/learn/start-a-new-react-project#bleeding-edge-react-frameworks)๋Š” ๋ชจ๋“ˆ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ<sup>Module Import</sup>๋ฅผ ์„œ๋ฒ„ ์‹คํ–‰ ์ฝ”๋“œ์™€ ํด๋ผ์ด์–ธํŠธ ์‹คํ–‰ ์ฝ”๋“œ ์‚ฌ์ด์˜ ๊ฒฝ๊ณ„๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. -`RichTextEditor`์˜ ์˜์กด์„ฑ์œผ๋กœ `formatDate`์™€ `Button`๋„ ํ•ด๋‹น ๋ชจ๋“ˆ์— `'use client'` ์ง€์‹œ์–ด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š๋”๋ผ๋„ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๋ชจ๋“ˆ์ด ์„œ๋ฒ„ ์ฝ”๋“œ์—์„œ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋Š” ์„œ๋ฒ„์—์„œ, ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ํ‰๊ฐ€๋  ์ˆ˜ ์žˆ์Œ์„ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +`RichTextEditor`์˜ ์˜์กด์„ฑ์œผ๋กœ ์ธํ•˜์—ฌ, `formatDate`์™€ `Button`์˜ ๋ชจ๋“ˆ์— `'use client'` ์ง€์‹œ์–ด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š๋”๋ผ๋„ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๋ชจ๋“ˆ์ด ์„œ๋ฒ„ ์ฝ”๋“œ์—์„œ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋Š” ์„œ๋ฒ„์—์„œ, ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ํ‰๊ฐ€๋  ์ˆ˜ ์žˆ์Œ์„ ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} -* `'use client'`๋Š” ํŒŒ์ผ์˜ ๋งจ ์ฒ˜์Œ์— ์žˆ์–ด์•ผ ํ•˜๋ฉฐ, ๋‹ค๋ฅธ ์ฝ”๋“œ๋‚˜ import ๋ฌธ๋ณด๋‹ค ์œ„์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ฃผ์„์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค). ์ž‘์€๋”ฐ์˜ดํ‘œ๋‚˜ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋ฉฐ ๋ฐฑํ‹ฑ์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +* `'use client'`๋Š” ํŒŒ์ผ์˜ ๋งจ ์ฒ˜์Œ์— ์žˆ์–ด์•ผ ํ•˜๋ฉฐ, ๋‹ค๋ฅธ ์ฝ”๋“œ๋‚˜ import ๋ฌธ๋ณด๋‹ค ์œ„์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (์ฃผ์„์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.) ์ž‘์€๋”ฐ์˜ดํ‘œ๋‚˜ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋ฉฐ ๋ฐฑํ‹ฑ์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. * `'use client'` ๋ชจ๋“ˆ์„ ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ ๋ Œ๋”๋ง ๋ชจ๋“ˆ์—์„œ ๊ฐ€์ ธ์˜ค๋ฉด ์ง€์‹œ์–ด๊ฐ€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. * ์ปดํฌ๋„ŒํŠธ ๋ชจ๋“ˆ์— `'use client'` ์ง€์‹œ์–ด๊ฐ€ ํฌํ•จ๋œ ๊ฒฝ์šฐ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์‚ฌ์šฉ์€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์ž„์ด ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ปดํฌ๋„ŒํŠธ์— `'use client'` ์ง€์‹œ์–ด๊ฐ€ ์—†๋”๋ผ๋„ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ‰๊ฐ€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์€ `'use client'` ์ง€์‹œ์–ด๊ฐ€ ํฌํ•จ๋œ ๋ชจ๋“ˆ์— ์ •์˜๋˜์–ด ์žˆ๊ฑฐ๋‚˜ `'use client'` ์ง€์‹œ์–ด๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“ˆ์˜ ์ „์ด์  ์˜์กด์„ฑ์ผ ๊ฒฝ์šฐ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. @@ -68,7 +58,7 @@ export default function RichTextEditor({ timestamp, text }) { React ์•ฑ์—์„œ ์ปดํฌ๋„ŒํŠธ๋Š” ์ข…์ข… ๋ณ„๋„์˜ ํŒŒ์ผ ๋˜๋Š” [๋ชจ๋“ˆ](/learn/importing-and-exporting-components#exporting-and-importing-a-component)๋กœ ๋ถ„๋ฆฌ๋ฉ๋‹ˆ๋‹ค. -React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์•ฑ์˜ ๊ฒฝ์šฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ ์•ฑ์€ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. `'use client'`๋Š” [๋ชจ๋“ˆ ์˜์กด์„ฑ ํŠธ๋ฆฌ](/learn/understanding-your-ui-as-a-tree#the-module-dependency-tree)์— ์„œ๋ฒ„-ํด๋ผ์ด์–ธํŠธ ๊ฒฝ๊ณ„๋ฅผ ๋„์ž…ํ•˜์—ฌ ํšจ๊ณผ์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ ๋ชจ๋“ˆ์˜ ํ•˜์œ„ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. +React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์•ฑ์˜ ๊ฒฝ์šฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ ์•ฑ์€ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. `'use client'`๋Š” [๋ชจ๋“ˆ ์˜์กด์„ฑ ํŠธ๋ฆฌ](/learn/understanding-your-ui-as-a-tree#the-module-dependency-tree)์— ์„œ๋ฒ„-ํด๋ผ์ด์–ธํŠธ ๊ฒฝ๊ณ„๋ฅผ ๋„์ž…ํ•˜์—ฌ ํšจ๊ณผ์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ ๋ชจ๋“ˆ์˜ ํ•˜์œ„ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋ฅผ ๋” ์ž˜ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์•ฑ์„ ๊ณ ๋ คํ•ด ๋ณด์„ธ์š”. @@ -174,7 +164,7 @@ React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์•ฑ์„ ์œ„ํ•œ ๋ Œ๋” ํŠธ๋ฆฌ์—์„œ `InspirationGenerato * **ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ**๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง๋˜๋Š” ๋ Œ๋” ํŠธ๋ฆฌ์˜ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. * **์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ**๋Š” ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋˜๋Š” ๋ Œ๋” ํŠธ๋ฆฌ์˜ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. -์˜ˆ์‹œ ์•ฑ์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ `App`, `FancyText` ๋ฐ `Copyright`๋Š” ๋ชจ๋‘ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋˜๋ฉฐ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. `InspirationGenerator.js`์™€ ๊ทธ ์ „์ด์  ์˜์กด์„ฑ์ด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋กœ ํ‘œ์‹œ๋˜๋ฏ€๋กœ ์ปดํฌ๋„ŒํŠธ `InspirationGenerator`์™€ ๊ทธ ์ž์‹ ์ปดํฌ๋„ŒํŠธ `FancyText`๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. +์˜ˆ์‹œ ์•ฑ์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ `App`, `FancyText` ๋ฐ `Copyright`๋Š” ๋ชจ๋‘ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋˜๋ฉฐ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. `InspirationGenerator.js`์™€ ๊ทธ ์ „์ด์  ์˜์กด์„ฑ์ด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋กœ ํ‘œ์‹œ๋˜๋ฏ€๋กœ ์ปดํฌ๋„ŒํŠธ `InspirationGenerator`์™€ ๊ทธ ์ž์‹ ์ปดํฌ๋„ŒํŠธ `FancyText`๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. <DeepDive> #### ์–ด๋–ป๊ฒŒ `FancyText`๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์ด๋ฉด์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์ธ๊ฐ€์š”? {/*how-is-fancytext-both-a-server-and-a-client-component*/} @@ -204,10 +194,10 @@ function App() { ๊ฐœ๋…์„ ์„ค๋ช…ํ•  ๋•Œ ์ข…์ข… ๋ถ€์ •ํ™•์„ฑ์€ ์ค‘์š”ํ•˜์ง€ ์•Š์ง€๋งŒ, ์ด ๊ฒฝ์šฐ์—๋Š” ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. -์„œ๋ฒ„ ๋˜๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์— ๊ด€ํ•ด ์ด์•ผ๊ธฐํ•  ๋•Œ, ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์„ ์–ธ๊ธ‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +์„œ๋ฒ„ ๋˜๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•  ๋•Œ, ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์„ ์–ธ๊ธ‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. -* ์ปดํฌ๋„ŒํŠธ๊ฐ€ `'use client'` ์ง€์‹œ์–ด๊ฐ€ ์žˆ๋Š” ๋ชจ๋“ˆ์—์„œ ์ •์˜๋˜์—ˆ๊ฑฐ๋‚˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ๊ฐ€์ ธ์™€ ํ˜ธ์ถœ๋œ๋‹ค๋ฉด ๊ทธ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. -* ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. +* ์ปดํฌ๋„ŒํŠธ๊ฐ€ `'use client'` ์ง€์‹œ์–ด๊ฐ€ ์žˆ๋Š” ๋ชจ๋“ˆ์—์„œ ์ •์˜๋˜์—ˆ๊ฑฐ๋‚˜, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๊ฐ€์ ธ์™€<sup>Imported</sup> ํ˜ธ์ถœ๋œ๋‹ค๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. +* ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ, ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. <Diagram name="use_client_render_tree" height={150} width={450} alt="A tree graph where each node represents a component and its children as child components. The top-level node is labelled 'App' and it has two child components 'InspirationGenerator' and 'FancyText'. 'InspirationGenerator' has two child components, 'FancyText' and 'Copyright'. Both 'InspirationGenerator' and its child component 'FancyText' are marked to be client-rendered.">๋ Œ๋” ํŠธ๋ฆฌ๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.</Diagram> @@ -216,7 +206,7 @@ function App() { `FancyText`๋ฅผ `App`์˜ ์ž์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `FancyText`๋ฅผ ๊ฐ€์ ธ์™€์„œ `InspirationGenerator`์—์„œ ํ˜ธ์ถœํ•  ๋•Œ `InspirationGenerator`์— `'use client'` ์ง€์‹œ์–ด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ `FancyText`์˜ ์‚ฌ์šฉ์€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค. -์ด๋Š” `FancyText`์— ๋Œ€ํ•œ ์ปดํฌ๋„ŒํŠธ ์ •์˜๊ฐ€ ์„œ๋ฒ„์—์„œ ํ‰๊ฐ€๋˜๊ณ  ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์„ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ์—์„œ ๋‚ด๋ ค๋ฐ›๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. +์ด๋Š” `FancyText`์˜ ์ปดํฌ๋„ŒํŠธ ์ •์˜๊ฐ€ ์„œ๋ฒ„์—์„œ ํ‰๊ฐ€๋  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์‚ฌ์šฉ๋˜๊ธฐ ์œ„ํ•ด ํด๋ผ์ด์–ธํŠธ์— ๋‹ค์šด๋กœ๋“œ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. </DeepDive> @@ -224,15 +214,15 @@ function App() { #### ์™œ `Copyright`๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์ธ๊ฐ€์š”? {/*why-is-copyright-a-server-component*/} -`Copyright` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ `InspirationGenerator`์˜ ์ž์‹์œผ๋กœ ๋ Œ๋”๋ง ๋˜์ง€๋งŒ ์ด๊ฒƒ์ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ผ๋Š” ์‚ฌ์‹ค์— ๋†€๋ž„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`Copyright` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ `InspirationGenerator`์˜ ์ž์‹์œผ๋กœ ๋ Œ๋”๋ง๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๊ฒƒ์ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ผ๋Š” ์ ์ด ๋†€๋ž๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -`'use client'` ์ง€์‹œ์–ด๋Š” _๋ชจ๋“ˆ ์˜์กด์„ฑ ํŠธ๋ฆฌ_(๋ Œ๋” ํŠธ๋ฆฌ๊ฐ€ ์•„๋‹Œ)์—์„œ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ๊ฐ„์˜ ๊ฒฝ๊ณ„๋ฅผ ์ •์˜ํ•œ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. +`'use client'` ์ง€์‹œ์–ด๋Š” (๋ Œ๋” ํŠธ๋ฆฌ๊ฐ€ ์•„๋‹Œ) <em>๋ชจ๋“ˆ ์˜์กด์„ฑ ํŠธ๋ฆฌ</em>์—์„œ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ๊ฐ„์˜ ๊ฒฝ๊ณ„๋ฅผ ์ •์˜ํ•œ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. <Diagram name="use_client_module_dependency" height={200} width={500} alt="A tree graph with the top node representing the module 'App.js'. 'App.js' has three children: 'Copyright.js', 'FancyText.js', and 'InspirationGenerator.js'. 'InspirationGenerator.js' has two children: 'FancyText.js' and 'inspirations.js'. The nodes under and including 'InspirationGenerator.js' have a yellow background color to signify that this sub-graph is client-rendered due to the 'use client' directive in 'InspirationGenerator.js'."> `'use client'` ์ง€์‹œ์–ด๋Š” ๋ชจ๋“ˆ ์˜์กด์„ฑ ํŠธ๋ฆฌ์—์„œ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์˜ ๊ฒฝ๊ณ„๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. </Diagram> -๋ชจ๋“ˆ ์˜์กด์„ฑ ํŠธ๋ฆฌ์—์„œ `App.js`๋Š” `Copyright.js` ๋ชจ๋“ˆ๋กœ๋ถ€ํ„ฐ `Copyright`๋ฅผ ๊ฐ€์ ธ์™€ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. `Copyright.js`์—๋Š” `'use client'` ์ง€์‹œ์–ด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ์ด ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. `App`์€ ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. +๋ชจ๋“ˆ ์˜์กด์„ฑ ํŠธ๋ฆฌ์—์„œ `App.js`๋Š” `Copyright.js` ๋ชจ๋“ˆ๋กœ๋ถ€ํ„ฐ `Copyright`๋ฅผ ๊ฐ€์ ธ์™€ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. `Copyright.js`์—๋Š” `'use client'` ์ง€์‹œ์–ด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. `App`์€ ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” JSX๋ฅผ props๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ `InspirationGenerator`๋Š” `Copyright`๋ฅผ [์ž์‹](/learn/passing-props-to-a-component#passing-jsx-as-children)์œผ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ `InspirationGenerator` ๋ชจ๋“ˆ์€ `Copyright` ๋ชจ๋“ˆ์„ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ด ๋ชจ๋“  ์ž‘์—…์€ `App`์— ์˜ํ•ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ `InspirationGenerator`๊ฐ€ ๋ Œ๋”๋ง์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— `Copyright` ์ปดํฌ๋„ŒํŠธ๋Š” ์™„์ „ํžˆ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. @@ -242,28 +232,27 @@ function App() { ### `'use client'`์˜ ์‚ฌ์šฉ ์‹œ๊ธฐ {/*when-to-use-use-client*/} -`'use client'`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ด๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋งํ•  ๊ฒƒ์„ ํ‘œ์‹œํ•ด์•ผ ํ•˜๋Š” ์‹œ๊ธฐ๋ฅผ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ ์žฅ๋‹จ์ ์„ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. +`'use client'`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์ธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ด๋ฏ€๋กœ, ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋งํ•  ๊ฒƒ์„ ํ‘œ์‹œํ•ด์•ผ ํ•˜๋Š” ์‹œ๊ธฐ๋ฅผ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ ์žฅ๋‹จ์ ์„ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. -๊ฐ„๋žตํ™”๋ฅผ ์œ„ํ•ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๊ด€ํ•ด ์ด์•ผ๊ธฐํ•˜์ง€๋งŒ, ์„œ๋ฒ„์—์„œ ์‹คํ–‰๋˜๋Š” ์•ฑ์˜ ๋ชจ๋“  ์ฝ”๋“œ์—๋Š” ๋™์ผํ•œ ์›์น™์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. +๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜์ง€๋งŒ, ์„œ๋ฒ„์—์„œ ์‹คํ–‰๋˜๋Š” ์•ฑ์˜ ๋ชจ๋“  ์ฝ”๋“œ์—๋Š” ๋™์ผํ•œ ์›์น™์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. #### ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ ์žฅ์  {/*advantages*/} -* ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ „์†กํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ์–‘์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ๋ชจ๋“ˆ๋งŒ ๋ฒˆ๋“ค๋ง ๋˜๊ณ  ํด๋ผ์ด์–ธํŠธ์—์„œ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. +* ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ์— ์ „์†ก๋˜๊ณ  ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ์˜ ์–‘์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ๋ชจ๋“ˆ๋งŒ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฒˆ๋“ค๋ง๋˜๊ณ  ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. * ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋ฒ„์—์„œ ์‹คํ–‰ํ•  ๋•Œ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ์ปฌ ํŒŒ์ผ ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฐ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์— ๋Œ€ํ•œ ์งง์€ ์ง€์—ฐ ์‹œ๊ฐ„์„ ๊ฒฝํ—˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #### ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ ํ•œ๊ณ„ {/*limitations*/} * ํด๋ผ์ด์–ธํŠธ์—์„œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•˜๊ณ  ํŠธ๋ฆฌ๊ฑฐํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์ƒํ˜ธ์ž‘์šฉ์„ ์ง€์›ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. * ์˜ˆ๋ฅผ ๋“ค์–ด `onClick`๊ณผ ๊ฐ™์€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋Œ€๋ถ€๋ถ„์˜ Hook์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. - * ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋˜๋ฉด ๊ทธ ์ถœ๋ ฅ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ Œ๋”๋งํ•  ์ปดํฌ๋„ŒํŠธ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ Œ๋”๋ง ํ›„ ๋ฉ”๋ชจ๋ฆฌ์— ์œ ์ง€๋˜์ง€ ์•Š์œผ๋ฉฐ ์ž์ฒด ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. + * ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋  ๋•Œ, ๊ทธ ์ถœ๋ ฅ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ Œ๋”๋งํ•  ์ปดํฌ๋„ŒํŠธ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ Œ๋”๋ง ํ›„ ๋ฉ”๋ชจ๋ฆฌ์— ์œ ์ง€๋˜์ง€ ์•Š์œผ๋ฉฐ ์ž์ฒด์ ์ธ State๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -### ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ˜ํ™˜๋˜๋Š” ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ ์œ ํ˜• {/*serializable-types*/} +### ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ ์œ ํ˜• {/*serializable-types*/} -React ์•ฑ์—์„œ์™€ ๊ฐ™์ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ ํ™˜๊ฒฝ์—์„œ ๋ Œ๋”๋ง ๋˜๋ฏ€๋กœ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์ถ”๊ฐ€์ ์ธ ๊ณ ๋ ค ์‚ฌํ•ญ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. +React ์•ฑ์—์„œ์™€ ๊ฐ™์ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ ํ™˜๊ฒฝ์—์„œ ๋ Œ๋”๋ง๋˜๋ฏ€๋กœ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์ถ”๊ฐ€์ ์ธ ๊ณ ๋ ค ์‚ฌํ•ญ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. -์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌ๋˜๋Š” prop ๊ฐ’์€ ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•˜๋Š” Prop ๊ฐ’์€ ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -<<<<<<< HEAD -์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š” props๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. +์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š” Props๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. * ์›์‹œ ์ž๋ฃŒํ˜• * [string](https://developer.mozilla.org/ko/docs/Glossary/String) * [number](https://developer.mozilla.org/ko/docs/Glossary/Number) @@ -271,7 +260,7 @@ React ์•ฑ์—์„œ์™€ ๊ฐ™์ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ด * [boolean](https://developer.mozilla.org/ko/docs/Glossary/Boolean) * [undefined](https://developer.mozilla.org/ko/docs/Glossary/Undefined) * [null](https://developer.mozilla.org/ko/docs/Glossary/Null) - * [symbol](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol) ( [`Symbol.for`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for)์„ ํ†ตํ•ด ๊ธ€๋กœ๋ฒŒ ์‹ฌ๋ณผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋“ฑ๋ก๋œ ์‹ฌ๋ณผ๋งŒ ํ•ด๋‹น ) + * [symbol](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol) ( [`Symbol.for`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for)์„ ํ†ตํ•ด ๊ธ€๋กœ๋ฒŒ ์‹ฌ๋ณผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋“ฑ๋ก๋œ ์‹ฌ๋ณผ๋งŒ ํ•ด๋‹น) * ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ํฌํ•จํ•˜๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ” * [String](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String) * [Array](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array) @@ -280,31 +269,9 @@ React ์•ฑ์—์„œ์™€ ๊ฐ™์ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ด * [TypedArray](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) ๋ฐ [ArrayBuffer](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) * [Date](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Date) * ์ผ๋ฐ˜ [๊ฐ์ฒด](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object) (์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ [๊ฐ์ฒด ์ด๋‹ˆ์…œ๋ผ์ด์ €](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Object_initializer)๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด) -* [์„œ๋ฒ„ ์•ก์…˜](/reference/react/use-server)์œผ๋กœ์„œ์˜ ํ•จ์ˆ˜ +* [์„œ๋ฒ„ ํ•จ์ˆ˜](/reference/rsc/server-functions)๋กœ์„œ์˜ ํ•จ์ˆ˜ * ํด๋ผ์ด์–ธํŠธ ๋˜๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์š”์†Œ(JSX) * [Promises](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise) -======= -Serializable props include: -* Primitives - * [string](https://developer.mozilla.org/en-US/docs/Glossary/String) - * [number](https://developer.mozilla.org/en-US/docs/Glossary/Number) - * [bigint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) - * [boolean](https://developer.mozilla.org/en-US/docs/Glossary/Boolean) - * [undefined](https://developer.mozilla.org/en-US/docs/Glossary/Undefined) - * [null](https://developer.mozilla.org/en-US/docs/Glossary/Null) - * [symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol), only symbols registered in the global Symbol registry via [`Symbol.for`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for) -* Iterables containing serializable values - * [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) - * [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) - * [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) - * [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) - * [TypedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) and [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) -* [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) -* Plain [objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object): those created with [object initializers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer), with serializable properties -* Functions that are [Server Functions](/reference/rsc/server-functions) -* Client or Server Component elements (JSX) -* [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc ๋‹จ, ๋‹ค์Œ์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. * ํด๋ผ์ด์–ธํŠธ๋กœ ํ‘œ์‹œ๋œ ๋ชจ๋“ˆ์—์„œ ๋‚ด๋ณด๋‚ด์ง€ ์•Š์•˜๊ฑฐ๋‚˜ [`'use server'`](/reference/rsc/use-server)๋กœ ํ‘œ์‹œ๋œ [ํ•จ์ˆ˜](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function) @@ -315,7 +282,7 @@ Serializable props include: ## ์‚ฌ์šฉ๋ฒ• {/*usage*/} -### ์ƒํ˜ธ์ž‘์šฉ๊ณผ ์ƒํƒœ๋ฅผ ๊ฐ€์ง„ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์ถ• {/*building-with-interactivity-and-state*/} +### ์ƒํ˜ธ์ž‘์šฉ ๋ฐ State๋ฅผ ๊ฐ€์ง„ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์ถ• {/*building-with-interactivity-and-state*/} <Sandpack> @@ -354,7 +321,7 @@ export default async function CounterContainer() { } ``` -์˜ˆ๋ฅผ ๋“ค์–ด, `Counter`์˜ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์ธ `CounterContainer`๋Š” ์ƒํ˜ธ์ž‘์šฉ์ด ์—†๊ณ  state๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— `'use client'`๊ฐ€ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ `CounterContainer`๋Š” ์„œ๋ฒ„์˜ ๋กœ์ปฌ ํŒŒ์ผ ์‹œ์Šคํ…œ์—์„œ ์ฝ์–ด์•ผ ํ•˜๋ฏ€๋กœ ์ด๊ฐ€ ๊ฐ€๋Šฅํ•œ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—ฌ์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค. +์˜ˆ๋ฅผ ๋“ค์–ด, `Counter`์˜ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์ธ `CounterContainer`๋Š” ์ƒํ˜ธ์ž‘์šฉ์ด ์—†๊ณ  State๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— `'use client'`๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ `CounterContainer`๋Š” ์„œ๋ฒ„์˜ ๋กœ์ปฌ ํŒŒ์ผ ์‹œ์Šคํ…œ์„ ์ฝ์–ด์•ผ ํ•˜๋ฏ€๋กœ, ์ด๊ฒƒ์ด ๊ฐ€๋Šฅํ•œ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—ฌ์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๋‚˜ ํด๋ผ์ด์–ธํŠธ ์ „์šฉ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ Œ๋”๋ง ์œ„์น˜์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š” ์ปดํฌ๋„ŒํŠธ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ž์„œ ์˜ˆ๋กœ ๋“  `FancyText`๊ฐ€ ๊ทธ๋Ÿฌํ•œ ์ปดํฌ๋„ŒํŠธ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. @@ -368,11 +335,11 @@ export default function FancyText({title, text}) { ์ด ๊ฒฝ์šฐ `'use client'` ์ง€์‹œ์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์œผ๋ฉด `FancyText`์˜ _์‚ฐ์ถœ๋ฌผ_(์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ)์ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ฐธ์กฐ๋  ๋•Œ ๋ธŒ๋ผ์šฐ์ €๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ์•ž์„œ Inspirations ์•ฑ ์˜ˆ์‹œ์—์„œ ๋ณด์—ฌ์ค€ ๊ฒƒ์ฒ˜๋Ÿผ `FancyText`๋Š” ๊ฐ€์ ธ์˜ค๊ณ  ์‚ฌ์šฉ๋˜๋Š” ์œ„์น˜์— ๋”ฐ๋ผ ์„œ๋ฒ„ ๋˜๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ `FancyText`์˜ HTML ์ถœ๋ ฅ์ด ์˜์กด์„ฑ์„ ํฌํ•จํ•œ ์†Œ์Šค ์ฝ”๋“œ์— ๋น„ํ•ด ํฌ๋‹ค๋ฉด, ํ•ญ์ƒ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ•์ œํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•œ ์˜ˆ๋กœ ๊ธด SVG ๊ฒฝ๋กœ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ•์ œํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ž…๋‹ˆ๋‹ค. +ํ•˜์ง€๋งŒ `FancyText`์˜ HTML ์ถœ๋ ฅ์ด (์˜์กด์„ฑ์„ ํฌํ•จํ•œ) ์†Œ์Šค ์ฝ”๋“œ์— ๋น„ํ•ด ํฌ๋‹ค๋ฉด, ํ•ญ์ƒ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ•์ œํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•œ ์˜ˆ๋กœ ๊ธด SVG ๊ฒฝ๋กœ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐ•์ œํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ž…๋‹ˆ๋‹ค. ### ํด๋ผ์ด์–ธํŠธ API ์‚ฌ์šฉ {/*using-client-apis*/} -React ์•ฑ์—์„œ๋Š” ์›น ์Šคํ† ๋ฆฌ์ง€, ์˜ค๋””์˜ค ๋ฐ ๋น„๋””์˜ค ์กฐ์ž‘, ํ•˜๋“œ์›จ์–ด ์žฅ์น˜ ๋“ฑ๊ณผ ๊ฐ™์€ [๋ธŒ๋ผ์šฐ์ €์˜ API](https://developer.mozilla.org/ko/docs/Web/API)๋ฅผ ํฌํ•จํ•œ ํด๋ผ์ด์–ธํŠธ ํŠน์ • API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +React ์•ฑ์—์„œ๋Š” ์›น ์Šคํ† ๋ฆฌ์ง€, ์˜ค๋””์˜ค ๋ฐ ๋น„๋””์˜ค ์กฐ์ž‘, ํ•˜๋“œ์›จ์–ด ์žฅ์น˜ ๋“ฑ๊ณผ ๊ฐ™์€ [๋ธŒ๋ผ์šฐ์ €์˜ API](https://developer.mozilla.org/ko/docs/Web/API)๋ฅผ ํฌํ•จํ•œ ํด๋ผ์ด์–ธํŠธ ์ „์šฉ API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ์—์„œ ์ปดํฌ๋„ŒํŠธ๋Š” [DOM API](https://developer.mozilla.org/ko/docs/Glossary/DOM)๋ฅผ ์‚ฌ์šฉํ•ด [`canvas`](https://developer.mozilla.org/ko/docs/Web/HTML/Element/canvas) ์š”์†Œ๋ฅผ ์กฐ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ API๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. @@ -400,13 +367,13 @@ export default function Circle() { React ์•ฑ์—์„œ๋Š” ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ผ๋ฐ˜์ ์ธ UI ํŒจํ„ด์ด๋‚˜ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์€ ์ปดํฌ๋„ŒํŠธ Hook์ด๋‚˜ ํด๋ผ์ด์–ธํŠธ API์— ์˜์กดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ React API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์„œ๋“œํŒŒํ‹ฐ ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -* [createContext](/reference/react/createContext) +* [`createContext`](/reference/react/createContext) * [`use`](/reference/react/use) ๋ฐ [`useId`](/reference/react/useId)๋ฅผ ์ œ์™ธํ•œ [`react`](/reference/react/hooks)์™€ [`react-dom`](/reference/react-dom/hooks)์˜ Hook -* [forwardRef](/reference/react/forwardRef) -* [memo](/reference/react/memo) -* [startTransition](/reference/react/startTransition) +* [`forwardRef`](/reference/react/forwardRef) +* [`memo`](/reference/react/memo) +* [`startTransition`](/reference/react/startTransition) * ํด๋ผ์ด์–ธํŠธ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ(์˜ˆ: DOM ์‚ฝ์ž… ํ˜น์€ ๋„ค์ดํ‹ฐ๋ธŒ ํ”Œ๋žซํผ ๋ทฐ ๋“ฑ) -์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ ํ˜ธํ™˜๋˜๋„๋ก ์—…๋ฐ์ดํŠธ๋˜์—ˆ๋‹ค๋ฉด ์ด๋ฏธ `'use client'`๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ๋งŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์™€ ๊ฐ™์€ props๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•  ์„œ๋“œํŒŒํ‹ฐ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์™€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์ด์— ์ž์ฒด ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ ํ˜ธํ™˜๋˜๋„๋ก ์—…๋ฐ์ดํŠธ๋˜์—ˆ๋‹ค๋ฉด ์ด๋ฏธ `'use client'`๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์™€ ๊ฐ™์€ Props๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ์‚ฌ์šฉํ•  ์„œ๋“œํŒŒํ‹ฐ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์™€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์ด์— ์ž์ฒด ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [TODO]: <> (Troubleshooting - need use-cases) From 43674555e9f8de11748ca618a00bf4fe237eae8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Thu, 2 Jan 2025 23:44:05 +0900 Subject: [PATCH 0383/1059] docs: update `use-server.md` --- src/content/reference/rsc/use-client.md | 8 +- src/content/reference/rsc/use-server.md | 180 ++++++------------------ 2 files changed, 44 insertions(+), 144 deletions(-) diff --git a/src/content/reference/rsc/use-client.md b/src/content/reference/rsc/use-client.md index 448860414..252884f7a 100644 --- a/src/content/reference/rsc/use-client.md +++ b/src/content/reference/rsc/use-client.md @@ -12,7 +12,7 @@ titleForTitleTag: "'use client' ์ง€์‹œ์–ด" <Intro> -`'use client'`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ์—์„œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`'use client'`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์—์„œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. </Intro> @@ -260,7 +260,7 @@ React ์•ฑ์—์„œ์™€ ๊ฐ™์ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ด * [boolean](https://developer.mozilla.org/ko/docs/Glossary/Boolean) * [undefined](https://developer.mozilla.org/ko/docs/Glossary/Undefined) * [null](https://developer.mozilla.org/ko/docs/Glossary/Null) - * [symbol](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol) ( [`Symbol.for`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for)์„ ํ†ตํ•ด ๊ธ€๋กœ๋ฒŒ ์‹ฌ๋ณผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋“ฑ๋ก๋œ ์‹ฌ๋ณผ๋งŒ ํ•ด๋‹น) + * [symbol](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol) ( [`Symbol.for`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for)๋ฅผ ํ†ตํ•ด ์ „์—ญ ์‹ฌ๋ณผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋“ฑ๋ก๋œ ์‹ฌ๋ณผ๋งŒ ํ•ด๋‹น) * ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ํฌํ•จํ•˜๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ” * [String](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String) * [Array](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array) @@ -271,13 +271,13 @@ React ์•ฑ์—์„œ์™€ ๊ฐ™์ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ด * ์ผ๋ฐ˜ [๊ฐ์ฒด](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object) (์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ [๊ฐ์ฒด ์ด๋‹ˆ์…œ๋ผ์ด์ €](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Object_initializer)๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด) * [์„œ๋ฒ„ ํ•จ์ˆ˜](/reference/rsc/server-functions)๋กœ์„œ์˜ ํ•จ์ˆ˜ * ํด๋ผ์ด์–ธํŠธ ๋˜๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์š”์†Œ(JSX) -* [Promises](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise) +* [Promise](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise) ๋‹จ, ๋‹ค์Œ์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. * ํด๋ผ์ด์–ธํŠธ๋กœ ํ‘œ์‹œ๋œ ๋ชจ๋“ˆ์—์„œ ๋‚ด๋ณด๋‚ด์ง€ ์•Š์•˜๊ฑฐ๋‚˜ [`'use server'`](/reference/rsc/use-server)๋กœ ํ‘œ์‹œ๋œ [ํ•จ์ˆ˜](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function) * [ํด๋ž˜์Šค](https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Classes_in_JavaScript) * ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋‚ด์žฅํ˜• ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์•„๋‹Œ ๊ฐ์ฒด ํ˜น์€ [null ํ”„๋กœํ† ํƒ€์ž…](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects)์„ ๊ฐ€์ง„ ๊ฐ์ฒด -* ๊ธ€๋กœ๋ฒŒํ•˜๊ฒŒ ๋“ฑ๋ก๋˜์ง€ ์•Š์€ symbol (์˜ˆ: `Symbol('my new symbol')`) +* ์ „์—ญ์— ๋“ฑ๋ก๋˜์ง€ ์•Š์€ Symbol (์˜ˆ: `Symbol('my new symbol')`) ## ์‚ฌ์šฉ๋ฒ• {/*usage*/} diff --git a/src/content/reference/rsc/use-server.md b/src/content/reference/rsc/use-server.md index fa644d03e..edb8d917c 100644 --- a/src/content/reference/rsc/use-server.md +++ b/src/content/reference/rsc/use-server.md @@ -1,27 +1,18 @@ --- title: "'use server'" -<<<<<<< HEAD titleForTitleTag: "'use server' ์ง€์‹œ์–ด" -canary: true -======= -titleForTitleTag: "'use server' directive" ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc --- <RSC> -<<<<<<< HEAD -`'use server'`๋Š” [React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉ](/learn/start-a-new-react-project#bleeding-edge-react-frameworks)ํ•˜๊ฑฐ๋‚˜ ๊ทธ์™€ ํ˜ธํ™˜๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค ๋•Œ๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. -======= `'use server'` is for use with [using React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc </RSC> <Intro> -`'use server'`๋Š” ํด๋ผ์ด์–ธํŠธ ์ธก ์ฝ”๋“œ์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„ ์ธก ํ•จ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. +`'use server'`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ ์ธก ์ฝ”๋“œ์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„ ์ธก ํ•จ์ˆ˜๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. </Intro> @@ -33,11 +24,7 @@ titleForTitleTag: "'use server' directive" ### `'use server'` {/*use-server*/} -<<<<<<< HEAD -ํ•จ์ˆ˜๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Œ์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด, ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ๋งจ ์œ„์— `'use server';`๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”. ์šฐ๋ฆฌ๋Š” ์ด๋ฅผ _Server Actions_ ์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. -======= -Add `'use server'` at the top of an async function body to mark the function as callable by the client. We call these functions [_Server Functions_](/reference/rsc/server-functions). ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +ํ•จ์ˆ˜๋ฅผ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Œ์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด, ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ์ตœ์ƒ๋‹จ์— `'use server';`๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”. ์ด๋ฅผ [_์„œ๋ฒ„ ํ•จ์ˆ˜_](/reference/rsc/server-functions)๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ```js {2} async function addToCart(data) { @@ -46,53 +33,28 @@ async function addToCart(data) { } ``` -<<<<<<< HEAD -Server Action์„ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ˜ธ์ถœํ•˜๋ฉด, ์ง๋ ฌํ™”๋œ ์ธ์ž์˜ ์‚ฌ๋ณธ์„ ํฌํ•จํ•˜๋Š” ์„œ๋ฒ„๋กœ์˜ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. Server Action์ด ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด, ๊ทธ ๊ฐ’์€ ์ง๋ ฌํ™”๋˜๊ณ  ํด๋ผ์ด์–ธํŠธ์— ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. +ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ์ „๋‹ฌ๋œ ๋ชจ๋“  ์ธ์ˆ˜์˜ ์ง๋ ฌํ™”๋œ ์‚ฌ๋ณธ์„ ํฌํ•จํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์„œ๋ฒ„๋กœ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„ ํ•จ์ˆ˜๊ฐ€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด, ๊ทธ ๊ฐ’์„ ์ง๋ ฌํ™”ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -ํ•จ์ˆ˜ ๊ฐ๊ฐ์— `'use server'`๋ฅผ ํ‘œ๊ธฐํ•˜๋Š” ๋Œ€์‹ , ํŒŒ์ผ์˜ ๋งจ ์œ„์— ์ง€์‹œ์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํŒŒ์ผ์˜ ๋ชจ๋“  export๋ฅผ, ํด๋ผ์ด์–ธํŠธ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Server Action์œผ๋กœ ํ‘œ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํ•จ์ˆ˜ ๊ฐ๊ฐ์— `'use server'`๋ฅผ ํ‘œ๊ธฐํ•˜๋Š” ๋Œ€์‹ , ํŒŒ์ผ์˜ ์ตœ์ƒ๋‹จ์— ์ง€์‹œ์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํŒŒ์ผ์˜ ๋ชจ๋“  ๋‚ด๋ณด๋‚ด๊ธฐ<sup>Export</sup>๋ฅผ ํด๋ผ์ด์–ธํŠธ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์„œ๋ฒ„ ํ•จ์ˆ˜๋กœ ํ‘œ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} -* `'use server'`๋Š” ํ•จ์ˆ˜ ๋˜๋Š” ๋ชจ๋“ˆ์˜ ๋งจ ์ฒ˜์Œ์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. import๋ฅผ ํฌํ•จํ•œ ๋‹ค๋ฅธ ์ฝ”๋“œ๋ณด๋‹ค ์œ„์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.(์ง€์‹œ์–ด ์œ„์˜ ์ฃผ์„์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค). ๋ฐฑํ‹ฑ์ด ์•„๋‹Œ ๋‹จ์ผ ๋˜๋Š” ์ด์ค‘ ๋”ฐ์˜ดํ‘œ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -* `'use server'`๋Š” ์„œ๋ฒ„ ์ธก ํŒŒ์ผ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์ธ Server Action์€ props๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ œ๊ณต๋˜๋Š” [์ง๋ ฌํ™” ํƒ€์ž…](#serializable-parameters-and-return-values)์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. -* Server Action์„ [ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ](/reference/rsc/use-client)์—์„œ import ํ•˜๊ธฐ ์œ„ํ•ด, ์ง€์‹œ์–ด๋Š” ๋ชจ๋“ˆ ์ˆ˜์ค€์—์„œ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -* ๊ธฐ๋ณธ ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ์ด ํ•ญ์ƒ ๋น„๋™๊ธฐ์ด๋ฏ€๋กœ `'use server'`๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -* ํ•ญ์ƒ Server Action์˜ ์ธ์ž๋ฅผ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ž…๋ ฅ์œผ๋กœ ์ทจ๊ธ‰ํ•˜๊ณ  ๋ชจ๋“  ๋ณ€๊ฒฝ์„ ๊ฒ€ํ† ํ•˜์„ธ์š”. [๋ณด์•ˆ ๊ณ ๋ ค์‚ฌํ•ญ](#security)์„ ํ™•์ธํ•˜์„ธ์š”. -* Server Action์€ [transition](/reference/react/useTransition) ์•ˆ์—์„œ ํ˜ธ์ถœ๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. [`<form action>`](/reference/react-dom/components/form#props) ๋˜๋Š” [`formAction`](/reference/react-dom/components/input#props)๋กœ ์ „๋‹ฌ๋œ Server Action์€ ์ž๋™์œผ๋กœ transition ๋‚ด์—์„œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. -* Server Action์€ ์„œ๋ฒ„ ์ธก ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” mutation์„ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ ๋ฐ์ดํ„ฐ fetching์—๋Š” ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์„œ๋ฒ„ ์•ก์…˜์„ ๊ตฌํ˜„ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์•ก์…˜์„ ์ฒ˜๋ฆฌํ•˜๋ฉฐ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์บ์‹œํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. -======= -When calling a Server Function on the client, it will make a network request to the server that includes a serialized copy of any arguments passed. If the Server Function returns a value, that value will be serialized and returned to the client. - -Instead of individually marking functions with `'use server'`, you can add the directive to the top of a file to mark all exports within that file as Server Functions that can be used anywhere, including imported in client code. - -#### Caveats {/*caveats*/} -* `'use server'` must be at the very beginning of their function or module; above any other code including imports (comments above directives are OK). They must be written with single or double quotes, not backticks. -* `'use server'` can only be used in server-side files. The resulting Server Functions can be passed to Client Components through props. See supported [types for serialization](#serializable-parameters-and-return-values). -* To import a Server Functions from [client code](/reference/rsc/use-client), the directive must be used on a module level. -* Because the underlying network calls are always asynchronous, `'use server'` can only be used on async functions. -* Always treat arguments to Server Functions as untrusted input and authorize any mutations. See [security considerations](#security). -* Server Functions should be called in a [Transition](/reference/react/useTransition). Server Functions passed to [`<form action>`](/reference/react-dom/components/form#props) or [`formAction`](/reference/react-dom/components/input#props) will automatically be called in a transition. -* Server Functions are designed for mutations that update server-side state; they are not recommended for data fetching. Accordingly, frameworks implementing Server Functions typically process one action at a time and do not have a way to cache the return value. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +* `'use server'`๋Š” ํ•จ์ˆ˜ ๋˜๋Š” ๋ชจ๋“ˆ์˜ ์ตœ์ƒ๋‹จ์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `import`๋ฅผ ํฌํ•จํ•œ ๋‹ค๋ฅธ ์ฝ”๋“œ๋ณด๋‹ค ์œ„์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (์ง€์‹œ์–ด ์œ„์˜ ์ฃผ์„์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.) ๋ฐฑํ‹ฑ์ด ์•„๋‹Œ ๋‹จ์ผ ๋˜๋Š” ์ด์ค‘ ๋”ฐ์˜ดํ‘œ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +* `'use server'`๋Š” ์„œ๋ฒ„ ์ธก ํŒŒ์ผ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ƒ์„ฑ๋œ ์„œ๋ฒ„ ํ•จ์ˆ˜๋Š” Props๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€์›๋˜๋Š” [์ง๋ ฌํ™” ํƒ€์ž…](#serializable-parameters-and-return-values)์„ ์ฐธ๊ณ ํ•˜์„ธ์š”. +* ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ [ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ](/reference/rsc/use-client)์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ<sup>Import</sup> ์œ„ํ•ด, ์ง€์‹œ์–ด๋ฅผ ๋ชจ๋“ˆ ์ˆ˜์ค€์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +* ๊ธฐ๋ณธ ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ์ด ํ•ญ์ƒ ๋น„๋™๊ธฐ์ ์ด๋ฏ€๋กœ, `'use server'`๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* ํ•ญ์ƒ ์„œ๋ฒ„ ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ž…๋ ฅ์œผ๋กœ ์ทจ๊ธ‰ํ•˜๊ณ  ๋ชจ๋“  ๋ณ€๊ฒฝ์„ ๊ฒ€ํ† ํ•˜์„ธ์š”. [๋ณด์•ˆ ๊ณ ๋ ค์‚ฌํ•ญ](#security)์„ ํ™•์ธํ•˜์„ธ์š”. +* ์„œ๋ฒ„ ํ•จ์ˆ˜๋Š” [Transition](/reference/react/useTransition) ์•ˆ์—์„œ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. [`<form action>`](/reference/react-dom/components/form#props) ๋˜๋Š” [`formAction`](/reference/react-dom/components/input#props)์œผ๋กœ ์ „๋‹ฌ๋œ ์„œ๋ฒ„ ํ•จ์ˆ˜๋Š” ์ž๋™์œผ๋กœ Transition ๋‚ด์—์„œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. +* ์„œ๋ฒ„ ํ•จ์ˆ˜๋Š” ์„œ๋ฒ„ ์ธก ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” Mutation์„ ์œ„ํ•ด ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ<sup>Fetching</sup>์—๋Š” ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์ž‘์—…๋งŒ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ๋ฐ˜ํ™˜ ๊ฐ’์„ ์บ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ### ๋ณด์•ˆ ๊ณ ๋ ค์‚ฌํ•ญ {/*security*/} -<<<<<<< HEAD -Server Action์— ๋Œ€ํ•œ ์ธ์ˆ˜๋Š” ์™„์ „ํžˆ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ œ์–ด๋ฉ๋‹ˆ๋‹ค. ๋ณด์•ˆ์„ ์œ„ํ•ด ํ•ญ์ƒ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ž…๋ ฅ์œผ๋กœ ์ทจ๊ธ‰ํ•˜์—ฌ, ์ธ์ž๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๊ฒ€์ฆํ•˜๊ณ  ์ด์Šค์ผ€์ดํ”„ ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. +์„œ๋ฒ„ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ธ์ˆ˜๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์™„์ „ํžˆ ์ œ์–ด๋ฉ๋‹ˆ๋‹ค. ๋ณด์•ˆ์„ ์œ„ํ•ด ํ•ญ์ƒ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ž…๋ ฅ์œผ๋กœ ์ทจ๊ธ‰ํ•˜์—ฌ, ์ธ์ˆ˜๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๊ฒ€์ฆํ•˜๊ณ  ์ด์Šค์ผ€์ดํ”„ ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. -Server Action์—์„œ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. +๋ชจ๋“  ์„œ๋ฒ„ ํ•จ์ˆ˜์—์„œ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. <Wip> -Server Action์—์„œ ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด, ๊ณ ์œ ํ•œ ๊ฐ’๊ณผ ๊ฐ์ฒด๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋กœ ์ „๋‹ฌ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์‹คํ—˜์ ์ธ ํ…Œ์ธํŠธ API๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. -======= -Arguments to Server Functions are fully client-controlled. For security, always treat them as untrusted input, and make sure to validate and escape arguments as appropriate. - -In any Server Function, make sure to validate that the logged-in user is allowed to perform that action. - -<Wip> - -To prevent sending sensitive data from a Server Function, there are experimental taint APIs to prevent unique values and objects from being passed to client code. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +์„œ๋ฒ„ ํ•จ์ˆ˜์—์„œ ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด, ๊ณ ์œ ํ•œ ๊ฐ’๊ณผ ๊ฐ์ฒด๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์‹คํ—˜์ ์ธ Taint API๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. [experimental_taintUniqueValue](/reference/react/experimental_taintUniqueValue)์™€ [experimental_taintObjectReference](/reference/react/experimental_taintObjectReference)๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”. @@ -100,20 +62,19 @@ To prevent sending sensitive data from a Server Function, there are experimental ### ์ง๋ ฌํ™” ๊ฐ€๋Šฅ ์ธ์ˆ˜์™€ ๋ฐ˜ํ™˜๊ฐ’ {/*serializable-parameters-and-return-values*/} -<<<<<<< HEAD -ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ ์ž‘์—…์„ ํ˜ธ์ถœํ•  ๋•Œ ์ „๋‹ฌ๋œ ์ธ์ˆ˜๋Š” ๋ชจ๋‘ ์ง๋ ฌํ™”๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฏ€๋กœ, ์ „๋‹ฌํ•˜๋Š” ๋ชจ๋“  ์ธ์ˆ˜๋Š” ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -๋‹ค์Œ์€ ์ง€์›๋˜๋Š” Server Action ์ธ์ž์˜ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. +๋‹ค์Œ์€ ์„œ๋ฒ„ ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋กœ ์ง€์›๋˜๋Š” ํƒ€์ž…์ž…๋‹ˆ๋‹ค. -* Primitives +* ์›์‹œ ์ž๋ฃŒํ˜• * [string](https://developer.mozilla.org/ko/docs/Glossary/String) * [number](https://developer.mozilla.org/ko/docs/Glossary/Number) * [bigint](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/BigInt) * [boolean](https://developer.mozilla.org/ko/docs/Glossary/Boolean) * [undefined](https://developer.mozilla.org/ko/docs/Glossary/Undefined) * [null](https://developer.mozilla.org/ko/docs/Glossary/Null) - * [symbol](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol), [`Symbol.for`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for)๋ฅผ ํ†ตํ•ด ์ „์—ญ Symbol๋กœ ๋“ฑ๋ก๋œ Symbol ํ•œ์ • -* ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ ๊ฐ’์„ ํฌํ•จํ•œ Iterables + * [symbol](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol) ( [`Symbol.for`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for)๋ฅผ ํ†ตํ•ด ์ „์—ญ ์‹ฌ๋ณผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ๋“ฑ๋ก๋œ ์‹ฌ๋ณผ๋งŒ ํ•ด๋‹น) +* ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’์„ ํฌํ•จํ•˜๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ” * [String](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String) * [Array](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array) * [Map](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Map) @@ -121,67 +82,27 @@ To prevent sending sensitive data from a Server Function, there are experimental * [TypedArray](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)์™€ [ArrayBuffer](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) * [Date](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Date) * [FormData](https://developer.mozilla.org/ko/docs/Web/API/FormData) ์ธ์Šคํ„ด์Šค -* [object initializers](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Object_initializer)๋กœ ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ ์†์„ฑ๊ณผ ํ•จ๊ป˜ ์ƒ์„ฑ๋œ ์ผ๋ฐ˜ [objects](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object) -* Server Action์ธ ํ•จ์ˆ˜ -* [Promises](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise) +* ์ผ๋ฐ˜ [๊ฐ์ฒด](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object) (์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ [๊ฐ์ฒด ์ด๋‹ˆ์…œ๋ผ์ด์ €](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Object_initializer)๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด) +* [์„œ๋ฒ„ ํ•จ์ˆ˜](/reference/rsc/server-functions)๋กœ์„œ์˜ ํ•จ์ˆ˜ +* [Promise](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise) -ํŠนํžˆ ๋‹ค์Œ์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +๋‹จ, ๋‹ค์Œ์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. * React ์—˜๋ฆฌ๋จผํŠธ ๋˜๋Š” [JSX](/learn/writing-markup-with-jsx) -* ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜ ๋˜๋Š” Server Action์ด ์•„๋‹Œ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•˜๋Š” ํ•จ์ˆ˜ +* ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜ ๋˜๋Š” ์„œ๋ฒ„ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•˜๋Š” ํ•จ์ˆ˜ * [ํด๋ž˜์Šค](https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Classes_in_JavaScript) -* ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ธ ๊ฐ์ฒด(์–ธ๊ธ‰๋œ ๋‚ด์žฅ ๊ฐ์ฒด ์ œ์™ธ)๋˜๋Š” [null ํ”„๋กœํ† ํƒ€์ž…](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects)์ด ์žˆ๋Š” ๊ฐœ์ฒด -* ์ „์—ญ์— ๋“ฑ๋ก๋˜์ง€ ์•Š์€ Symbol, ์˜ˆ. `Symbol('my new symbol')` -======= -Since client code calls the Server Function over the network, any arguments passed will need to be serializable. - -Here are supported types for Server Function arguments: - -* Primitives - * [string](https://developer.mozilla.org/en-US/docs/Glossary/String) - * [number](https://developer.mozilla.org/en-US/docs/Glossary/Number) - * [bigint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) - * [boolean](https://developer.mozilla.org/en-US/docs/Glossary/Boolean) - * [undefined](https://developer.mozilla.org/en-US/docs/Glossary/Undefined) - * [null](https://developer.mozilla.org/en-US/docs/Glossary/Null) - * [symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol), only symbols registered in the global Symbol registry via [`Symbol.for`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for) -* Iterables containing serializable values - * [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) - * [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) - * [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) - * [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) - * [TypedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) and [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) -* [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) -* [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) instances -* Plain [objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object): those created with [object initializers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer), with serializable properties -* Functions that are Server Functions -* [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) - -Notably, these are not supported: -* React elements, or [JSX](/learn/writing-markup-with-jsx) -* Functions, including component functions or any other function that is not a Server Function -* [Classes](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript) -* Objects that are instances of any class (other than the built-ins mentioned) or objects with [a null prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects) -* Symbols not registered globally, ex. `Symbol('my new symbol')` +* ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ธ ๊ฐ์ฒด(์–ธ๊ธ‰๋œ ๋‚ด์žฅ ๊ฐ์ฒด ์ œ์™ธ)๋˜๋Š” [null ํ”„๋กœํ† ํƒ€์ž…](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects)์ด ์žˆ๋Š” ๊ฐ์ฒด +* ์ „์—ญ์— ๋“ฑ๋ก๋˜์ง€ ์•Š์€ Symbol (์˜ˆ: `Symbol('my new symbol')`) * Events from event handlers ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc - -์ง€์›๋˜๋Š” ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ ๋ฐ˜ํ™˜ ๊ฐ’์€ ๊ฒฝ๊ณ„ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์˜ [์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ props](/reference/react/use-client#passing-props-from-server-to-client-components)์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. - -### Server Action ํ˜•์‹ {/*server-actions-in-forms*/} -Server Action์˜ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š”, ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ [HTML ํผ ์—˜๋ฆฌ๋จผํŠธ](https://developer.mozilla.org/ko/docs/Web/HTML/Element/form)๋Š” ์‚ฌ์šฉ์ž๊ฐ€ mutation์„ ์ œ์ถœํ•˜๋Š” ์ „ํ†ต์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋กœ, React๋Š” [forms](/reference/react-dom/components/form)์—์„œ Server Action์— ๋Œ€ํ•œ ์ตœ์ƒ์˜ ์ง€์›์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +์ง€์›๋˜๋Š” ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ ๋ฐ˜ํ™˜ ๊ฐ’์€ ๊ฒฝ๊ณ„ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์˜ [์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ Props](/reference/rsc/use-client#passing-props-from-server-to-client-components)์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. -<<<<<<< HEAD -์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋Š” ์–‘์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. -======= -## Usage {/*usage*/} +## ์‚ฌ์šฉ๋ฒ• {/*usage*/} ### Server Functions in forms {/*server-functions-in-forms*/} -The most common use case of Server Functions will be calling functions that mutate data. On the browser, the [HTML form element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) is the traditional approach for a user to submit a mutation. With React Server Components, React introduces first-class support for Server Functions as Actions in [forms](/reference/react-dom/components/form). +์„œ๋ฒ„ ํ•จ์ˆ˜์˜ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š”, ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์˜ [HTML ํผ ์—˜๋ฆฌ๋จผํŠธ](https://developer.mozilla.org/ko/docs/Web/HTML/Element/form)๋Š” ์‚ฌ์šฉ์ž๊ฐ€ Mutation์„ ์ œ์ถœํ•˜๋Š” ์ „ํ†ต์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•ด, React๋Š” [ํผ<sup>Form</sup>](/reference/react-dom/components/form)์—์„œ ์•ก์…˜์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์„œ๋ฒ„ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ตœ์ƒ์˜ ์ง€์›์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. -Here is a form that allows a user to request a username. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +์—ฌ๊ธฐ, ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋Š” ํผ<sup>Form</sup>์ด ์žˆ์Šต๋‹ˆ๋‹ค. ```js [[1, 3, "formData"]] // App.js @@ -202,24 +123,15 @@ export default function App() { } ``` -<<<<<<< HEAD -์˜ˆ์‹œ์—์„œ `requestUsername`๋Š” `<form>`์„ ํ†ตํ•œ Server Action์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ด ์–‘์‹์„ ์ œ์ถœํ•˜๋ฉด ์„œ๋ฒ„ ํ•จ์ˆ˜์ธ `requestUsername`์— ๋„คํŠธ์›Œํฌ ์š”์ฒญ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํผ์—์„œ Server Action์„ ํ˜ธ์ถœํ•  ๋•Œ React๋Š” ํผ์˜ <CodeStep step={1}>[FormData](https://developer.mozilla.org/ko/docs/Web/API/FormData)</CodeStep>๋ฅผ Server Action์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. - -Server Action์„ ํผ `action`์— ์ „๋‹ฌํ•˜์—ฌ, React๋Š” ํผ์„ [์ ์ง„์  ํ–ฅ์ƒ](https://developer.mozilla.org/ko/docs/Glossary/Progressive_Enhancement)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค์ด ๋กœ๋“œ๋˜๊ธฐ ์ „์— ์–‘์‹์„ ์ œ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -======= -In this example `requestUsername` is a Server Function passed to a `<form>`. When a user submits this form, there is a network request to the server function `requestUsername`. When calling a Server Function in a form, React will supply the form's <CodeStep step={1}>[FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData)</CodeStep> as the first argument to the Server Function. - -By passing a Server Function to the form `action`, React can [progressively enhance](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement) the form. This means that forms can be submitted before the JavaScript bundle is loaded. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +์˜ˆ์‹œ์—์„œ `requestUsername`์€ `<form>`์„ ํ†ตํ•œ ์„œ๋ฒ„ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ด ํผ<sup>Form</sup>์„ ์ œ์ถœํ•˜๋ฉด ์„œ๋ฒ„ ํ•จ์ˆ˜์ธ `requestUsername`์— ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ํผ<sup>Form</sup>์—์„œ ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, React๋Š” ํผ<sup>Form</sup>์˜ <CodeStep step={1}>[formData](https://developer.mozilla.org/ko/docs/Web/API/FormData)</CodeStep>๋ฅผ ์„œ๋ฒ„ ํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํผ `action`์— ์ „๋‹ฌํ•˜์—ฌ, React๋Š” ํผ์„ [์ ์ง„์  ํ–ฅ์ƒ](https://developer.mozilla.org/ko/docs/Glossary/Progressive_Enhancement)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค์„ ๋กœ๋“œํ•˜๊ธฐ ์ „์— ์–‘์‹์„ ์ œ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. #### ํผ์—์„œ ๋ฐ˜ํ™˜ ๊ฐ’ ์ฒ˜๋ฆฌ {/*handling-return-values*/} -<<<<<<< HEAD -์ ์ง„์  ํ–ฅ์ƒ์„ ์ง€์›ํ•˜๋ฉฐ Server Action์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ UI๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ ค๋ฉด, [`useActionState`](/reference/react/useActionState)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. -======= -To update the UI based on the result of a Server Function while supporting progressive enhancement, use [`useActionState`](/reference/react/useActionState). ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +In the username request form, there might be the chance that a username is not available. `requestUsername` should tell us if it fails or not. + +์ ์ง„์  ํ–ฅ์ƒ์„ ์ง€์›ํ•˜๋ฉฐ ์„œ๋ฒ„ ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ UI๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ ค๋ฉด, [`useActionState`](/reference/react/useActionState)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ```js // requestUsername.js @@ -257,21 +169,13 @@ function UsernameForm() { } ``` -๋Œ€๋ถ€๋ถ„์˜ Hook๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ `useActionState`๋Š” <CodeStep step={1}>[client code](/reference/rsc/use-client)</CodeStep>์—์„œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -<<<<<<< HEAD -### `<form>`์™ธ๋ถ€์—์„œ Server Action ํ˜ธ์ถœํ•˜๊ธฐ {/*calling-a-server-action-outside-of-form*/} - -Server Action์€ ๋…ธ์ถœ๋œ ์„œ๋ฒ„ ์—”๋“œํฌ์ธํŠธ์ด๋ฉฐ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ์–ด๋””์—์„œ๋‚˜ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋Œ€๋ถ€๋ถ„์˜ Hook๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ `useActionState`๋Š” <CodeStep step={2}>[ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ](/reference/rsc/use-client)</CodeStep>์—์„œ๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -[form](/reference/react-dom/components/form) ์™ธ๋ถ€์—์„œ Server Action์„ ์‚ฌ์šฉํ•  ๋•Œ, [Transition](/reference/react/useTransition)์—์„œ ์„œ๋ฒ„ ์•ก์…˜์„ ํ˜ธ์ถœํ•˜๋ฉด ๋กœ๋”ฉ ์ธ๋””์ผ€์ดํ„ฐ๋ฅผ ํ‘œ์‹œํ•˜๊ณ , [๋‚™๊ด€์  ์ƒํƒœ ์—…๋ฐ์ดํŠธ](/reference/react/useOptimistic)๋ฅผ ํ‘œ์‹œํ•˜๋ฉฐ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํผ์€ transition์˜ Server Action์„ ์ž๋™์œผ๋กœ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค. -======= -### Calling a Server Function outside of `<form>` {/*calling-a-server-function-outside-of-form*/} +### `<form>`์™ธ๋ถ€์—์„œ ์„œ๋ฒ„ ํ•จ์ˆ˜ ํ˜ธ์ถœํ•˜๊ธฐ {/*calling-a-server-function-outside-of-form*/} -Server Functions are exposed server endpoints and can be called anywhere in client code. +์„œ๋ฒ„ ํ•จ์ˆ˜๋Š” ๋…ธ์ถœ๋œ ์„œ๋ฒ„ ์—”๋“œํฌ์ธํŠธ์ด๋ฉฐ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ์–ด๋””์—์„œ๋‚˜ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -When using a Server Function outside a [form](/reference/react-dom/components/form), call the Server Function in a [Transition](/reference/react/useTransition), which allows you to display a loading indicator, show [optimistic state updates](/reference/react/useOptimistic), and handle unexpected errors. Forms will automatically wrap Server Functions in transitions. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +[ํผ<sup>Form</sup>](/reference/react-dom/components/form) ์™ธ๋ถ€์—์„œ ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, [Transition](/reference/react/useTransition)์—์„œ ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋กœ๋”ฉ ์ธ๋””์ผ€์ดํ„ฐ<sup>Loading Indicator</sup>๋ฅผ ํ‘œ์‹œํ•˜๊ณ , [๋‚™๊ด€์  ์ƒํƒœ ์—…๋ฐ์ดํŠธ](/reference/react/useOptimistic)๋ฅผ ํ‘œ์‹œํ•˜๋ฉฐ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํผ์€ Transition์˜ ์„œ๋ฒ„ ํ•จ์ˆ˜๋ฅผ ์ž๋™์œผ๋กœ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค. ```js {9-12} import incrementLike from './actions'; @@ -308,8 +212,4 @@ export default async function incrementLike() { } ``` -<<<<<<< HEAD -Server Action ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ฝ์œผ๋ ค๋ฉด ๋ฐ˜ํ™˜๋œ promise๋ฅผ `await` ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. -======= -To read a Server Function return value, you'll need to `await` the promise returned. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +์„œ๋ฒ„ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ฝ์œผ๋ ค๋ฉด ๋ฐ˜ํ™˜๋œ Promise๋ฅผ `await` ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. From 9137ecc96c7b3ef1c592b0d0bb5d366c008fd3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Thu, 2 Jan 2025 23:59:27 +0900 Subject: [PATCH 0384/1059] docs: update `rules/index.md` --- src/content/reference/rules/index.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/content/reference/rules/index.md b/src/content/reference/rules/index.md index 586abda2b..4c28026ba 100644 --- a/src/content/reference/rules/index.md +++ b/src/content/reference/rules/index.md @@ -3,7 +3,7 @@ title: React์˜ ๊ทœ์น™ --- <Intro> -๊ฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋งˆ๋‹ค ๊ฐœ๋…์„ ํ‘œํ˜„ํ•˜๋Š” ๊ณ ์œ ํ•œ ๋ฐฉ์‹์ด ์žˆ๋“ฏ์ด, React๋„ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ณ  ๊ณ ํ’ˆ์งˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒ์„ฑํ•˜๋Š” ํŒจํ„ด์„ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๊ณ ์œ ํ•œ ๊ด€์šฉ๊ตฌ์™€ ๊ทœ์น™์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. +๊ฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋งˆ๋‹ค ๊ฐœ๋…์„ ํ‘œํ˜„ํ•˜๋Š” ๊ณ ์œ ํ•œ ๋ฐฉ์‹์ด ์žˆ๋“ฏ์ด, React์—๋„ ํŒจํ„ด ์ดํ•ด๋ฅผ ์‰ฝ๊ฒŒ ํ•˜๋ฉฐ ๊ณ ํ’ˆ์งˆ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ์ผ์ข…์˜ ๊ทœ์น™ ํ˜น์€ ๋ชจ๋ฒ”์ ์ธ ๋ฐฉ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. </Intro> <InlineToc /> @@ -14,22 +14,22 @@ title: React์˜ ๊ทœ์น™ React๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋” ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด [React๋กœ ์‚ฌ๊ณ ํ•˜๊ธฐ](/learn/thinking-in-react)๋ฅผ ์ฝ์–ด๋ณด๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. </Note> -์ด ์„น์…˜์—์„œ๋Š” ๊ด€์šฉ์ ์ธ React ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ทœ์น™์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ด€์šฉ์ ์ธ React ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ฒด๊ณ„์ ์œผ๋กœ ์กฐ์งํ•˜๊ณ  ์•ˆ์ „ํ•˜๋ฉฐ ์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํŠน์„ฑ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ณ€ํ™”์— ๋” ์ž˜ ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ณ  ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ๋„๊ตฌ์™€์˜ ํ˜‘์—…์„ ๋” ์›ํ™œํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. +์ด ์„น์…˜์—์„œ๋Š” ๋ชจ๋ฒ”์ ์ธ React ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ทœ์น™์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋ฒ”์ ์ธ React ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ฒด๊ณ„์ ์œผ๋กœ ์กฐ์งํ•˜๊ณ  ์•ˆ์ „ํ•˜๋ฉฐ ์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํŠน์„ฑ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ณ€ํ™”์— ๋” ์ž˜ ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ณ  ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ๋„๊ตฌ์™€์˜ ํ˜‘์—…์„ ๋” ์›ํ™œํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. -์ด๋Ÿฌํ•œ ๊ทœ์น™์„ **React์˜ ๊ทœ์น™** ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋‹จ์ˆœํ•œ ์ง€์นจ์ด ์•„๋‹ˆ๋ผ ๊ทœ์น™์œผ๋กœ, ์ด๋ฅผ ์–ด๊ธธ ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ฒ„๊ทธ๊ฐ€ ์ƒ๊ธธ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์œผ๋ฉฐ ์ฝ”๋“œ๊ฐ€ ์ผ๋ฐ˜์ ์ด์ง€ ์•Š๊ฒŒ ๋ณ€ํ•ด ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๊ณ  ๋…ผ๋ฆฌ์ ์œผ๋กœ ์„ค๋ช…ํ•˜๊ธฐ ํž˜๋“ค์–ด์ง‘๋‹ˆ๋‹ค. +์ด๋Ÿฌํ•œ ๊ทœ์น™์„ **React์˜ ๊ทœ์น™**์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋‹จ์ˆœํ•œ ์ง€์นจ์ด ์•„๋‹ˆ๋ผ ๊ทœ์น™์œผ๋กœ, ์ด๋ฅผ ์–ด๊ธธ ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ฒ„๊ทธ๊ฐ€ ์ƒ๊ธธ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์œผ๋ฉฐ ์ฝ”๋“œ๊ฐ€ ์ผ๋ฐ˜์ ์ด์ง€ ์•Š๊ฒŒ ๋ณ€ํ•ด ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๊ณ  ๋…ผ๋ฆฌ์ ์œผ๋กœ ์„ค๋ช…ํ•˜๊ธฐ ํž˜๋“ค์–ด์ง‘๋‹ˆ๋‹ค. -์ฝ”๋“œ๋ฒ ์ด์Šค๊ฐ€ React์˜ ๊ทœ์น™์„ ๋”ฐ๋ฅด๋„๋ก ๋•๊ธฐ ์œ„ํ•ด React์˜ [ESLint](https://www.npmjs.com/package/eslint-plugin-react-hooks) ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ ํ•จ๊ป˜ [Strict Mode](/reference/react/StrictMode)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ฐ•๋ ฅํžˆ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. React์˜ ๊ทœ์น™์„ ๋”ฐ๋ฅด๋ฉด ๋ฒ„๊ทธ๋ฅผ ์ฐพ์•„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์œ ์ง€ ๋ณด์ˆ˜์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ฝ”๋“œ๋ฒ ์ด์Šค๊ฐ€ React์˜ ๊ทœ์น™์„ ๋”ฐ๋ฅด๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด React์˜ [ESLint](https://www.npmjs.com/package/eslint-plugin-react-hooks) ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ ํ•จ๊ป˜ [Strict Mode](/reference/react/StrictMode)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ฐ•๋ ฅํžˆ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. React์˜ ๊ทœ์น™์„ ๋”ฐ๋ฅด๋ฉด ๋ฒ„๊ทธ๋ฅผ ์ฐพ์•„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์œ ์ง€ ๋ณด์ˆ˜์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --- ## ์ปดํฌ๋„ŒํŠธ์™€ Hook์€ ์ˆœ์ˆ˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค {/*components-and-hooks-must-be-pure*/} -[์ปดํฌ๋„ŒํŠธ์™€ Hook์˜ ์ˆœ์ˆ˜์„ฑ](/reference/rules/components-and-hooks-must-be-pure)์€ React์˜ ์ฃผ์š” ๊ทœ์น™์œผ๋กœ ์ด๋ฅผ ํ†ตํ•ด ์•ฑ์˜ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ณ  ๋””๋ฒ„๊น…์ด ์‰ฌ์›Œ์ง€๋ฉฐ React๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +[์ปดํฌ๋„ŒํŠธ์™€ Hook์˜ ์ˆœ์ˆ˜์„ฑ](/reference/rules/components-and-hooks-must-be-pure)์€ React์˜ ์ฃผ์š” ๊ทœ์น™์œผ๋กœ, ์ด๋ฅผ ํ†ตํ•ด ์•ฑ์ด ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ณ  ๋””๋ฒ„๊น…์ด ์‰ฌ์›Œ์ง€๋ฉฐ React๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -* [์ปดํฌ๋„ŒํŠธ๋Š” ๋ฉฑ๋“ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent) โ€“ React ์ปดํฌ๋„ŒํŠธ๋Š” ํ•ญ์ƒ ์ž…๋ ฅ ๊ฐ’(props, state, context)์— ๋”ฐ๋ผ ๋™์ผํ•œ ์ถœ๋ ฅ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. +* [์ปดํฌ๋„ŒํŠธ๋Š” ๋ฉฑ๋“ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent) โ€“ React ์ปดํฌ๋„ŒํŠธ๋Š” ํ•ญ์ƒ ์ž…๋ ฅ ๊ฐ’(Props, State, Context)์— ๋”ฐ๋ผ ๋™์ผํ•œ ์ถœ๋ ฅ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. * [์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” ๋ Œ๋”๋ง ์™ธ๋ถ€์—์„œ ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) โ€“ [์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ](/learn/keeping-components-pure#side-effects-unintended-consequences)๋Š” React๊ฐ€ ์ตœ์ƒ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ Œ๋”๋ง ์ค‘์— ์‹คํ–‰๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. -* [Props์™€ state๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#props-and-state-are-immutable) โ€“ ์ปดํฌ๋„ŒํŠธ์˜ props์™€ state๋Š” ๋‹จ์ผ ๋ Œ๋”๋ง์— ๋Œ€ํ•ด ๋ถˆ๋ณ€์˜ [์Šค๋ƒ…์ƒท](/learn/state-as-a-snapshot)์ž…๋‹ˆ๋‹ค. ์ ˆ๋Œ€ ์ด๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. -* [Hook์˜ ๋ฐ˜ํ™˜๊ฐ’๊ณผ ์ธ์ˆ˜๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#return-values-and-arguments-to-hooks-are-immutable) โ€“ ๊ฐ’์ด Hook์— ์ „๋‹ฌ๋˜๋ฉด ์ด๋ฅผ ์ˆ˜์ •ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. JSX์˜ props์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Hook์— ์ „๋‹ฌ๋œ ๊ฐ’๋„ ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค. +* [Props์™€ State๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#props-and-state-are-immutable) โ€“ ์ปดํฌ๋„ŒํŠธ์˜ Props์™€ State๋Š” ๋‹จ์ผ ๋ Œ๋”๋ง์— ๋Œ€ํ•œ ๋ถˆ๋ณ€์˜ [์Šค๋ƒ…์ƒท](/learn/state-as-a-snapshot)์ž…๋‹ˆ๋‹ค. ์ ˆ๋Œ€ ์ด๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. +* [Hook์˜ ๋ฐ˜ํ™˜๊ฐ’๊ณผ ์ธ์ˆ˜๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#return-values-and-arguments-to-hooks-are-immutable) โ€“ ๊ฐ’์ด Hook์— ์ „๋‹ฌ๋˜๋ฉด ์ด๋ฅผ ์ˆ˜์ •ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. JSX์˜ Props์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Hook์— ์ „๋‹ฌ๋œ ๊ฐ’๋„ ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค. * [JSX๋กœ ์ „๋‹ฌ๋œ ๊ฐ’์€ ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค](/reference/rules/components-and-hooks-must-be-pure#values-are-immutable-after-being-passed-to-jsx) โ€“ JSX์— ์‚ฌ์šฉ๋œ ํ›„์—๋Š” ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. JSX๊ฐ€ ์ƒ์„ฑ๋˜๊ธฐ ์ „์— ๋ณ€๊ฒฝ์„ ์ˆ˜ํ–‰ํ•˜์„ธ์š”. --- @@ -45,8 +45,8 @@ React๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋” ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด [ ## Hook์˜ ๊ทœ์น™ {/*rules-of-hooks*/} -Hook์€ JavaScript ํ•จ์ˆ˜๋กœ ์ •์˜๋˜์ง€๋งŒ ํ˜ธ์ถœ ์œ„์น˜์— ์ œ์•ฝ์ด ์žˆ๋Š” ํŠน๋ณ„ํ•œ ์œ ํ˜•์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ UI ๋กœ์ง์ž…๋‹ˆ๋‹ค. Hook์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” [Hook์˜ ๊ทœ์น™](/reference/rules/rules-of-hooks) ์„ ๋”ฐ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. +Hook์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜๋กœ ์ •์˜ํ•˜์ง€๋งŒ, ํ˜ธ์ถœ ์œ„์น˜์— ์ œ์•ฝ์ด ์žˆ๋Š” ํŠน๋ณ„ํ•œ ์œ ํ˜•์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ UI ๋กœ์ง์ž…๋‹ˆ๋‹ค. Hook์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” [Hook์˜ ๊ทœ์น™](/reference/rules/rules-of-hooks)์„ ๋”ฐ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. * [Hook์„ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ๋งŒ ํ˜ธ์ถœํ•˜์„ธ์š”](/reference/rules/rules-of-hooks#only-call-hooks-at-the-top-level) โ€“ Hook์„ ๋ฐ˜๋ณต๋ฌธ, ์กฐ๊ฑด๋ฌธ, ๋˜๋Š” ์ค‘์ฒฉ๋œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”. ๋Œ€์‹  Hook์„ ํ•ญ์ƒ React ํ•จ์ˆ˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ ํ˜ธ์ถœํ•˜๊ณ , early return ์ด์ „์— ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -* [Hook์„ React ํ•จ์ˆ˜์—์„œ๋งŒ ํ˜ธ์ถœํ•˜์„ธ์š” ](/reference/rules/rules-of-hooks#only-call-hooks-from-react-functions) โ€“ ์ผ๋ฐ˜ JavaScript ํ•จ์ˆ˜์—์„œ Hook์„ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”. +* [Hook์„ React ํ•จ์ˆ˜์—์„œ๋งŒ ํ˜ธ์ถœํ•˜์„ธ์š” ](/reference/rules/rules-of-hooks#only-call-hooks-from-react-functions) โ€“ ์ผ๋ฐ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜์—์„œ Hook์„ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”. From 8310e7dd0f44962b1f467df3e98d76cd9464cd5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 17:20:57 +0900 Subject: [PATCH 0385/1059] docs: update `components-and-hooks-must-be-pure` --- .../components-and-hooks-must-be-pure.md | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) 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 cc1bf4fe7..9044d4f5a 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 @@ -16,19 +16,19 @@ title: ์ปดํฌ๋„ŒํŠธ์™€ Hook์€ ์ˆœ์ˆ˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค React๋ฅผ ๋งŒ๋“œ๋Š” ํ•ต์‹ฌ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜๋Š” _์ˆœ์ˆ˜์„ฑ_ ์ž…๋‹ˆ๋‹ค. ์ˆœ์ˆ˜ํ•œ ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -* **๋ฉฑ๋“ฑ์„ฑ** โ€“ ์ปดํฌ๋„ŒํŠธ์˜ props, state, context ํ˜น์€ Hook์˜ ์ธ์ˆ˜์— ๋Œ€ํ•œ ๋™์ผํ•œ ์ž…๋ ฅ์œผ๋กœ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค [ํ•ญ์ƒ ๊ฐ™์€ ๊ฒฐ๊ณผ](/learn/keeping-components-pure#purity-components-as-formulas)๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. -* **๋ Œ๋”๋ง ์‹œ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค** โ€“ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ์žˆ๋Š” ์ฝ”๋“œ๋Š” [**๋ Œ๋”๋ง๊ณผ ๋ณ„๋„๋กœ ์‹คํ–‰**](#how-does-react-run-your-code)๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด [์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ](/learn/responding-to-events)์—์„œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ UI์™€ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•˜์—ฌ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ [Effect](/reference/react/useEffect)์—์„œ๋Š” ๋ Œ๋”๋ง ํ›„์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. +* **๋ฉฑ๋“ฑ์„ฑ** โ€“ ์ปดํฌ๋„ŒํŠธ์˜ Props, State, Context ํ˜น์€ Hook์˜ ์ธ์ˆ˜์— ๋Œ€ํ•œ ๋™์ผํ•œ ์ž…๋ ฅ์œผ๋กœ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค [ํ•ญ์ƒ ๊ฐ™์€ ๊ฒฐ๊ณผ](/learn/keeping-components-pure#purity-components-as-formulas)๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. +* **๋ Œ๋”๋ง ์‹œ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค** โ€“ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ์žˆ๋Š” ์ฝ”๋“œ๋Š” [**๋ Œ๋”๋ง๊ณผ ๋ณ„๋„๋กœ ์‹คํ–‰**](#how-does-react-run-your-code)ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, [์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ](/learn/responding-to-events)๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ UI์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜์—ฌ UI๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒฝ์šฐ๋‚˜, ๋ Œ๋”๋ง ํ›„์— ์‹คํ–‰๋˜๋Š” [Effect](/reference/react/useEffect)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **์ง€์—ญ ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”** โ€“ ์ปดํฌ๋„ŒํŠธ์™€ Hook์€ ๋ Œ๋”๋ง ์‹œ [์ง€์—ญ์—์„œ ์ƒ์„ฑ๋˜์ง€ ์•Š์€ ๊ฐ’์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š์•„์•ผ](#mutation) ํ•ฉ๋‹ˆ๋‹ค. -๋ Œ๋”๋ง์ด ์ˆœ์ˆ˜ํ•˜๊ฒŒ ์œ ์ง€๋˜๋ฉด, React๋Š” ์–ด๋–ค ์—…๋ฐ์ดํŠธ๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋จผ์ € ๋ณด์ด๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ์ง€๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ Œ๋”๋ง์˜ ์ˆœ์ˆ˜์„ฑ ๋•๋ถ„์— ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ [๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ](#how-does-react-run-your-code) ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— React๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์€ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์„ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ๋‚˜์ค‘์— ํ•„์š”ํ•  ๋•Œ ๋‹ค์‹œ ๋Œ์•„์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ Œ๋”๋ง์„ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ์œ ์ง€ํ•˜๋ฉด, React๋Š” ์–ด๋–ค ์—…๋ฐ์ดํŠธ๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋จผ์ € ๋ณด์ด๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ์ง€๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋ Œ๋”๋ง์˜ ์ˆœ์ˆ˜์„ฑ ๋•๋ถ„์— ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ [๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ](#how-does-react-run-your-code) ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— React๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์€ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์„ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ณ  ๋‚˜์ค‘์— ํ•„์š”ํ•  ๋•Œ ๋‹ค์‹œ ๋Œ์•„์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์ฒด์ ์œผ๋กœ, ์ด๋Š” ๋ Œ๋”๋ง ๋กœ์ง์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์–ด React๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์พŒ์ ํ•œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ [๋ Œ๋”๋ง ์ค‘](#how-does-react-run-your-code)์— ์ „์—ญ ๋ณ€์ˆ˜ ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ปดํฌ๋„ŒํŠธ์— ์ถ”์ ๋˜์ง€ ์•Š์€ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, React๊ฐ€ ๋ Œ๋”๋ง ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•  ๋•Œ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ์›ํ•˜์ง€ ์•Š๋Š” ๋ฐฉ์‹์œผ๋กœ ํŠธ๋ฆฌ๊ฑฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ข…์ข… ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฒ„๊ทธ๋กœ ์ด์–ด์ ธ ์‚ฌ์šฉ์ž์˜ ์•ฑ ๊ฒฝํ—˜์„ ์ €ํ•˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. [์ปดํฌ๋„ŒํŠธ๋ฅผ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ](/learn/keeping-components-pure#side-effects-unintended-consequences)์—์„œ ์ด ์˜ˆ์‹œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. #### React๊ฐ€ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹ {/*how-does-react-run-your-code*/} -React๋Š” ์„ ์–ธ์ ์ž…๋‹ˆ๋‹ค. React์— _๋ฌด์—‡์„_ ๋ Œ๋”๋งํ• ์ง€ ๋งํ•ด์ฃผ๋ฉด, React๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ _์–ด๋–ป๊ฒŒ_ ์ตœ์ ์œผ๋กœ ํ‘œ์‹œํ• ์ง€ ์•Œ์•„๋ƒ…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด React๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นฉ๋‹ˆ๋‹ค. React๋ฅผ ์ž˜ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ด ๋ชจ๋“  ๋‹จ๊ณ„๋ฅผ ์•Œ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋†’์€ ์ˆ˜์ค€์—์„œ _๋ Œ๋”๋ง_ ์ค‘์— ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ์™€ ๊ทธ ์™ธ๋ถ€์—์„œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. +React๋Š” ์„ ์–ธ์ ์ž…๋‹ˆ๋‹ค. React์— _๋ฌด์—‡์„_ ๋ Œ๋”๋งํ• ์ง€ ๋งํ•ด์ฃผ๋ฉด, React๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ _์–ด๋–ป๊ฒŒ_ ์ตœ์ ์œผ๋กœ ํ‘œ์‹œํ• ์ง€ ์•Œ์•„๋ƒ…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด React๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นฉ๋‹ˆ๋‹ค. React๋ฅผ ์ž˜ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ด ๋ชจ๋“  ๋‹จ๊ณ„๋ฅผ ์•Œ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ณ ์ˆ˜์ค€์—์„œ _๋ Œ๋”๋ง_ ์ค‘์— ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ์™€ ๊ทธ ์™ธ๋ถ€์—์„œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. -_๋ Œ๋”๋ง_ ์€ UI์˜ ๋‹ค์Œ ๋ฒ„์ „์ด ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ํ›„์— [Effect](/reference/react/useEffect)๊ฐ€ _flushed_ ๋ฉ๋‹ˆ๋‹ค(๋” ์ด์ƒ ๋‚จ์•„ ์žˆ์ง€ ์•Š์„ ๋•Œ๊นŒ์ง€ ์‹คํ–‰๋จ). ๊ทธ๋ฆฌ๊ณ  Effect๊ฐ€ ๋ ˆ์ด์•„์›ƒ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒฝ์šฐ ๊ณ„์‚ฐ์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ์ƒˆ๋กœ์šด ๊ณ„์‚ฐ์„ ์ด์ „ UI ๋ฒ„์ „์„ ๋งŒ๋“œ๋Š” ๋ฐ ์‚ฌ์šฉ๋œ ๊ณ„์‚ฐ๊ณผ ๋น„๊ตํ•œ ๋‹ค์Œ, ์ตœ์‹  ๋ฒ„์ „๊ณผ ์ผ์น˜์‹œํ‚ค๊ธฐ ์œ„ํ•ด [DOM](https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model)(์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ๋ณด๋Š” ๊ฒƒ)์— ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ๋ณ€๊ฒฝ๋งŒ์„ _์ปค๋ฐ‹_ ํ•ฉ๋‹ˆ๋‹ค. +<em>๋ Œ๋”๋ง</em>์€ UI์˜ ๋‹ค์Œ ๋ฒ„์ „์ด ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ํ›„์— [Effect](/reference/react/useEffect)๊ฐ€ _flushed_ ๋ฉ๋‹ˆ๋‹ค. (๋” ์ด์ƒ ๋‚จ์•„ ์žˆ์ง€ ์•Š์„ ๋•Œ๊นŒ์ง€ ์‹คํ–‰๋จ.) ๊ทธ๋ฆฌ๊ณ  Effect๊ฐ€ ๋ ˆ์ด์•„์›ƒ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒฝ์šฐ, ๊ณ„์‚ฐ์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ์ƒˆ๋กœ์šด ๊ณ„์‚ฐ์„ ์ด์ „ UI ๋ฒ„์ „์„ ๋งŒ๋“œ๋Š” ๋ฐ ์‚ฌ์šฉ๋œ ๊ณ„์‚ฐ๊ณผ ๋น„๊ตํ•œ ๋‹ค์Œ, ์ตœ์‹  ๋ฒ„์ „๊ณผ ์ผ์น˜์‹œํ‚ค๊ธฐ ์œ„ํ•ด [DOM](https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model)(์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ๋ณด๋Š” ๊ฒƒ)์— ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ๋ณ€๊ฒฝ๋งŒ์„ _์ปค๋ฐ‹_ ํ•ฉ๋‹ˆ๋‹ค. <DeepDive> @@ -38,7 +38,7 @@ _๋ Œ๋”๋ง_ ์€ UI์˜ ๋‹ค์Œ ๋ฒ„์ „์ด ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์„ ```js {2} function Dropdown() { - const selectedItems = new Set(); // ๋ Œ๋”๋ง ์ค‘์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค + const selectedItems = new Set(); // ๋ Œ๋”๋ง ์ค‘์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. // ... } ``` @@ -49,7 +49,7 @@ function Dropdown() { function Dropdown() { const selectedItems = new Set(); const onSelect = (item) => { - // ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์•ˆ์— ์žˆ์œผ๋ฏ€๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํŠธ๋ฆฌ๊ฑฐํ•  ๋•Œ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค + // ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์•ˆ์— ์žˆ์œผ๋ฏ€๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํŠธ๋ฆฌ๊ฑฐํ•  ๋•Œ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. selectedItems.add(item); } } @@ -59,7 +59,7 @@ function Dropdown() { function Dropdown() { const selectedItems = new Set(); useEffect(() => { - // Effect ์•ˆ์— ์žˆ์œผ๋ฏ€๋กœ ๋ Œ๋”๋ง ํ›„์—๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค + // Effect ์•ˆ์— ์žˆ์œผ๋ฏ€๋กœ ๋ Œ๋”๋ง ํ›„์—๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. logForAnalytics(selectedItems); }, [selectedItems]); } @@ -70,9 +70,9 @@ function Dropdown() { ## ์ปดํฌ๋„ŒํŠธ์™€ Hook์€ ๋ฉฑ๋“ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค {/*components-and-hooks-must-be-idempotent*/} -์ปดํฌ๋„ŒํŠธ๋Š” ํ•ญ์ƒ props, state, context์™€ ๊ฐ™์€ ์ž…๋ ฅ์— ๋Œ€ํ•ด ๋™์ผํ•œ ์ถœ๋ ฅ์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ _๋ฉฑ๋“ฑ์„ฑ_ ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. [๋ฉฑ๋“ฑ์„ฑ](https://ko.wikipedia.org/wiki/%EB%A9%B1%EB%93%B1%EB%B2%95%EC%B9%99)์€ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ์šฉ์–ด์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋™์ผํ•œ ์ž…๋ ฅ์œผ๋กœ ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค [ํ•ญ์ƒ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š” ๊ฒƒ](learn/keeping-components-pure)์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. +์ปดํฌ๋„ŒํŠธ๋Š” ํ•ญ์ƒ Props, State, Context์™€ ๊ฐ™์€ ์ž…๋ ฅ์— ๋Œ€ํ•ด ๋™์ผํ•œ ์ถœ๋ ฅ์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ <em>๋ฉฑ๋“ฑ์„ฑ</em>์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. [๋ฉฑ๋“ฑ์„ฑ](https://ko.wikipedia.org/wiki/%EB%A9%B1%EB%93%B1%EB%B2%95%EC%B9%99)์€ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ์šฉ์–ด์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋™์ผํ•œ ์ž…๋ ฅ์œผ๋กœ ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค [ํ•ญ์ƒ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š” ๊ฒƒ](learn/keeping-components-pure)์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -์ด๋Š” _๋ชจ๋“ _ ์ฝ”๋“œ๊ฐ€ [๋ Œ๋”๋ง ์ค‘](#how-does-react-run-your-code)์—๋„ ๋ฉฑ๋“ฑ์„ฑ์„ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ด ์ฝ”๋“œ ๋ผ์ธ์€ ๋ฉฑ๋“ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(๋”ฐ๋ผ์„œ ์ปดํฌ๋„ŒํŠธ๋„ ๋ฉฑ๋“ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค). +์ด๋Š” _๋ชจ๋“ _ ์ฝ”๋“œ๊ฐ€ [๋ Œ๋”๋ง ์ค‘](#how-does-react-run-your-code)์—๋„ ๋ฉฑ๋“ฑ์„ฑ์„ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ์ฝ”๋“œ ๋ผ์ธ์€ ๋ฉฑ๋“ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (๋”ฐ๋ผ์„œ ์ปดํฌ๋„ŒํŠธ๋„ ๋ฉฑ๋“ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.) ```js {2} function Clock() { @@ -83,7 +83,7 @@ function Clock() { `new Date()` ํ•จ์ˆ˜๋Š” ํ•ญ์ƒ ํ˜„์žฌ ๋‚ ์งœ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๊ฒฐ๊ณผ๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉฑ๋“ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์œ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋ฉด ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋Š” ์‹œ๊ฐ„์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋œ ์‹œ๊ฐ„์— ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ `Math.random()`๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜๋„ ๋ฉฑ๋“ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž…๋ ฅ์ด ๋™์ผํ•ด๋„ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -์ด๋Š” `new Date()`์™€ ๊ฐ™์€ ๋น„๋ฉฑ๋“ฑ ํ•จ์ˆ˜๋ฅผ _์ „ํ˜€_ ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‹จ์ง€ ์ด๋ฅผ [๋ Œ๋”๋ง ์ค‘](#how-does-react-run-your-code)์— ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ [Effect](/reference/react/useEffect)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์‹  ๋‚ ์งœ๋ฅผ ์ด ์ปดํฌ๋„ŒํŠธ์— _๋™๊ธฐํ™”_ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋Š” `new Date()`์™€ ๊ฐ™์€ ๋น„๋ฉฑ๋“ฑ ํ•จ์ˆ˜๋ฅผ _์ „ํ˜€_ ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‹จ์ง€ ์ด๋ฅผ [๋ Œ๋”๋ง ์ค‘](#how-does-react-run-your-code)์— ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ [Effect](/reference/react/useEffect)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์‹  ๋‚ ์งœ๋ฅผ ์ปดํฌ๋„ŒํŠธ์— _๋™๊ธฐํ™”_ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <Sandpack> @@ -91,7 +91,7 @@ function Clock() { import { useState, useEffect } from 'react'; function useTime() { - // 1. ํ˜„์žฌ ๋‚ ์งœ์˜ state๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค. `useState`๋Š” ์ดˆ๊ธฐ state๋กœ ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. + // 1. ํ˜„์žฌ ๋‚ ์งœ์˜ State๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค. `useState`๋Š” ์ดˆ๊ธฐ State๋กœ ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. // ์ด ํ•จ์ˆ˜๋Š” Hook์ด ํ˜ธ์ถœ๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋ฏ€๋กœ, Hook์ด ํ˜ธ์ถœ๋˜๋Š” ์‹œ์ ์˜ ํ˜„์žฌ ๋‚ ์งœ๊ฐ€ // ์ฒ˜์Œ์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. const [time, setTime] = useState(() => new Date()); @@ -99,9 +99,9 @@ function useTime() { useEffect(() => { // 2. `setInterval`์„ ์‚ฌ์šฉํ•˜์—ฌ ํ˜„์žฌ ๋‚ ์งœ๋ฅผ ๋งค์ดˆ๋งˆ๋‹ค ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. const id = setInterval(() => { - setTime(new Date()); // โœ… Good: ๋ Œ๋”๋ง์—์„œ ๋น„๋ฉฑ๋“ฑ ์ฝ”๋“œ๊ฐ€ ๋” ์ด์ƒ ์‹คํ–‰๋˜์ง€ ์•Š์Œ + setTime(new Date()); // โœ… Good: ๋ Œ๋”๋ง์—์„œ ๋น„๋ฉฑ๋“ฑ ์ฝ”๋“œ๊ฐ€ ๋” ์ด์ƒ ์‹คํ–‰๋˜์ง€ ์•Š์Œ. }, 1000); - // 3. `setInterval` ํƒ€์ด๋จธ๊ฐ€ ๋ˆ„์ˆ˜๋˜์ง€ ์•Š๋„๋ก cleanup ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + // 3. `setInterval` ํƒ€์ด๋จธ๊ฐ€ ๋ˆ„์ˆ˜๋˜์ง€ ์•Š๋„๋ก Cleanup ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. return () => clearInterval(id); }, []); @@ -124,29 +124,29 @@ React์™€ ์™ธ๋ถ€ ์ƒํƒœ๋ฅผ ๋™๊ธฐํ™”ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋ฉด, ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘ ## ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” ๋ Œ๋”๋ง ์™ธ๋ถ€์—์„œ ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค {/*side-effects-must-run-outside-of-render*/} -[์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ](/learn/keeping-components-pure#side-effects-unintended-consequences)๋Š” React๊ฐ€ ์ตœ์ƒ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— [๋ Œ๋”๋ง ์ค‘์—](#how-does-react-run-your-code) ์‹คํ–‰๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. +[์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ](/learn/keeping-components-pure#side-effects-unintended-consequences)๋Š” [๋ Œ๋”๋ง ์ค‘์—](#how-does-react-run-your-code) ์‹คํ–‰๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š”, React๊ฐ€ ์ตœ์ƒ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค! <Note> -์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” Effects๋ณด๋‹ค ๋” ๋„“์€ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. Effects๋Š” ํŠนํžˆ `useEffect` ์•ˆ์— ๊ฐ์‹ธ์ง„ ์ฝ”๋“œ๋ฅผ ์ง€์นญํ•˜๋Š” ๋ฐ˜๋ฉด, ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” ํ˜ธ์ถœ์ž์—๊ฒŒ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„ ์–ด๋–ค ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ํšจ๊ณผ๋ฅผ ๊ฐ€์ง„ ์ฝ”๋“œ๋ฅผ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. +์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” Effect๋ณด๋‹ค ๋” ๋„“์€ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. Effect๋Š” ํŠนํžˆ `useEffect` ์•ˆ์— ๊ฐ์‹ธ์ง„ ์ฝ”๋“œ๋ฅผ ์ง€์นญํ•˜๋Š” ๋ฐ˜๋ฉด, ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” ํ˜ธ์ถœ์ž์—๊ฒŒ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ธฐ๋ณธ ๊ฒฐ๊ณผ ์™ธ์—๋„ ์–ด๋–ค ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ์ฝ”๋“œ๋ฅผ ์ง€์นญํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์šฉ์–ด์ž…๋‹ˆ๋‹ค. -์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” ์ „ํ˜•์ ์œผ๋กœ [์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ](/learn/responding-to-events)๋‚˜ Effects ์•ˆ์—์„œ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ Œ๋”๋ง ์ค‘์—๋Š” ์ ˆ๋Œ€๋กœ ์ž‘์„ฑ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. +์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ [์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ](/learn/responding-to-events)๋‚˜ Effect ์•ˆ์—์„œ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ Œ๋”๋ง ์ค‘์—๋Š” ์ ˆ๋Œ€๋กœ ์ž‘์„ฑํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. </Note> -๋ Œ๋”๋ง์€ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ์œ ์ง€๋˜์–ด์•ผ ํ•˜์ง€๋งŒ, ํ™”๋ฉด์— ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์•ฑ์ด ํฅ๋ฏธ๋กœ์šด ๋™์ž‘์„ ํ•˜๋ ค๋ฉด ์–ด๋А ์‹œ์ ์—์„œ๋Š” ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค! ์ด ๊ทœ์น™์˜ ํ•ต์‹ฌ์€ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ [๋ Œ๋”๋ง ์ค‘์—](#how-does-react-run-your-code) ์‹คํ–‰๋˜์–ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค, React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ [์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ](learn/responding-to-events)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด ์ฝ”๋“œ๊ฐ€ ๋ Œ๋”๋ง ์ค‘์— ์‹คํ–‰๋  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์„ React์— ๋ช…์‹œ์ ์œผ๋กœ ์•Œ๋ ค์ฃผ์–ด ๋ Œ๋”๋ง์„ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์˜ต์…˜์„ ๋‹ค ์‹œ๋„ํ•ด ๋ณด๊ณ  ๋‚˜์„œ๋„ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, ๊ทธ๋ฆฌ๊ณ  ์ •๋ง ์ตœํ›„์˜ ์ˆ˜๋‹จ์œผ๋กœ๋งŒ, `useEffect`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +๋ Œ๋”๋ง์€ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ์œ ์ง€๋˜์–ด์•ผ ํ•˜์ง€๋งŒ, ํ™”๋ฉด์— ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์•ฑ์ด ํฅ๋ฏธ๋กœ์šด ๋™์ž‘์„ ํ•˜๋ ค๋ฉด ์–ด๋А ์‹œ์ ์—์„œ๋Š” ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค! ์ด ๊ทœ์น™์˜ ํ•ต์‹ฌ์€ React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ [๋ Œ๋”๋ง ์ค‘์—](#how-does-react-run-your-code) ์‹คํ–‰๋˜์–ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ [์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ](learn/responding-to-events)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด ์ฝ”๋“œ๊ฐ€ ๋ Œ๋”๋ง ์ค‘์— ์‹คํ–‰๋  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์„ React์— ๋ช…์‹œ์ ์œผ๋กœ ์•Œ๋ ค์ฃผ์–ด ๋ Œ๋”๋ง์„ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์˜ต์…˜์„ ๋‹ค ์‹œ๋„ํ•ด ๋ณด๊ณ  ๋‚˜์„œ๋„ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, ์ •๋ง ์ตœํ›„์˜ ์ˆ˜๋‹จ์œผ๋กœ `useEffect`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ### ๋ณ€๊ฒฝ์ด ํ—ˆ์šฉ๋˜๋Š” ๊ฒฝ์šฐ {/*mutation*/} #### ์ง€์—ญ ๋ณ€๊ฒฝ {/*local-mutation*/} -์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ์˜ ์ผ๋ฐ˜์ ์ธ ์˜ˆ๋กœ ๋ณ€๊ฒฝ(mutation)์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ณ€๊ฒฝ์€ [์›์‹œ ๊ฐ’](https://developer.mozilla.org/ko/docs/Glossary/Primitive)์ด ์•„๋‹Œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ”ํžˆ ๋ณ€๊ฒฝ์€ React์—์„œ ๊ถŒ์žฅํ•˜์ง€ ์•Š์ง€๋งŒ, _์ง€์—ญ_ ๋ณ€๊ฒฝ์€ ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ์˜ ์ผ๋ฐ˜์ ์ธ ์˜ˆ๋กœ ๋ณ€๊ฒฝ<sup>Mutation</sup>์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ณ€๊ฒฝ์€ [์›์‹œ ๊ฐ’](https://developer.mozilla.org/ko/docs/Glossary/Primitive)์ด ์•„๋‹Œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ”ํžˆ React์—์„œ๋Š” ๋ณ€๊ฒฝ์„ ๊ถŒ์žฅํ•˜์ง€ ์•Š์ง€๋งŒ, _์ง€์—ญ_ ๋ณ€๊ฒฝ์€ ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```js {2,7} function FriendList({ friends }) { - const items = []; // โœ… Good: ์ง€์—ญ ๋ณ€์ˆ˜๋กœ ์ƒ์„ฑ๋จ + const items = []; // โœ… Good: ์ง€์—ญ ๋ณ€์ˆ˜๋กœ ์ƒ์„ฑ๋จ. for (let i = 0; i < friends.length; i++) { const friend = friends[i]; items.push( <Friend key={friend.id} friend={friend} /> - ); // โœ… Good: ์ง€์—ญ ๋ณ€๊ฒฝ์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค + ); // โœ… Good: ์ง€์—ญ ๋ณ€๊ฒฝ์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. } return <section>{items}</section>; } @@ -154,18 +154,18 @@ function FriendList({ friends }) { ์ง€์—ญ ๋ณ€๊ฒฝ์„ ํ”ผํ•˜๊ณ ์ž ์ฝ”๋“œ๋ฅผ ๋น„ํ‹€ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. [`Array.map`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map)์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์ง€์—ญ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•œ ๋‹ค์Œ [๋ Œ๋”๋ง ์ค‘](#how-does-react-run-your-code)์— ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -๋น„๋ก `items`๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ, ์ด ์ฝ”๋“œ๊ฐ€ _์ง€์—ญ์—์„œ๋งŒ_ ๋ณ€๊ฒฝํ•œ๋‹ค๋Š” ์ ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰ ์ด ๋ณ€๊ฒฝ์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋  ๋•Œ "๊ธฐ์–ต๋˜์ง€" ์•Š์Šต๋‹ˆ๋‹ค. `items`๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์กด์žฌํ•˜๋Š” ๋™์•ˆ์—๋งŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. `<FriendList />`๊ฐ€ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค `items`๋Š” ํ•ญ์ƒ _์žฌ์ƒ์„ฑ_ ๋˜๋ฏ€๋กœ, ์ปดํฌ๋„ŒํŠธ๋Š” ํ•ญ์ƒ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +๋น„๋ก `items`๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ, ์ด ์ฝ”๋“œ๋ฅผ _์ง€์—ญ์—์„œ๋งŒ_ ๋ณ€๊ฒฝํ•œ๋‹ค๋Š” ์ ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰ ์ด ๋ณ€๊ฒฝ์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋  ๋•Œ "๊ธฐ์–ต๋˜์ง€" ์•Š์Šต๋‹ˆ๋‹ค. `items`๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์กด์žฌํ•˜๋Š” ๋™์•ˆ์—๋งŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. `<FriendList />`๊ฐ€ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค `items`๋Š” ํ•ญ์ƒ _์žฌ์ƒ์„ฑ_ ๋˜๋ฏ€๋กœ, ์ปดํฌ๋„ŒํŠธ๋Š” ํ•ญ์ƒ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด `items`๊ฐ€ ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋˜๋ฉด ์ด์ „ ๊ฐ’์„ ์œ ์ง€ํ•˜๊ณ  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. ```js {1,7} -const items = []; // ๐Ÿ”ด Bad: ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋จ +const items = []; // ๐Ÿ”ด Bad: ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋จ. function FriendList({ friends }) { for (let i = 0; i < friends.length; i++) { const friend = friends[i]; items.push( <Friend key={friend.id} friend={friend} /> - ); // ๐Ÿ”ด Bad: ๋ Œ๋”๋ง ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค + ); // ๐Ÿ”ด Bad: ๋ Œ๋”๋ง ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. } return <section>{items}</section>; } @@ -186,7 +186,7 @@ function ExpenseForm() { #### DOM ๋ณ€๊ฒฝ {/*changing-the-dom*/} -์‚ฌ์šฉ์ž์—๊ฒŒ ์ง์ ‘์ ์œผ๋กœ ๋ณด์ด๋Š” ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” React ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ๋กœ์ง์—์„œ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰ ๋‹จ์ˆœํžˆ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ํ™”๋ฉด์— ๋ณ€ํ™”๋ฅผ ์ผ์œผ์ผœ์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. +์‚ฌ์šฉ์ž์—๊ฒŒ ์ง์ ‘์ ์œผ๋กœ ๋ณด์ด๋Š” ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋Š” React ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ๋กœ์ง์—์„œ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋‹จ์ˆœํžˆ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ํ™”๋ฉด์— ๋ณ€ํ™”๋ฅผ ์ผ์œผ์ผœ์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ```js {2} function ProductDetailPage({ product }) { @@ -202,42 +202,42 @@ function ProductDetailPage({ product }) { ## Props์™€ State๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค {/*props-and-state-are-immutable*/} -์ปดํฌ๋„ŒํŠธ์˜ props์™€ state๋Š” ๋ถˆ๋ณ€์˜ [์Šค๋ƒ…์ƒท](learn/state-as-a-snapshot)์ž…๋‹ˆ๋‹ค. ์ง์ ‘์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  ์ƒˆ๋กœ์šด props๋ฅผ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ `useState`์—์„œ ์ œ๊ณตํ•˜๋Š” setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. +์ปดํฌ๋„ŒํŠธ์˜ Props์™€ State๋Š” ๋ถˆ๋ณ€์˜ [์Šค๋ƒ…์ƒท](learn/state-as-a-snapshot)์ž…๋‹ˆ๋‹ค. ์ง์ ‘์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  ์ƒˆ๋กœ์šด Props๋ฅผ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ `useState`์—์„œ ์ œ๊ณตํ•˜๋Š” Setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. -props์™€ state ๊ฐ’์„ ๋ Œ๋”๋ง ํ›„์— ์—…๋ฐ์ดํŠธ๋˜๋Š” ์Šค๋ƒ…์ƒท์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ props๋‚˜ state ๋ณ€์ˆ˜๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด props๋ฅผ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ์ œ๊ณต๋œ setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์Œ ๋ฒˆ์— ๋ Œ๋”๋ง ๋  ๋•Œ state๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์–ด์•ผ ํ•จ์„ React์— ์•Œ๋ ค์ค๋‹ˆ๋‹ค. +Props์™€ State ๊ฐ’์„ ๋ Œ๋”๋ง ํ›„์— ์—…๋ฐ์ดํŠธ๋˜๋Š” ์Šค๋ƒ…์ƒท์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ Props๋‚˜ State ๋ณ€์ˆ˜๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด Props๋ฅผ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ์ œ๊ณต๋œ Setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์Œ ๋ฒˆ์— ๋ Œ๋”๋ง ๋  ๋•Œ State๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์–ด์•ผ ํ•จ์„ React์— ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ### Props๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š” {/*props*/} -props๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค. props๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ผ๊ด€์„ฑ ์—†๋Š” ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๋ฉฐ, ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ž‘๋™ํ•  ์ˆ˜๋„ ์žˆ๊ณ  ์•ˆ ํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋””๋ฒ„๊น…์ด ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +Props๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค. Props๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ผ๊ด€์„ฑ ์—†๋Š” ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•˜๊ฒŒ ๋˜๋ฉฐ, ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ž‘๋™ํ•  ์ˆ˜๋„ ์žˆ๊ณ  ์•ˆ ํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋””๋ฒ„๊น…์ด ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {2} function Post({ item }) { - item.url = new Url(item.url, base); // ๐Ÿ”ด Bad: ์ ˆ๋Œ€ props๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š” + item.url = new Url(item.url, base); // ๐Ÿ”ด Bad: ์ ˆ๋Œ€ Props๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. return <Link url={item.url}>{item.title}</Link>; } ``` ```js {2} function Post({ item }) { - const url = new Url(item.url, base); // โœ… Good: ๋Œ€์‹  ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“œ์„ธ์š” + const url = new Url(item.url, base); // โœ… Good: ๋Œ€์‹ , ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“œ์„ธ์š”. return <Link url={url}>{item.title}</Link>; } ``` ### State๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š” {/*state*/} -`useState`๋Š” state ๋ณ€์ˆ˜์™€ ๊ทธ state๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•œ setter๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +`useState`๋Š” State ๋ณ€์ˆ˜์™€ ๊ทธ State๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•œ Setter ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ```js const [stateVariable, setter] = useState(0); ``` -state ๋ณ€์ˆ˜๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜๋Š” ๋Œ€์‹ , `useState`์— ์˜ํ•ด ๋ฐ˜ํ™˜๋œ setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. state ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•„ ์‚ฌ์šฉ์ž๋Š” ์ด์ „ UI๋ฅผ ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด React์— state๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋ฉฐ UI๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌ๋ Œ๋”๋ง์„ ๋Œ€๊ธฐ์—ด์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค. +State ๋ณ€์ˆ˜๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜๋Š” ๋Œ€์‹ , `useState`์— ์˜ํ•ด ๋ฐ˜ํ™˜๋œ Setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€๊ฒฝํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. State ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•„ ์‚ฌ์šฉ์ž๋Š” ์ด์ „ UI๋ฅผ ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. Setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด React์— State๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋ฉฐ UI๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌ๋ Œ๋”๋ง์„ ๋Œ€๊ธฐ์—ด์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค. ```js {5} function Counter() { const [count, setCount] = useState(0); function handleClick() { - count = count + 1; // ๐Ÿ”ด Bad: ์ ˆ๋Œ€ state๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š” + count = count + 1; // ๐Ÿ”ด Bad: ์ ˆ๋Œ€ State๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. } return ( @@ -268,13 +268,13 @@ function Counter() { ## Hook์˜ ๋ฐ˜ํ™˜๊ฐ’๊ณผ ์ธ์ˆ˜๋Š” ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค {/*return-values-and-arguments-to-hooks-are-immutable*/} -๊ฐ’์ด Hook์— ์ „๋‹ฌ๋˜๋ฉด, ์ด๋ฅผ ์ˆ˜์ •ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. JSX์˜ props์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Hook์— ์ „๋‹ฌ๋œ ๊ฐ’์€ ๋ถˆ๋ณ€์ด ๋ฉ๋‹ˆ๋‹ค. +๊ฐ’์ด Hook์— ์ „๋‹ฌ๋˜๋ฉด, ์ด๋ฅผ ์ˆ˜์ •ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. JSX์˜ Props์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Hook์— ์ „๋‹ฌ๋œ ๊ฐ’์€ ๋ถˆ๋ณ€์ž…๋‹ˆ๋‹ค. ```js {4} function useIconStyle(icon) { const theme = useContext(ThemeContext); if (icon.enabled) { - icon.className = computeStyle(icon, theme); // ๐Ÿ”ด Bad: ์ ˆ๋Œ€ Hook ์ธ์ˆ˜๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š” + icon.className = computeStyle(icon, theme); // ๐Ÿ”ด Bad: ์ ˆ๋Œ€ Hook ์ธ์ˆ˜๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. } return icon; } @@ -283,7 +283,7 @@ function useIconStyle(icon) { ```js {3} function useIconStyle(icon) { const theme = useContext(ThemeContext); - const newIcon = { ...icon }; // โœ… Good: ๋Œ€์‹  ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“œ์„ธ์š” + const newIcon = { ...icon }; // โœ… Good: ๋Œ€์‹  ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“œ์„ธ์š”. if (icon.enabled) { newIcon.className = computeStyle(icon, theme); } @@ -310,15 +310,15 @@ function useIconStyle(icon) { Hook ์ธ์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์ปค์Šคํ…€ Hook์˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ์ž˜๋ชป๋˜๋ฏ€๋กœ, ์ด๋ฅผ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ```js {4} -style = useIconStyle(icon); // `style`์€ `icon`์„ ๊ธฐ์ค€์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋จ -icon.enabled = false; // Bad: ๐Ÿ”ด ์ ˆ๋Œ€ Hook ์ธ์ˆ˜๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š” -style = useIconStyle(icon); // ์ด์ „์— ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋œ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ˜ํ™˜๋จ +style = useIconStyle(icon); // `style`์€ `icon`์„ ๊ธฐ์ค€์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋จ. +icon.enabled = false; // Bad: ๐Ÿ”ด ์ ˆ๋Œ€ Hook ์ธ์ˆ˜๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋งˆ์„ธ์š”. +style = useIconStyle(icon); // ์ด์ „์— ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋œ ๊ฒฐ๊ณผ๊ฐ€ ๋ฐ˜ํ™˜๋จ. ``` ```js {4} -style = useIconStyle(icon); // `style`์€ `icon`์„ ๊ธฐ์ค€์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋จ -icon = { ...icon, enabled: false }; // Good: โœ… ๋Œ€์‹  ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“œ์„ธ์š” -style = useIconStyle(icon); // `style`์˜ ์ƒˆ๋กœ์šด ๊ฐ’์ด ๊ณ„์‚ฐ๋จ +style = useIconStyle(icon); // `style`์€ `icon`์„ ๊ธฐ์ค€์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋จ. +icon = { ...icon, enabled: false }; // Good: โœ… ๋Œ€์‹  ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“œ์„ธ์š”. +style = useIconStyle(icon); // `style`์˜ ์ƒˆ๋กœ์šด ๊ฐ’์ด ๊ณ„์‚ฐ๋จ. ``` ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Hook์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ ๊ฐ’์ด ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋˜์–ด ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. @@ -335,7 +335,7 @@ JSX๋ฅผ ํ‘œํ˜„์‹์—์„œ ์‚ฌ์šฉํ•  ๋•Œ, React๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์ด ๋ function Page({ colour }) { const styles = { colour, size: "large" }; const header = <Header styles={styles} />; - styles.size = "small"; // ๐Ÿ”ด Bad: styles๋Š” ์ด๋ฏธ ์œ„์˜ JSX์—์„œ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค + styles.size = "small"; // ๐Ÿ”ด Bad: `styles`๋Š” ์ด๋ฏธ ์œ„์˜ JSX์—์„œ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. const footer = <Footer styles={styles} />; return ( <> @@ -351,7 +351,7 @@ function Page({ colour }) { function Page({ colour }) { const headerStyles = { colour, size: "large" }; const header = <Header styles={headerStyles} />; - const footerStyles = { colour, size: "small" }; // โœ… Good: ์ƒˆ๋กœ์šด ๊ฐ’์„ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค + const footerStyles = { colour, size: "small" }; // โœ… Good: ์ƒˆ๋กœ์šด ๊ฐ’์„ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. const footer = <Footer styles={footerStyles} />; return ( <> From f39068a13ba3fa8cd16a1264257b4bec7b3a7c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 17:44:10 +0900 Subject: [PATCH 0386/1059] docs: update `react-calls-components-and-hooks` --- .../rules/react-calls-components-and-hooks.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/content/reference/rules/react-calls-components-and-hooks.md b/src/content/reference/rules/react-calls-components-and-hooks.md index 708cd91f8..58a8a8a51 100644 --- a/src/content/reference/rules/react-calls-components-and-hooks.md +++ b/src/content/reference/rules/react-calls-components-and-hooks.md @@ -13,17 +13,17 @@ React๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์ปดํฌ ## ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š” {/*never-call-component-functions-directly*/} ์ปดํฌ๋„ŒํŠธ๋Š” JSX์—์„œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ํ•จ์ˆ˜์ฒ˜๋Ÿผ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”. React๊ฐ€ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -React๋Š” [๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ](/reference/rules/components-and-hooks-must-be-pure#how-does-react-run-your-code) ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๊ฐ€ ์–ธ์ œ ํ˜ธ์ถœ๋ ์ง€ ๊ฒฐ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. React์—์„œ๋Š” ์ด๋ฅผ JSX๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. +React๋Š” [๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ](/reference/rules/components-and-hooks-must-be-pure#how-does-react-run-your-code) ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๊ฐ€ ์–ธ์ œ ํ˜ธ์ถœ๋ ์ง€ ๊ฒฐ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. React๋Š” ์ด๋ฅผ JSX๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ```js {2} function BlogPost() { - return <Layout><Article /></Layout>; // โœ… ์ปดํฌ๋„ŒํŠธ๋ฅผ JSX์—์„œ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค + return <Layout><Article /></Layout>; // โœ… Good: ์ปดํฌ๋„ŒํŠธ๋ฅผ JSX์—์„œ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. } ``` ```js {2} function BlogPost() { - return <Layout>{Article()}</Layout>; // ๐Ÿ”ด ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š” + return <Layout>{Article()}</Layout>; // ๐Ÿ”ด Bad: ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”. } ``` @@ -31,7 +31,7 @@ function BlogPost() { React๊ฐ€ ๋ Œ๋”๋ง์„ ์กฐ์ •ํ•˜๋„๋ก ํ•˜๋ฉด ์—ฌ๋Ÿฌ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. -* **์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•จ์ˆ˜ ์ด์ƒ์˜ ์—ญํ• ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.** React๋Š” Hook์„ ์‚ฌ์šฉํ•ด ์ปดํฌ๋„ŒํŠธ์— _๋กœ์ปฌ ์ƒํƒœ_ ์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์—ฌ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํŠธ๋ฆฌ ๋‚ด์—์„œ ๊ณ ์œ ํ•œ ์ •์ฒด์„ฑ์„ ๊ฐ–๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* **์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•จ์ˆ˜ ์ด์ƒ์˜ ์—ญํ• ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.** React๋Š” Hook์„ ์‚ฌ์šฉํ•ด ์ปดํฌ๋„ŒํŠธ์— <em>์ง€์—ญ State</em>์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์—ฌ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํŠธ๋ฆฌ ๋‚ด์—์„œ ๊ณ ์œ ํ•œ ์ •์ฒด์„ฑ์„ ๊ฐ–๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **์ปดํฌ๋„ŒํŠธ ํƒ€์ž…์ด ์žฌ์กฐ์ • ๊ณผ์ •์— ์ฐธ์—ฌํ•ฉ๋‹ˆ๋‹ค.** React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ํ•˜๋ฉด ํŠธ๋ฆฌ์˜ ๊ฐœ๋…์  ๊ตฌ์กฐ์— ๋Œ€ํ•ด ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `<Feed>`์—์„œ `<Profile>` ํŽ˜์ด์ง€๋กœ ์ „ํ™˜๋  ๋•Œ React๋Š” ์ด๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. * **React๊ฐ€ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.** ์˜ˆ๋ฅผ ๋“ค์–ด React๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์‚ฌ์ด์— ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ผ๋ถ€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์—ฌ, ํฐ ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์ด ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **๋” ๋‚˜์€ ๋””๋ฒ„๊น… ๊ฒฝํ—˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.** ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ผ๊ธ‰ ๊ฐ์ฒด๋กœ ์ทจ๊ธ‰๋˜๋ฉด, ๊ฐœ๋ฐœ ์ค‘์— ๋ถ„์„ํ•  ์ˆ˜ ์žˆ๋Š” ํ’๋ถ€ํ•œ ๊ฐœ๋ฐœ ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -39,11 +39,11 @@ React๊ฐ€ ๋ Œ๋”๋ง์„ ์กฐ์ •ํ•˜๋„๋ก ํ•˜๋ฉด ์—ฌ๋Ÿฌ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. --- -## Hook์„ ์ผ๋ฐ˜ ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•˜์ง€ ๋งˆ์„ธ์š” {/*never-pass-around-hooks-as-regular-values*/} +## Hook์„ ์ผ๋ฐ˜ ๊ฐ’์ฒ˜๋Ÿผ ์ „๋‹ฌํ•˜์ง€ ๋งˆ์„ธ์š” {/*never-pass-around-hooks-as-regular-values*/} Hook์€ ์ปดํฌ๋„ŒํŠธ๋‚˜ Hook ๋‚ด๋ถ€์—์„œ๋งŒ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Hook์„ ์ผ๋ฐ˜ ๊ฐ’์ฒ˜๋Ÿผ ์ „๋‹ฌํ•˜์ง€ ๋งˆ์„ธ์š”. -Hook์€ ์ปดํฌ๋„ŒํŠธ์— React ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. Hook์€ ํ•ญ์ƒ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•˜๋ฉฐ ์ผ๋ฐ˜ ๊ฐ’์ฒ˜๋Ÿผ ์ „๋‹ฌํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. Hook์„ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœํ•ด์•ผ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” _๋กœ์ปฌ ์ถ”๋ก _ ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. +Hook์€ ์ปดํฌ๋„ŒํŠธ์— React ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. Hook์€ ํ•ญ์ƒ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•˜๋ฉฐ ์ผ๋ฐ˜ ๊ฐ’์ฒ˜๋Ÿผ ์ „๋‹ฌํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. Hook์„ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœํ•ด์•ผ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” _์ง€์—ญ ์ถ”๋ก _ ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ทœ์น™์„ ์–ด๊ธฐ๋ฉด React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. @@ -53,7 +53,7 @@ Hook์€ ๊ฐ€๋Šฅํ•œ ํ•œ "์ •์ "์œผ๋กœ ์œ ์ง€๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” Hook์„ ```js {2} function ChatInput() { - const useDataWithLogging = withLogging(useData); // ๐Ÿ”ด ๊ณ ์ฐจ Hook์„ ์ž‘์„ฑํ•˜์ง€ ๋งˆ์„ธ์š” + const useDataWithLogging = withLogging(useData); // ๐Ÿ”ด Bad: ๊ณ ์ฐจ Hook์„ ์ž‘์„ฑํ•˜์ง€ ๋งˆ์„ธ์š”. const data = useDataWithLogging(); } ``` @@ -62,7 +62,7 @@ Hook์€ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•ด์•ผ ํ•˜๋ฉฐ ์ˆ˜์ •๋˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. Hook์„ ```js {2,6} function ChatInput() { - const data = useDataWithLogging(); // โœ… Hook์„ ์ƒˆ๋กœ ์ž‘์„ฑํ•˜์„ธ์š” + const data = useDataWithLogging(); // โœ… Good: Hook์„ ์ƒˆ๋กœ ์ž‘์„ฑํ•˜์„ธ์š”. } function useDataWithLogging() { @@ -76,7 +76,7 @@ Hook์€ ๋™์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์„œ๋„ ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Hook์„ ๊ฐ’์œผ ```js {2} function ChatInput() { - return <Button useData={useDataWithLogging} /> // ๐Ÿ”ด Hook์„ props๋กœ ์ „๋‹ฌํ•˜์ง€ ๋งˆ์„ธ์š” + return <Button useData={useDataWithLogging} /> // ๐Ÿ”ด Bad: Hook์„ Props๋กœ ์ „๋‹ฌํ•˜์ง€ ๋งˆ์„ธ์š”. } ``` @@ -88,7 +88,7 @@ function ChatInput() { } function Button() { - const data = useDataWithLogging(); // โœ… Hook์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜์„ธ์š” + const data = useDataWithLogging(); // โœ… Good: Hook์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜์„ธ์š”. } function useDataWithLogging() { @@ -96,4 +96,4 @@ function useDataWithLogging() { } ``` -์ด๋ ‡๊ฒŒ ํ•˜๋ฉด `<Button />` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ›จ์”ฌ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ณ  ๋””๋ฒ„๊น…ํ•˜๊ธฐ๋„ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. Hook์„ ๋™์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์•ฑ์˜ ๋ณต์žก์„ฑ์ด ํฌ๊ฒŒ ์ฆ๊ฐ€ํ•˜๊ณ , ๋กœ์ปฌ ์ถ”๋ก ์„ ๋ฐฉํ•ดํ•˜์—ฌ ์žฅ๊ธฐ์ ์œผ๋กœ ํŒ€์˜ ์ƒ์‚ฐ์„ฑ์„ ์ €ํ•˜์‹œํ‚ต๋‹ˆ๋‹ค. ๋˜ํ•œ Hook์„ ์กฐ๊ฑด๋ถ€๋กœ ํ˜ธ์ถœํ•˜๋ฉด ์•ˆ๋œ๋‹ค๋Š” [Hook์˜ ๊ทœ์น™](/reference/rules/rules-of-hooks)์„ ์‹ค์ˆ˜๋กœ ์–ด๊ธฐ๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ชจํ‚นํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ๋Œ€์‹  ์„œ๋ฒ„๋ฅผ ๋ชจํ‚นํ•˜์—ฌ ๋ฏธ๋ฆฌ ์ค€๋น„๋œ ๋ฐ์ดํ„ฐ์— ์‘๋‹ตํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๋‚ซ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์•ฑ์„ end-to-end ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค. +์ด๋ ‡๊ฒŒ ํ•˜๋ฉด `<Button />` ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ›จ์”ฌ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ณ  ๋””๋ฒ„๊น…ํ•˜๊ธฐ๋„ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. Hook์„ ๋™์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์•ฑ์˜ ๋ณต์žก์„ฑ์ด ํฌ๊ฒŒ ์ฆ๊ฐ€ํ•˜๊ณ , ์ง€์—ญ ์ถ”๋ก ์„ ๋ฐฉํ•ดํ•˜์—ฌ ์žฅ๊ธฐ์ ์œผ๋กœ ํŒ€์˜ ์ƒ์‚ฐ์„ฑ์„ ์ €ํ•˜์‹œํ‚ต๋‹ˆ๋‹ค. ๋˜ํ•œ Hook์„ ์กฐ๊ฑด๋ถ€๋กœ ํ˜ธ์ถœํ•˜๋ฉด ์•ˆ๋œ๋‹ค๋Š” [Hook์˜ ๊ทœ์น™](/reference/rules/rules-of-hooks)์„ ์‹ค์ˆ˜๋กœ ์–ด๊ธฐ๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ชจํ‚น<sup>Mocking</sup>ํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ๋Œ€์‹  ์„œ๋ฒ„๋ฅผ ๋ชจํ‚น<sup>Mocking</sup>ํ•˜์—ฌ ๋ฏธ๋ฆฌ ์ค€๋น„๋œ ๋ฐ์ดํ„ฐ์— ์‘๋‹ตํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๋‚ซ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์•ฑ์„ end-to-end ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค. From 0da537ecf0ed0a3913c6722fe76f6d4460f7cb32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 18:17:24 +0900 Subject: [PATCH 0387/1059] docs: update `rules-of-hooks.md` --- src/content/reference/rules/rules-of-hooks.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/content/reference/rules/rules-of-hooks.md b/src/content/reference/rules/rules-of-hooks.md index 26cf1ff14..9ae43ffa6 100644 --- a/src/content/reference/rules/rules-of-hooks.md +++ b/src/content/reference/rules/rules-of-hooks.md @@ -3,7 +3,7 @@ title: Hook์˜ ๊ทœ์น™ --- <Intro> -Hook์€ JavaScript ํ•จ์ˆ˜๋กœ ์ •์˜๋˜์ง€๋งŒ ํ˜ธ์ถœ ์œ„์น˜์— ์ œ์•ฝ์ด ์žˆ๋Š” ํŠน๋ณ„ํ•œ ์œ ํ˜•์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ UI ๋กœ์ง์ž…๋‹ˆ๋‹ค. +Hook์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜๋กœ ์ •์˜๋˜์ง€๋งŒ ํ˜ธ์ถœ ์œ„์น˜์— ์ œ์•ฝ์ด ์žˆ๋Š” ํŠน๋ณ„ํ•œ ์œ ํ˜•์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ UI ๋กœ์ง์ž…๋‹ˆ๋‹ค. </Intro> <InlineToc /> @@ -12,7 +12,7 @@ Hook์€ JavaScript ํ•จ์ˆ˜๋กœ ์ •์˜๋˜์ง€๋งŒ ํ˜ธ์ถœ ์œ„์น˜์— ์ œ์•ฝ์ด ์žˆ๋Š” ## Hook์„ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ๋งŒ ํ˜ธ์ถœํ•˜์„ธ์š” {/*only-call-hooks-at-the-top-level*/} -React์—์„œ๋Š” `use`๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ [*Hook*](/reference/react) ์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. +React์—์„œ๋Š” `use`๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ [*Hook*](/reference/react)์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. **Hook์„ ๋ฐ˜๋ณต๋ฌธ, ์กฐ๊ฑด๋ฌธ, ์ค‘์ฒฉ ํ•จ์ˆ˜, ๋˜๋Š” `try`/`catch`/`finally` ๋ธ”๋ก ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”.** ๋Œ€์‹  Hook์„ ํ•ญ์ƒ React ํ•จ์ˆ˜์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ ํ˜ธ์ถœํ•˜๊ณ , early return ์ด์ „์— ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Hook์€ React๊ฐ€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ์—๋งŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -21,13 +21,13 @@ React์—์„œ๋Š” `use`๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ [*Hook*](/reference/react) ์ด๋ผ ```js{2-3,8-9} function Counter() { - // โœ… ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค + // โœ… Good: ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. const [count, setCount] = useState(0); // ... } function useWindowWidth() { - // โœ… ์ปค์Šคํ…€ Hook์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค + // โœ… Good: ์ปค์Šคํ…€ Hook์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. const [width, setWidth] = useState(window.innerWidth); // ... } @@ -47,7 +47,7 @@ function useWindowWidth() { ```js{3-4,11-12,20-21} function Bad({ cond }) { if (cond) { - // ๐Ÿ”ด ์กฐ๊ฑด๋ถ€ ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ์™ธ๋ถ€๋กœ ์ด๋™ํ•˜์„ธ์š”!) + // ๐Ÿ”ด Bad: ์กฐ๊ฑด๋ถ€ ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ์™ธ๋ถ€๋กœ ์ด๋™ํ•˜์„ธ์š”!) const theme = useContext(ThemeContext); } // ... @@ -55,7 +55,7 @@ function Bad({ cond }) { function Bad() { for (let i = 0; i < 10; i++) { - // ๐Ÿ”ด ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ์™ธ๋ถ€๋กœ ์ด๋™ํ•˜์„ธ์š”!) + // ๐Ÿ”ด Bad: ๋ฐ˜๋ณต๋ฌธ ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ์™ธ๋ถ€๋กœ ์ด๋™ํ•˜์„ธ์š”!) const theme = useContext(ThemeContext); } // ... @@ -65,14 +65,14 @@ function Bad({ cond }) { if (cond) { return; } - // ๐Ÿ”ด ์กฐ๊ฑด๋ถ€ return๋ฌธ ์ดํ›„ (์ˆ˜์ •ํ•˜๋ ค๋ฉด return๋ฌธ ์ด์ „์œผ๋กœ ์ด๋™ํ•˜์„ธ์š”!) + // ๐Ÿ”ด Bad: ์กฐ๊ฑด๋ถ€ `return`๋ฌธ ์ดํ›„ (์ˆ˜์ •ํ•˜๋ ค๋ฉด `return`๋ฌธ ์ด์ „์œผ๋กœ ์ด๋™ํ•˜์„ธ์š”!) const theme = useContext(ThemeContext); // ... } function Bad() { function handleClick() { - // ๐Ÿ”ด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ์™ธ๋ถ€๋กœ ์ด๋™ํ•˜์„ธ์š”!) + // ๐Ÿ”ด Bad: ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ์™ธ๋ถ€๋กœ ์ด๋™ํ•˜์„ธ์š”!) const theme = useContext(ThemeContext); } // ... @@ -80,7 +80,7 @@ function Bad() { function Bad() { const style = useMemo(() => { - // ๐Ÿ”ด useMemo ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ์™ธ๋ถ€๋กœ ์ด๋™ํ•˜์„ธ์š”!) + // ๐Ÿ”ด Bad: `useMemo` ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ์™ธ๋ถ€๋กœ ์ด๋™ํ•˜์„ธ์š”!) const theme = useContext(ThemeContext); return createStyle(theme); }); @@ -89,7 +89,7 @@ function Bad() { class Bad extends React.Component { render() { - // ๐Ÿ”ด ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ ๋Œ€์‹  ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”!) + // ๐Ÿ”ด Bad: ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ ๋Œ€์‹  ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”!) useEffect(() => {}) // ... } @@ -97,7 +97,7 @@ class Bad extends React.Component { function Bad() { try { - // ๐Ÿ”ด try/catch/finally ๋ธ”๋ก ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ์™ธ๋ถ€๋กœ ์ด๋™ํ•˜์„ธ์š”!) + // ๐Ÿ”ด Bad: `try`/`catch`/`finally` ๋ธ”๋ก ๋‚ด๋ถ€ (์ˆ˜์ •ํ•˜๋ ค๋ฉด ์™ธ๋ถ€๋กœ ์ด๋™ํ•˜์„ธ์š”!) const [x, setX] = useState(0); } catch { const [x, setX] = useState(1); @@ -109,7 +109,7 @@ function Bad() { <Note> -[์ปค์Šคํ…€ Hook](/learn/reusing-logic-with-custom-hooks)์€ ๋‹ค๋ฅธ Hook์„ *ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค* (๊ทธ๊ฒƒ์ด ์ปค์Šคํ…€ Hook์˜ ์ฃผ๋œ ๋ชฉ์ ์ž…๋‹ˆ๋‹ค). ์ปค์Šคํ…€ Hook๋„ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋˜๋Š” ๋™์•ˆ์—๋งŒ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +[์ปค์Šคํ…€ Hook](/learn/reusing-logic-with-custom-hooks)์€ ๋‹ค๋ฅธ Hook์„ *ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค*. (์ด๊ฒƒ์ด ๋ฐ”๋กœ ์ปค์Šคํ…€ Hook์˜ ์ฃผ๋œ ๋ชฉ์ ์ž…๋‹ˆ๋‹ค.) ์ปค์Šคํ…€ Hook๋„ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋˜๋Š” ๋™์•ˆ์—๋งŒ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. </Note> @@ -117,7 +117,7 @@ function Bad() { ## Hook์„ React ํ•จ์ˆ˜์—์„œ๋งŒ ํ˜ธ์ถœํ•˜์„ธ์š” {/*only-call-hooks-from-react-functions*/} -์ผ๋ฐ˜ JavaScript ํ•จ์ˆ˜์—์„œ Hook์„ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”. ๋Œ€์‹  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ผ๋ฐ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜์—์„œ Hook์„ ํ˜ธ์ถœํ•˜์ง€ ๋งˆ์„ธ์š”. ๋Œ€์‹  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. โœ… Hook์„ React ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ˜ธ์ถœํ•˜์„ธ์š”. โœ… Hook์„ [์ปค์Šคํ…€ Hook](/learn/reusing-logic-with-custom-hooks#extracting-your-own-custom-hook-from-a-component)์—์„œ ํ˜ธ์ถœํ•˜์„ธ์š”. From d7f4ab7665403a56670859d2bcb1d1064cd3f669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 18:30:41 +0900 Subject: [PATCH 0388/1059] docs: update `prerender.md` --- src/content/reference/react-dom/static/prerender.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/content/reference/react-dom/static/prerender.md b/src/content/reference/react-dom/static/prerender.md index 198faea64..bb726683f 100644 --- a/src/content/reference/react-dom/static/prerender.md +++ b/src/content/reference/react-dom/static/prerender.md @@ -73,7 +73,7 @@ On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to ### When should I use `prerender`? {/*when-to-use-prerender*/} -The static `prerender` API is used for static server-side generation (SSG). Unlike `renderToString`, `prerender` waits for all data to load before resolving. This makes it suitable for generating static HTML for a full page, including data that needs to be fetched using Suspense. To stream content as it loads, use a streaming server-side render (SSR) API like [renderToReadableStream](/reference/react-dom/server/renderToReadableStream). +The static `prerender` API is used for static server-side generation (SSG). Unlike `renderToString`, `prerender` waits for all data to load before resolving. This makes it suitable for generating static HTML for a full page, including data that needs to be fetched using Suspense. To stream content as it loads, use a streaming server-side render (SSR) API like [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream). </Note> @@ -83,7 +83,7 @@ The static `prerender` API is used for static server-side generation (SSG). Unli ### Rendering a React tree to a stream of static HTML {/*rendering-a-react-tree-to-a-stream-of-static-html*/} -Call `prerender` to render your React tree to static HTML into a [Readable Web Stream:](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream): +Call `prerender` to render your React tree to static HTML into a [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream): ```js [[1, 4, "<App />"], [2, 5, "['/main.js']"]] import { prerender } from 'react-dom/static'; @@ -229,7 +229,7 @@ async function renderToString() { const {prelude} = await prerender(<App />, { bootstrapScripts: ['/main.js'] }); - + const reader = stream.getReader(); let content = ''; while (true) { @@ -291,7 +291,6 @@ Suspense-enabled data fetching without the use of an opinionated framework is no ### My stream doesn't start until the entire app is rendered {/*my-stream-doesnt-start-until-the-entire-app-is-rendered*/} -The `prerender` response waits for the entire app to finish rendering, including waiting for all suspense boundaries to resolve, before resolving. It is designed for static site generation (SSG) ahead of time and does not support streaming more content as it loads. +The `prerender` response waits for the entire app to finish rendering, including waiting for all suspense boundaries to resolve, before resolving. It is designed for static site generation (SSG) ahead of time and does not support streaming more content as it loads. -To stream content as it loads, use a streaming server render API like [renderToReadableStream](/reference/react-dom/server/renderToReadableStream). - \ No newline at end of file +To stream content as it loads, use a streaming server render API like [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream). From 9ebd94c856ae01669c5442b3adfa46faf49449ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 18:39:03 +0900 Subject: [PATCH 0389/1059] docs: update `prerenderToNodeStream.md` --- .../react-dom/static/prerenderToNodeStream.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/content/reference/react-dom/static/prerenderToNodeStream.md b/src/content/reference/react-dom/static/prerenderToNodeStream.md index 039987497..a90ca86b3 100644 --- a/src/content/reference/react-dom/static/prerenderToNodeStream.md +++ b/src/content/reference/react-dom/static/prerenderToNodeStream.md @@ -4,7 +4,7 @@ title: prerenderToNodeStream <Intro> -`prerenderToNodeStream` renders a React tree to a static HTML string using a [Node.js Stream.](https://nodejs.org/api/stream.html). +`prerenderToNodeStream` renders a React tree to a static HTML string using a [Node.js Stream](https://nodejs.org/api/stream.html). ```js const {prelude} = await prerenderToNodeStream(reactNode, options?) @@ -63,7 +63,7 @@ On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to #### Returns {/*returns*/} `prerenderToNodeStream` returns a Promise: -- If rendering the is successful, the Promise will resolve to an object containing: +- If rendering is successful, the Promise will resolve to an object containing: - `prelude`: a [Node.js Stream.](https://nodejs.org/api/stream.html) of HTML. You can use this stream to send a response in chunks, or you can read the entire stream into a string. - If rendering fails, the Promise will be rejected. [Use this to output a fallback shell.](#recovering-from-errors-inside-the-shell) @@ -71,7 +71,7 @@ On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to ### When should I use `prerenderToNodeStream`? {/*when-to-use-prerender*/} -The static `prerenderToNodeStream` API is used for static server-side generation (SSG). Unlike `renderToString`, `prerenderToNodeStream` waits for all data to load before resolving. This makes it suitable for generating static HTML for a full page, including data that needs to be fetched using Suspense. To stream content as it loads, use a streaming server-side render (SSR) API like [renderToReadableStream](/reference/react-dom/server/renderToReadableStream). +The static `prerenderToNodeStream` API is used for static server-side generation (SSG). Unlike `renderToString`, `prerenderToNodeStream` waits for all data to load before resolving. This makes it suitable for generating static HTML for a full page, including data that needs to be fetched using Suspense. To stream content as it loads, use a streaming server-side render (SSR) API like [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream). </Note> @@ -81,7 +81,7 @@ The static `prerenderToNodeStream` API is used for static server-side generation ### Rendering a React tree to a stream of static HTML {/*rendering-a-react-tree-to-a-stream-of-static-html*/} -Call `prerenderToNodeStream` to render your React tree to static HTML into a [Node.js Stream.](https://nodejs.org/api/stream.html): +Call `prerenderToNodeStream` to render your React tree to static HTML into a [Node.js Stream](https://nodejs.org/api/stream.html): ```js [[1, 5, "<App />"], [2, 6, "['/main.js']"]] import { prerenderToNodeStream } from 'react-dom/static'; @@ -91,7 +91,7 @@ app.use('/', async (request, response) => { const { prelude } = await prerenderToNodeStream(<App />, { bootstrapScripts: ['/main.js'], }); - + response.setHeader('Content-Type', 'text/plain'); prelude.pipe(response); }); @@ -228,7 +228,7 @@ async function renderToString() { const {prelude} = await prerenderToNodeStream(<App />, { bootstrapScripts: ['/main.js'] }); - + return new Promise((resolve, reject) => { let data = ''; prelude.on('data', chunk => { @@ -291,5 +291,5 @@ Suspense-enabled data fetching without the use of an opinionated framework is no The `prerenderToNodeStream` response waits for the entire app to finish rendering, including waiting for all suspense boundaries to resolve, before resolving. It is designed for static site generation (SSG) ahead of time and does not support streaming more content as it loads. -To stream content as it loads, use a streaming server render API like [renderToPipeableStream](/reference/react-dom/server/renderToPipeableStream). - +To stream content as it loads, use a streaming server render API like [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream). + From f222c5d4e7f55de4c23a13b18afd28efdee099ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 18:51:24 +0900 Subject: [PATCH 0390/1059] docs: update `server/index.md` --- .../reference/react-dom/server/index.md | 37 +++---------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/src/content/reference/react-dom/server/index.md b/src/content/reference/react-dom/server/index.md index c294b6386..1ef5474df 100644 --- a/src/content/reference/react-dom/server/index.md +++ b/src/content/reference/react-dom/server/index.md @@ -4,11 +4,7 @@ title: Server React DOM APIs <Intro> -<<<<<<< HEAD -`react-dom/server` API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„œ๋ฒ„์—์„œ HTML๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด API๋Š” ์•ฑ์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์— ์žˆ๋Š” ์„œ๋ฒ„์—์„œ๋งŒ ์ดˆ๊ธฐ HTML์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. [ํ”„๋ ˆ์ž„์›Œํฌ](/learn/start-a-new-react-project#production-grade-react-frameworks)๊ฐ€ ๋Œ€์‹  ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ปดํฌ๋„ŒํŠธ๋Š” ์ด๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. -======= -The `react-dom/server` APIs let you server-side render React components to HTML. These APIs are only used on the server at the top level of your app to generate the initial HTML. A [framework](/learn/start-a-new-react-project#production-grade-react-frameworks) may call them for you. Most of your components don't need to import or use them. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +`react-dom/server` API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„œ๋ฒ„ ์ธก์—์„œ HTML๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด API๋Š” ์•ฑ์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์— ์žˆ๋Š” ์„œ๋ฒ„์—์„œ๋งŒ ์ดˆ๊ธฐ HTML์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. [ํ”„๋ ˆ์ž„์›Œํฌ](/learn/start-a-new-react-project#production-grade-react-frameworks)๊ฐ€ ๋Œ€์‹  ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ปดํฌ๋„ŒํŠธ๋Š” ์ด๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. </Intro> @@ -16,20 +12,15 @@ The `react-dom/server` APIs let you server-side render React components to HTML. ## Server APIs for Node.js Streams {/*server-apis-for-nodejs-streams*/} -๋‹ค์Œ ๋ฉ”์„œ๋“œ๋“ค์€ [Node.js Streams](https://nodejs.org/api/stream.html)์ด ์žˆ๋Š” ํ™˜๊ฒฝ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +๋‹ค์Œ ๋ฉ”์„œ๋“œ๋“ค์€ [Node.js Stream](https://nodejs.org/api/stream.html)์ด ์žˆ๋Š” ํ™˜๊ฒฝ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -<<<<<<< HEAD -* [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)์€ React ํŠธ๋ฆฌ๋ฅผ pipeable [Node.js Stream.](https://nodejs.org/api/stream.html)๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. -* [`renderToStaticNodeStream`](/reference/react-dom/server/renderToStaticNodeStream)์€ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” React ํŠธ๋ฆฌ๋ฅผ [Node.js Readable Stream.](https://nodejs.org/api/stream.html#readable-streams)๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. -======= -* [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream) renders a React tree to a pipeable [Node.js Stream.](https://nodejs.org/api/stream.html) ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +* [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)์€ React ํŠธ๋ฆฌ๋ฅผ [Pipeable Node.js Stream](https://nodejs.org/api/stream.html)์œผ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. --- ## Server APIs for Web Streams {/*server-apis-for-web-streams*/} -๋‹ค์Œ ๋ฉ”์„œ๋“œ๋“ค์€ ๋ธŒ๋ผ์šฐ์ €, Deno ๋ฐ ์ผ๋ถ€ ์ตœ์‹  ์—ฃ์ง€ ๋Ÿฐํƒ€์ž„์„ ํฌํ•จํ•˜๋Š” [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)์ด ์žˆ๋Š” ํ™˜๊ฒฝ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +๋‹ค์Œ ๋ฉ”์„œ๋“œ๋“ค์€ ๋ธŒ๋ผ์šฐ์ €, Deno ๋ฐ ์ผ๋ถ€ ์ตœ์‹  ์—ฃ์ง€ ๋Ÿฐํƒ€์ž„์„ ํฌํ•จํ•˜๋Š” [Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)์ด ์žˆ๋Š” ํ™˜๊ฒฝ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream)์€ React ํŠธ๋ฆฌ๋ฅผ [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)์œผ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. @@ -37,25 +28,9 @@ The `react-dom/server` APIs let you server-side render React components to HTML. ## Legacy Server APIs for non-streaming environments {/*legacy-server-apis-for-non-streaming-environments*/} -๋‹ค์Œ ๋ฉ”์„œ๋“œ๋“ค์€ ์ŠคํŠธ๋ฆผ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +๋‹ค์Œ ๋ฉ”์„œ๋“œ๋“ค์€ Stream์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * [`renderToString`](/reference/react-dom/server/renderToString)์€ React ํŠธ๋ฆฌ๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. -* [`renderToStaticMarkup`](/reference/react-dom/server/renderToStaticMarkup)์€ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” React ํŠธ๋ฆฌ๋ฅผ HTML ๋ฌธ์ž์—ด๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. +* [`renderToStaticMarkup`](/reference/react-dom/server/renderToStaticMarkup)์€ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” React ํŠธ๋ฆฌ๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. -<<<<<<< HEAD ์œ„ ๋ฉ”์„œ๋“œ๋“ค์€ ์ŠคํŠธ๋ฆฌ๋ฐ API์™€ ๋น„๊ตํ•˜์—ฌ ๊ธฐ๋Šฅ์ด ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค. - ---- - -## Deprecated server APIs {/*deprecated-server-apis*/} - -<Deprecated> - -์ด API๋Š” ์ถ”ํ›„ React major ๋ฒ„์ „์—์„œ ์ œ๊ฑฐ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. - -</Deprecated> - -* [`renderToNodeStream`](/reference/react-dom/server/renderToNodeStream)์€ React ํŠธ๋ฆฌ๋ฅผ [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams)์œผ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. (Deprecated.) -======= -They have limited functionality compared to the streaming APIs. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc From 8ffa5290775dfb4d534e8231588284dc2a29ebe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 19:27:34 +0900 Subject: [PATCH 0391/1059] docs: update `renderToPipeableStream.md` --- .../server/renderToPipeableStream.md | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/content/reference/react-dom/server/renderToPipeableStream.md b/src/content/reference/react-dom/server/renderToPipeableStream.md index 0f3a78da4..684130fe0 100644 --- a/src/content/reference/react-dom/server/renderToPipeableStream.md +++ b/src/content/reference/react-dom/server/renderToPipeableStream.md @@ -94,7 +94,7 @@ app.use('/', (request, response) => { <CodeStep step={1}>๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ</CodeStep>์™€ ํ•จ๊ป˜ <CodeStep step={2}>๋ถ€ํŠธ์ŠคํŠธ๋žฉ `<script>` ๊ฒฝ๋กœ ๋ชฉ๋ก</CodeStep>์„ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” **๋ฃจํŠธ `<html>` ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•œ ์ „์ฒด ๋ฌธ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** -์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js [[1, 1, "App"]] export default function App() { @@ -200,7 +200,7 @@ app.use('/', (request, response) => { }); ``` -์œ„ ์˜ˆ์‹œ์—์„œ `bootstrapScriptContent` ์˜ต์…˜์€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ „์—ญ `window.assetMap` ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋Š” ์ถ”๊ฐ€ ์ธ๋ผ์ธ `<script>` ํƒœ๊ทธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋™์ผํ•œ `assetMap`์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +์œ„ ์˜ˆ์‹œ์—์„œ `bootstrapScriptContent` ์˜ต์…˜์€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ „์—ญ `window.assetMap` ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋Š” ์ถ”๊ฐ€ ์ธ๋ผ์ธ `<script>` ํƒœ๊ทธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋™์ผํ•œ `assetMap`์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {4} import { hydrateRoot } from 'react-dom/client'; @@ -276,7 +276,7 @@ function ProfilePage() { } ``` -์ด ์˜ˆ์‹œ์—์„œ React๋Š” ํŽ˜์ด์ง€ ์ŠคํŠธ๋ฆฌ๋ฐ์„ ๋” ์ผ์ฐ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `ProfileLayout`๊ณผ `ProfileCover`๋งŒ `<Suspense>` ๊ฒฝ๊ณ„๋กœ ๋‘˜๋Ÿฌ์‹ธ์—ฌ ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋จผ์ € ๋ Œ๋”๋ง์„ ์™„๋ฃŒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ `Sidebar`, `Friends`, `Photos`์ด ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ React๋Š” ๋Œ€์‹  `BigSpinner` ํด๋ฐฑ์„ ์œ„ํ•œ HTML์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฉด ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ํ‘œ์‹œ๋  ๋•Œ๊นŒ์ง€ ๋” ๋งŽ์€ ์ฝ˜ํ…์ธ ๊ฐ€ ๊ณ„์† ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. +์ด ์˜ˆ์‹œ์—์„œ React๋Š” ํŽ˜์ด์ง€ ์ŠคํŠธ๋ฆฌ๋ฐ์„ ๋” ์ผ์ฐ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `ProfileLayout`๊ณผ `ProfileCover`๋งŒ `<Suspense>` ๊ฒฝ๊ณ„๋กœ ๋‘˜๋Ÿฌ์‹ธ์—ฌ ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋จผ์ € ๋ Œ๋”๋ง์„ ์™„๋ฃŒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ `Sidebar`, `Friends`, `Photos`๊ฐ€ ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, React๋Š” ๋Œ€์‹  `BigSpinner` ํด๋ฐฑ์„ ์œ„ํ•œ HTML์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฉด ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ํ‘œ์‹œ๋  ๋•Œ๊นŒ์ง€ ๋” ๋งŽ์€ ์ฝ˜ํ…์ธ ๊ฐ€ ๊ณ„์† ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์ŠคํŠธ๋ฆฌ๋ฐ์€ ๋ธŒ๋ผ์šฐ์ €์—์„œ React ์ž์ฒด๊ฐ€ ๋กœ๋“œ๋˜๊ฑฐ๋‚˜ ์•ฑ์ด ์ƒํ˜ธ์ž‘์šฉ ๊ฐ€๋Šฅํ•ด์งˆ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„์˜ HTML ์ฝ˜ํ…์ธ ๋Š” `<script>` ํƒœ๊ทธ๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์— ์ ์ง„์ ์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. @@ -284,17 +284,17 @@ function ProfilePage() { <Note> -**Suspense ๊ฐ€ ํ™œ์„ฑํ™”๋œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋งŒ Suspense ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.** ์—ฌ๊ธฐ์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. +**Suspense๊ฐ€ ํ™œ์„ฑํ™”๋œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋งŒ Suspense ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.** ์—ฌ๊ธฐ์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. -- [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/)์™€ [Next.js](https://nextjs.org/docs/getting-started/react-essentials) ๊ฐ™์ด Suspense๊ฐ€ ๊ฐ€๋Šฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ -- [`lazy`](/reference/react/lazy)๋ฅผ ํ™œ์šฉํ•œ ์ง€์—ฐ ๋กœ๋”ฉ ์ปดํฌ๋„ŒํŠธ -- [`use`](/reference/react/use)๋ฅผ ์‚ฌ์šฉํ•ด์„œ Promise ๊ฐ’ ์ฝ๊ธฐ +- [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/)์™€ [Next.js](https://nextjs.org/docs/getting-started/react-essentials) ๊ฐ™์€ Suspense๊ฐ€ ๊ฐ€๋Šฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ. +- [`lazy`](/reference/react/lazy)๋ฅผ ํ™œ์šฉํ•œ ์ง€์—ฐ ๋กœ๋”ฉ ์ปดํฌ๋„ŒํŠธ. +- [`use`](/reference/react/use)๋ฅผ ์‚ฌ์šฉํ•ด์„œ Promise ๊ฐ’ ์ฝ๊ธฐ. -Suspense ๋Š” ์ดํŽ™ํŠธ ๋˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋ฅผ ๊ฐ์ง€ํ•˜์ง€ **์•Š์Šต๋‹ˆ๋‹ค.** +Suspense๋Š” ์ดํŽ™ํŠธ ๋˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋ฅผ ๊ฐ์ง€ํ•˜์ง€ **์•Š์Šต๋‹ˆ๋‹ค.** ์œ„์˜ `Posts` ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๋Š” ์ •ํ™•ํ•œ ๋ฐฉ๋ฒ•์€ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. Suspense ์ง€์› ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฌธ์„œ์—์„œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋…์ž์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” Suspense ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋Š” ์•„์ง ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Suspense ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋ถˆ์•ˆ์ •ํ•˜๊ณ  ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ Suspense ์™€ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•œ ๊ณต์‹ API๋Š” ํ–ฅํ›„ React ๋ฒ„์ „์—์„œ ์ถœ์‹œ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +๋…์ž์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” Suspense ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋Š” ์•„์ง ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Suspense ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋ถˆ์•ˆ์ •ํ•˜๊ณ  ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ Suspense์™€ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•œ ๊ณต์‹ API๋Š” ํ–ฅํ›„ React ๋ฒ„์ „์—์„œ ์ถœ์‹œ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. </Note> @@ -502,8 +502,7 @@ const { pipe } = renderToPipeableStream(<App />, { ### ๋‹ค์–‘ํ•œ ์˜ค๋ฅ˜๋ฅผ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ {/*handling-different-errors-in-different-ways*/} -[์ž์‹ ๋งŒ์˜ `Error` ์„œ๋ธŒ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑ](https://ko.javascript.info/custom-errors)ํ•˜๊ณ  [`instanceof`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/instanceof) ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž ์ •์˜ `NotFoundError`๋ฅผ ์ •์˜ํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด๋ฅผ ๋˜์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์˜ค๋ฅ˜ ์œ ํ˜•์— ๋”ฐ๋ผ `onError`, `onShellReady`, `onShellError` ์ฝœ๋ฐฑ์ด ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +[์ž์‹ ๋งŒ์˜ `Error` ์„œ๋ธŒ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑ](https://ko.javascript.info/custom-errors)ํ•˜๊ณ  [`instanceof`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/instanceof) ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž ์ •์˜ `NotFoundError`๋ฅผ ์ •์˜ํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด๋ฅผ ๋˜์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์˜ค๋ฅ˜ ์œ ํ˜•์— ๋”ฐ๋ผ `onError`, `onShellReady`, `onShellError` ์ฝœ๋ฐฑ์ด ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {2,4-14,19,24,30} let didError = false; From 2a8198670a5805ad58ba5bfff0e885e23f29ea70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 19:59:25 +0900 Subject: [PATCH 0392/1059] docs: update `renderToReadableStream.md` --- .../server/renderToPipeableStream.md | 20 ++-- .../server/renderToReadableStream.md | 94 +++++++++---------- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/content/reference/react-dom/server/renderToPipeableStream.md b/src/content/reference/react-dom/server/renderToPipeableStream.md index 684130fe0..5890c48a3 100644 --- a/src/content/reference/react-dom/server/renderToPipeableStream.md +++ b/src/content/reference/react-dom/server/renderToPipeableStream.md @@ -16,7 +16,7 @@ const { pipe, abort } = renderToPipeableStream(reactNode, options?) <Note> -์ด API๋Š” Node.js ์ „์šฉ์ž…๋‹ˆ๋‹ค. Deno ๋ฐ ์ตœ์‹  ์—ฃ์ง€ ๋Ÿฐํƒ€์ž„๊ณผ ๊ฐ™์€ [Web ์ŠคํŠธ๋ฆผ](https://developer.mozilla.org/ko/docs/Web/API/Streams_API)์ด ์žˆ๋Š” ํ™˜๊ฒฝ์—์„œ๋Š” ๋Œ€์‹  [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream)์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์ด API๋Š” Node.js ์ „์šฉ์ž…๋‹ˆ๋‹ค. Deno ๋ฐ ์ตœ์‹  ์—ฃ์ง€ ๋Ÿฐํƒ€์ž„๊ณผ ๊ฐ™์€ [Web ์ŠคํŠธ๋ฆผ](https://developer.mozilla.org/ko/docs/Web/API/Streams_API)์ด ์žˆ๋Š” ํ™˜๊ฒฝ์—์„œ๋Š” [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream)์„ ๋Œ€์‹  ์‚ฌ์šฉํ•˜์„ธ์š”. </Note> @@ -284,17 +284,17 @@ function ProfilePage() { <Note> -**Suspense๊ฐ€ ํ™œ์„ฑํ™”๋œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋งŒ Suspense ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.** ์—ฌ๊ธฐ์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. +**Suspense๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋งŒ Suspense ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.** ์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. - [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/)์™€ [Next.js](https://nextjs.org/docs/getting-started/react-essentials) ๊ฐ™์€ Suspense๊ฐ€ ๊ฐ€๋Šฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ. - [`lazy`](/reference/react/lazy)๋ฅผ ํ™œ์šฉํ•œ ์ง€์—ฐ ๋กœ๋”ฉ ์ปดํฌ๋„ŒํŠธ. - [`use`](/reference/react/use)๋ฅผ ์‚ฌ์šฉํ•ด์„œ Promise ๊ฐ’ ์ฝ๊ธฐ. -Suspense๋Š” ์ดํŽ™ํŠธ ๋˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋ฅผ ๊ฐ์ง€ํ•˜์ง€ **์•Š์Šต๋‹ˆ๋‹ค.** +Suspense๋Š” Effect ๋˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๊ฒฝ์šฐ, **์ด๋ฅผ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.** -์œ„์˜ `Posts` ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๋Š” ์ •ํ™•ํ•œ ๋ฐฉ๋ฒ•์€ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. Suspense ์ง€์› ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฌธ์„œ์—์„œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`Posts` ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ •ํ™•ํ•œ ๋ฐฉ๋ฒ•์€ ์•ž์„œ ์„ค๋ช…ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. Suspense๋ฅผ ์ง€์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ž์„ธํ•œ ๋ฐฉ๋ฒ•์€ ํ•ด๋‹น ํ”„๋ ˆ์ž„์›Œํฌ ๋ฌธ์„œ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋…์ž์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” Suspense ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋Š” ์•„์ง ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Suspense ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋ถˆ์•ˆ์ •ํ•˜๊ณ  ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ Suspense์™€ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•œ ๊ณต์‹ API๋Š” ํ–ฅํ›„ React ๋ฒ„์ „์—์„œ ์ถœ์‹œ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +๋…์ž์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” Suspense ์ง€์› ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋Š” ์•„์ง ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Suspense๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋ถˆ์•ˆ์ •ํ•˜๊ณ  ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ Suspense์™€ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•œ ๊ณต์‹ API๋Š” React์˜ ํ–ฅํ›„ ๋ฒ„์ „์—์„œ ์ถœ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. </Note> @@ -350,9 +350,9 @@ const { pipe } = renderToPipeableStream(<App />, { --- -### ์„œ๋ฒ„์—์„œ ํฌ๋ž˜์‹œ ๋กœ๊น…ํ•˜๊ธฐ {/*logging-crashes-on-the-server*/} +### ์„œ๋ฒ„์—์„œ์˜ ์ถฉ๋Œ์„ ๊ธฐ๋กํ•˜๊ธฐ {/*logging-crashes-on-the-server*/} -๊ธฐ๋ณธ์ ์œผ๋กœ ์„œ๋ฒ„์˜ ๋ชจ๋“  ์˜ค๋ฅ˜๋Š” ์ฝ˜์†”์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ์ด ๋™์ž‘์„ ์žฌ์ •์˜ํ•˜์—ฌ ํฌ๋ž˜์‹œ ๋ณด๊ณ ์„œ๋ฅผ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ธฐ๋ณธ์ ์œผ๋กœ ์„œ๋ฒ„์˜ ๋ชจ๋“  ์˜ค๋ฅ˜๋Š” ์ฝ˜์†”์— ๊ธฐ๋ก<sup>Logging</sup>๋ฉ๋‹ˆ๋‹ค. ์ด ๋™์ž‘์„ ์žฌ์ •์˜ํ•˜์—ฌ ์ถฉ๋Œ<sup>Crash</sup> ๋ณด๊ณ ์„œ๋ฅผ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {7-10} const { pipe } = renderToPipeableStream(<App />, { @@ -437,7 +437,7 @@ function ProfilePage() { 2. ๋” ์ด์ƒ ์„œ๋ฒ„์—์„œ `Posts` ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์„ "ํฌ๊ธฐ"ํ•ฉ๋‹ˆ๋‹ค. 3. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋กœ๋“œ๋˜๋ฉด React๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ `Posts` ๋ Œ๋”๋ง์„ *์žฌ์‹œ๋„*ํ•ฉ๋‹ˆ๋‹ค. -ํด๋ผ์ด์–ธํŠธ์—์„œ `Posts` ๋ Œ๋”๋ง์„ *๋‹ค์‹œ ์‹œ๋„ํ•ด๋„* ์‹คํŒจํ•˜๋ฉด React๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์—๋Ÿฌ๋ฅผ ๋˜์ง‘๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ์—๋Ÿฌ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, [๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ถ€๋ชจ ์—๋Ÿฌ ๊ฒฝ๊ณ„](/reference/react/Component#static-getderivedstatefromerror)์— ๋”ฐ๋ผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์—๋Ÿฌ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ณต๊ตฌํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด ํ™•์‹คํ•ด์งˆ ๋•Œ๊นŒ์ง€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋กœ๋”ฉ ํ‘œ์‹œ๊ธฐ๊ฐ€ ํ‘œ์‹œ๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. +ํด๋ผ์ด์–ธํŠธ์—์„œ `Posts` ๋ Œ๋”๋ง์„ *๋‹ค์‹œ ์‹œ๋„ํ•ด๋„* ์‹คํŒจํ•˜๋ฉด React๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์˜ค๋ฅ˜๋ฅผ ๋˜์ง‘๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ์˜ค๋ฅ˜์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, [๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ถ€๋ชจ ์˜ค๋ฅ˜ ๊ฒฝ๊ณ„](/reference/react/Component#static-getderivedstatefromerror)์— ๋”ฐ๋ผ ์‚ฌ์šฉ์ž์—๊ฒŒ ์˜ค๋ฅ˜๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ณต๊ตฌํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด ํ™•์‹คํ•ด์งˆ ๋•Œ๊นŒ์ง€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋กœ๋”ฉ ํ‘œ์‹œ๊ธฐ๊ฐ€ ํ‘œ์‹œ๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ `Posts` ๋ Œ๋”๋ง์„ ๋‹ค์‹œ ์‹œ๋„ํ•˜์—ฌ ์„ฑ๊ณตํ•˜๋ฉด ์„œ๋ฒ„์˜ ๋กœ๋”ฉ ํด๋ฐฑ์ด ํด๋ผ์ด์–ธํŠธ ๋ Œ๋”๋ง ์ถœ๋ ฅ์œผ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์„œ๋ฒ„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์„œ๋ฒ„ `onError` ์ฝœ๋ฐฑ ๋ฐ ํด๋ผ์ด์–ธํŠธ [`onRecoverableError`](/reference/react-dom/client/hydrateRoot#hydrateroot) ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋˜์–ด ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -469,7 +469,7 @@ const { pipe } = renderToPipeableStream(<App />, { }); ``` -์…ธ *์™ธ๋ถ€*(์ฆ‰, `<Suspense>` ๊ฒฝ๊ณ„ ์•ˆ์ชฝ)์— ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—๋Ÿฌ๋ฅผ ๋˜์ ธ๋„ React๋Š” ๋ Œ๋”๋ง์„ ๋ฉˆ์ถ”์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, `onError` ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋˜์ง€๋งŒ `onShellError` ๋Œ€์‹  `onShellReady`๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” [์œ„์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ](#recovering-from-errors-outside-the-shell) React๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ•ด๋‹น ์˜ค๋ฅ˜๋ฅผ ๋ณต๊ตฌํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +์…ธ *์™ธ๋ถ€*(์ฆ‰, `<Suspense>` ๊ฒฝ๊ณ„ ์•ˆ์ชฝ)์— ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ๋˜์ ธ๋„ React๋Š” ๋ Œ๋”๋ง์„ ๋ฉˆ์ถ”์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, `onError` ์ฝœ๋ฐฑ์ด ์‹คํ–‰๋˜์ง€๋งŒ `onShellError` ๋Œ€์‹  `onShellReady`๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” [์œ„์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ](#recovering-from-errors-outside-the-shell) React๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ•ด๋‹น ์˜ค๋ฅ˜๋ฅผ ๋ณต๊ตฌํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -502,7 +502,7 @@ const { pipe } = renderToPipeableStream(<App />, { ### ๋‹ค์–‘ํ•œ ์˜ค๋ฅ˜๋ฅผ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ {/*handling-different-errors-in-different-ways*/} -[์ž์‹ ๋งŒ์˜ `Error` ์„œ๋ธŒ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑ](https://ko.javascript.info/custom-errors)ํ•˜๊ณ  [`instanceof`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/instanceof) ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž ์ •์˜ `NotFoundError`๋ฅผ ์ •์˜ํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด๋ฅผ ๋˜์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์˜ค๋ฅ˜ ์œ ํ˜•์— ๋”ฐ๋ผ `onError`, `onShellReady`, `onShellError` ์ฝœ๋ฐฑ์ด ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +[์ž์‹ ๋งŒ์˜ `Error` ์„œ๋ธŒ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑ](https://ko.javascript.info/custom-errors)ํ•˜๊ณ  [`instanceof`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/instanceof) ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์–ด๋–ค ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž ์ •์˜ `NotFoundError`๋ฅผ ์ •์˜ํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด๋ฅผ ๋˜์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์˜ค๋ฅ˜ ์œ ํ˜•์— ๋”ฐ๋ผ `onError`, `onShellReady`, `onShellError` ์ฝœ๋ฐฑ์ด ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {2,4-14,19,24,30} let didError = false; diff --git a/src/content/reference/react-dom/server/renderToReadableStream.md b/src/content/reference/react-dom/server/renderToReadableStream.md index 24563d4c1..03db97a2b 100644 --- a/src/content/reference/react-dom/server/renderToReadableStream.md +++ b/src/content/reference/react-dom/server/renderToReadableStream.md @@ -4,7 +4,7 @@ title: renderToReadableStream <Intro> -`renderToReadableStream`๋Š” [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)์„ ์ด์šฉํ•ด React tree๋ฅผ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค. +`renderToReadableStream`๋Š” [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)์„ ์ด์šฉํ•ด React ํŠธ๋ฆฌ๋ฅผ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค. ```js const stream = await renderToReadableStream(reactNode, options?) @@ -16,7 +16,7 @@ const stream = await renderToReadableStream(reactNode, options?) <Note> -์ด API๋Š” [Web Streams.](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. Node.js์˜ ๊ฒฝ์šฐ, [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. +์ด API๋Š” [Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. Node.js์˜ ๊ฒฝ์šฐ, [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)์„ ๋Œ€์‹  ์‚ฌ์šฉํ•˜์„ธ์š”. </Note> @@ -26,7 +26,7 @@ const stream = await renderToReadableStream(reactNode, options?) ### `renderToReadableStream(reactNode, options?)` {/*rendertoreadablestream*/} -`renderToReadableStream`๋ฅผ ํ˜ธ์ถœํ•ด [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ•œ React tree๋ฅผ HTML์ฒ˜๋Ÿผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. +`renderToReadableStream`์„ ํ˜ธ์ถœํ•˜์—ฌ React ํŠธ๋ฆฌ๋ฅผ HTML๋กœ [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)์— ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ```js import { renderToReadableStream } from 'react-dom/server'; @@ -43,7 +43,7 @@ async function handler(request) { ํด๋ผ์ด์–ธํŠธ์—์„œ, [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ํ˜ธ์ถœํ•ด ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ HTML์„ ์ƒํ˜ธ์ž‘์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ญ๋‹ˆ๋‹ค. -[์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) +[์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.](#usage) #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} @@ -56,7 +56,7 @@ async function handler(request) { * **optional** `identifierPrefix`: React๊ฐ€ ID๋กœ์„œ ์‚ฌ์šฉํ•  ๋ฌธ์ž์—ด ์•ž๋จธ๋ฆฌ๋กœ [`useId`](/reference/react/useId)๋กœ ์ƒ์„ฑ๋œ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ root๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ๊ฐ root๊ฐ„์˜ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. [`hydrateRoot`](/reference/react-dom/client/hydrateRoot#parameters)์— ์ „๋‹ฌํ•œ ์•ž๋จธ๋ฆฌ์™€ ๋ฐ˜๋“œ์‹œ ๋™์ผํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. * **optional** `namespaceURI`: ๋ฌธ์ž์—ด๋กœ ์ŠคํŠธ๋ฆผ์„ ์œ„ํ•œ ๊ธฐ์ค€ [namespace URI](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS#important_namespace_uris)์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜ HTML์— ํ•ด๋‹นํ•˜๋Š” ๊ธฐ๋ณธ๊ฐ’์ด ์„ค์ •๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. SVG๋ฅผ ์œ„ํ•ด `'http://www.w3.org/2000/svg'`๋ฅผ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ MathML์„ ์œ„ํ•ด `'http://www.w3.org/1998/Math/MathML'`์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **optional** `nonce`: [`script-src` Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src)๋ฅผ ํ—ˆ์šฉํ•˜๊ธฐ ์œ„ํ•œ [`nonce`](http://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#nonce) (ํ•œ๋ฒˆ๋งŒ ์‚ฌ์šฉ๋˜๋Š”) ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. - * **optional** `onError`: [ํšŒ๋ณตํ•  ์ˆ˜ ์žˆ๋“ ](#recovering-from-errors-outside-the-shell) ์žˆ๋“  [์—†๋“ ] ์ƒ๊ด€์—†์ด, ์„œ๋ฒ„์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ, ์ด ์ฝœ๋ฐฑ์€ `console.error`๋งŒ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. [ํฌ๋ž˜์‹œ ๋ฆฌํฌํŠธ๋ฅผ ๋กœ๊ทธํ•˜๊ธฐ](#logging-crashes-on-the-server) ์œ„ํ•ด ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๊ฑฐ๋‚˜, [์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์กฐ์ •ํ•˜๊ธฐ](#setting-the-status-code) ์œ„ํ•ด ์˜ค๋ฒ„๋ผ์ด๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + * **optional** `onError`: [ํšŒ๋ณตํ•  ์ˆ˜ ์žˆ๋“ ](#recovering-from-errors-outside-the-shell) ์žˆ๋“  [์—†๋“ ] ์ƒ๊ด€์—†์ด, ์„œ๋ฒ„์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ, ์ด ์ฝœ๋ฐฑ์€ `console.error`๋งŒ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. [ํฌ๋ž˜์‹œ ๋ฆฌํฌํŠธ๋ฅผ ๋กœ๊ทธํ•˜๊ธฐ](#logging-crashes-on-the-server) ์œ„ํ•ด ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๊ฑฐ๋‚˜, [์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์กฐ์ •ํ•˜๊ธฐ](#setting-the-status-code) ์œ„ํ•ด ์˜ค๋ฒ„๋ผ์ด๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. * **optional** `progressiveChunkSize`: ์ฒญํฌ์˜ ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. [๊ธฐ๋ณธ ํœด๋ฆฌ์Šคํ‹ฑ์— ๋Œ€ํ•ด ๋” ์ฝ์–ด๋ณด๊ธฐ.](https://github.com/facebook/react/blob/14c2be8dac2d5482fda8a0906a31d239df8551fc/packages/react-server/src/ReactFizzServer.js#L210-L225) * **optional** `signal`: [์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์ทจ์†Œ](#aborting-server-rendering)ํ•˜๊ณ , ๊ทธ ๋‚˜๋จธ์ง€๋ฅผ ํด๋ผ์ด์–ธํŠธ์— ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•œ [๊ฑฐ์ ˆ ์‹ ํ˜ธ(abort signal)](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. @@ -64,8 +64,8 @@ async function handler(request) { `renderToReadableStream`๋Š” [Promise](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise)๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. -- [shell](#specifying-what-goes-into-the-shell)๋ Œ๋”๋ง์— ์„ฑ๊ณตํ–ˆ๋‹ค๋ฉด, ๋ฐ˜ํ™˜๋œ Promise๋Š” [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)์œผ๋กœ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. -- [shell](#specifying-what-goes-into-the-shell)๋ Œ๋”๋ง์— ์‹คํŒจํ•˜๋ฉด, ๋ฐ˜ํ™˜๋œ Promise๋Š” ์ทจ์†Œ๋ฉ๋‹ˆ๋‹ค. [shell ๋ Œ๋”๋ง์— ์‹คํŒจ์‹œ, ์ด๊ฒƒ์„ ์ด์šฉํ•ด ์‹คํŒจ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•˜์„ธ์š”.](#recovering-from-errors-inside-the-shell) +- [shell](#specifying-what-goes-into-the-shell) ๋ Œ๋”๋ง์— ์„ฑ๊ณตํ–ˆ๋‹ค๋ฉด, ๋ฐ˜ํ™˜๋œ Promise๋Š” [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)์œผ๋กœ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. +- [shell](#specifying-what-goes-into-the-shell) ๋ Œ๋”๋ง์— ์‹คํŒจํ•˜๋ฉด, ๋ฐ˜ํ™˜๋œ Promise๋Š” ์ทจ์†Œ๋ฉ๋‹ˆ๋‹ค. [shell ๋ Œ๋”๋ง์— ์‹คํŒจ์‹œ, ์ด๊ฒƒ์„ ์ด์šฉํ•ด ์‹คํŒจ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•˜์„ธ์š”.](#recovering-from-errors-inside-the-shell) ๋ฐ˜ํ™˜๋œ ์ŠคํŠธ๋ฆผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถ”๊ฐ€์ ์ธ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. @@ -75,9 +75,9 @@ async function handler(request) { ## ์‚ฌ์šฉ ์˜ˆ์‹œ {/*usage*/} -### Readable Web Stream์„ ์ด์šฉํ•ด React tree๋ฅผ HTML์ฒ˜๋Ÿผ ๋ Œ๋”๋งํ•˜๊ธฐ {/*rendering-a-react-tree-as-html-to-a-readable-web-stream*/} +### Readable Web Stream์„ ์ด์šฉํ•ด React ํŠธ๋ฆฌ๋ฅผ HTML์ฒ˜๋Ÿผ ๋ Œ๋”๋งํ•˜๊ธฐ {/*rendering-a-react-tree-as-html-to-a-readable-web-stream*/} -`renderToReadableStream`๋ฅผ ํ˜ธ์ถœํ•ด [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)์„ ํ†ตํ•ด React tree๋ฅผ HTML์ฒ˜๋Ÿผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. +`renderToReadableStream`์„ ํ˜ธ์ถœํ•ด [Readable Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream)์„ ํ†ตํ•ด React ํŠธ๋ฆฌ๋ฅผ HTML๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ```js [[1, 4, "<App />"], [2, 5, "['/main.js']"]] import { renderToReadableStream } from 'react-dom/server'; @@ -94,7 +94,7 @@ async function handler(request) { <CodeStep step={1}>root ์ปดํฌ๋„ŒํŠธ</CodeStep>์™€ ํ•จ๊ป˜, <CodeStep step={2}>bootstrap `<script>` ๊ฒฝ๋กœ</CodeStep> ๋ฆฌ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ œ๊ณต๋œ root ์ปดํฌ๋„ŒํŠธ๋Š” **์ตœ์ƒ์œ„ `<html>` ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ๋ฌธ์„œ๋ฅผ ํฌํ•จํ•ด์„œ** ๋ฐ˜ํ™˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๊ฐ€ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค: +์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๊ฐ€ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js [[1, 1, "App"]] export default function App() { @@ -114,7 +114,7 @@ export default function App() { } ``` -React๋Š” [doctype](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)์™€ <CodeStep step={2}>bootstrap `<script>` ํƒœ๊ทธ๋“ค</CodeStep>์„ ๊ฒฐ๊ณผ HTML ์ŠคํŠธ๋ฆผ์— ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค: +React๋Š” [doctype](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)๊ณผ <CodeStep step={2}>bootstrap `<script>` ํƒœ๊ทธ๋“ค</CodeStep>์„ ๊ฒฐ๊ณผ HTML ์ŠคํŠธ๋ฆผ์— ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค. ```html [[2, 5, "/main.js"]] <!DOCTYPE html> @@ -124,7 +124,7 @@ React๋Š” [doctype](https://developer.mozilla.org/en-US/docs/Glossary/Doctype)์™€ <script src="/main.js" async=""></script> ``` -ํด๋ผ์ด์–ธํŠธ์—์„ , ์ถ”๊ฐ€๋œ bootstrap ์Šคํฌ๋ฆฝํŠธ๋Š” [`hydrateRoot`๋ฅผ ํ˜ธ์ถœํ•ด `document` ์ „์ฒด๋ฅผ hydrate ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค:](/reference/react-dom/client/hydrateRoot#hydrating-an-entire-document) +ํด๋ผ์ด์–ธํŠธ์—์„ , ์ถ”๊ฐ€๋œ bootstrap ์Šคํฌ๋ฆฝํŠธ๋Š” [`hydrateRoot`๋ฅผ ํ˜ธ์ถœํ•ด `document` ์ „์ฒด๋ฅผ hydrate ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค](/reference/react-dom/client/hydrateRoot#hydrating-an-entire-document). ```js [[1, 4, "<App />"]] import { hydrateRoot } from 'react-dom/client'; @@ -139,9 +139,9 @@ hydrateRoot(document, <App />); #### ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์—์„œ CSS์™€ JS์˜ ๊ฒฝ๋กœ ์ฝ์–ด์˜ค๊ธฐ {/*reading-css-and-js-asset-paths-from-the-build-output*/} -JS์™€ CSS๊ฐ™์€ ์ตœ์ข… ์—์…‹๋“ค์— ๋Œ€ํ•œ URL๋“ค์€ ์ข…์ข… ๋นŒ๋“œ ํ›„์— ํ•ด์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `styles.css` ๋Œ€์‹  `styles.123456.css`์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ๋๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—์…‹๋“ค์˜ ํŒŒ์ผ๋ช…์„ ํ•ด์‹œํ•˜๋Š” ๊ฒƒ์€ ๋ชจ๋“  ๋นŒ๋“œ์˜ ๊ฒฐ๊ณผ๋ฌผ์ด ๊ฐ๊ฐ ๋‹ค๋ฅธ ํŒŒ์ผ๋ช…์„ ๊ฐ€์ง€๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ •์  ์—์…‹๋“ค์— ๋Œ€ํ•œ ์žฅ๊ธฐ ์บ์‹ฑ์„ ์•ˆ์ „ํ•˜๊ฒŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค: ์ฆ‰, ํŠน์ • ์ด๋ฆ„์˜ ํŒŒ์ผ ๋‚ด์šฉ์€ ์ ˆ๋Œ€ ๋ฐ”๋€Œ์ง€ ์•Š๋Š” ๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. +JS์™€ CSS๊ฐ™์€ ์ตœ์ข… ์—์…‹๋“ค์— ๋Œ€ํ•œ URL๋“ค์€ ์ข…์ข… ๋นŒ๋“œ ํ›„์— ํ•ด์‹œ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `styles.css` ๋Œ€์‹  `styles.123456.css`์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ๋๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—์…‹๋“ค์˜ ํŒŒ์ผ๋ช…์„ ํ•ด์‹œํ•˜๋Š” ๊ฒƒ์€ ๋ชจ๋“  ๋นŒ๋“œ์˜ ๊ฒฐ๊ณผ๋ฌผ์ด ๊ฐ๊ฐ ๋‹ค๋ฅธ ํŒŒ์ผ๋ช…์„ ๊ฐ€์ง€๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ •์  ์—์…‹๋“ค์— ๋Œ€ํ•œ ์žฅ๊ธฐ ์บ์‹ฑ์„ ์•ˆ์ „ํ•˜๊ฒŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. ์ฆ‰, ํŠน์ • ์ด๋ฆ„์˜ ํŒŒ์ผ ๋‚ด์šฉ์€ ์ ˆ๋Œ€ ๋ฐ”๋€Œ์ง€ ์•Š๋Š” ๋‹ค๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ, ๋นŒ๋“œ ํ›„์— ์—์…‹๋“ค์˜ URL์„ ์•Œ ์ˆ˜ ์—†๋‹ค๋ฉด, ์†Œ์Šค ์ฝ”๋“œ์— URL์„ ๋„ฃ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, JSX์— `"/styles.css"`๋ฅผ ํ•˜๋“œ์ฝ”๋”ฉํ•˜๋Š” ๊ฒƒ์€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์†Œ์Šค ์ฝ”๋“œ์— URL์„ ๋„ฃ์ง€ ์•Š์œผ๋ ค๋ฉด, ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” props๋กœ ์ „๋‹ฌ๋œ ๋งต์—์„œ ์‹ค์ œ ํŒŒ์ผ๋ช…์„ ์ฝ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค: +ํ•˜์ง€๋งŒ, ๋นŒ๋“œ ํ›„์— ์—์…‹๋“ค์˜ URL์„ ์•Œ ์ˆ˜ ์—†๋‹ค๋ฉด, ์†Œ์Šค ์ฝ”๋“œ์— URL์„ ๋„ฃ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, JSX์— `"/styles.css"`๋ฅผ ํ•˜๋“œ์ฝ”๋”ฉํ•˜๋Š” ๊ฒƒ์€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์†Œ์Šค ์ฝ”๋“œ์— URL์„ ๋„ฃ์ง€ ์•Š์œผ๋ ค๋ฉด, ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” props๋กœ ์ „๋‹ฌ๋œ ๋งต์—์„œ ์‹ค์ œ ํŒŒ์ผ๋ช…์„ ์ฝ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ```js {1,6} export default function App({ assetMap }) { @@ -157,7 +157,7 @@ export default function App({ assetMap }) { } ``` -์„œ๋ฒ„์—์„  `<App assetMap={assetMap} />`์„ ๋ Œ๋”๋งํ•˜๊ณ , ์—์…‹ URL๋“ค๊ณผ ํ•จ๊ป˜ `assetMap`์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค: +์„œ๋ฒ„์—์„  `<App assetMap={assetMap} />`์„ ๋ Œ๋”๋งํ•˜๊ณ , ์—์…‹ URL๋“ค๊ณผ ํ•จ๊ป˜ `assetMap`์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ```js {1-5,8,9} // ๋นŒ๋“œ ๋„๊ตฌ๋กœ๋ถ€ํ„ฐ ์ด JSON์„ ์–ป์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์—์„œ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -176,7 +176,7 @@ async function handler(request) { } ``` -์„œ๋ฒ„๊ฐ€ `<App assetMap={assetMap} />`๋ฅผ ๋ Œ๋”๋งํ•œ ์ดํ›„์—”, ํด๋ผ์ด์–ธํŠธ์—์„œ๋„ hydration ์—๋Ÿฌ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด `assetMap`๊ณผ ํ•จ๊ป˜ ๋ Œ๋”๋งํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. `assetMap`์„ ์ง๋ ฌํ™”ํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +์„œ๋ฒ„๊ฐ€ `<App assetMap={assetMap} />`๋ฅผ ๋ Œ๋”๋งํ•œ ์ดํ›„์—”, ํด๋ผ์ด์–ธํŠธ์—์„œ๋„ hydration ์˜ค๋ฅ˜๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด `assetMap`๊ณผ ํ•จ๊ป˜ ๋ Œ๋”๋งํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. `assetMap`์„ ์ง๋ ฌํ™”ํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {9-10} // ๋นŒ๋“œ ๋„๊ตฌ๋กœ๋ถ€ํ„ฐ ์ด JSON์„ ์–ป์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. @@ -197,7 +197,7 @@ async function handler(request) { } ``` -์œ„์˜ ์˜ˆ์‹œ์—์„œ, `bootstrapScriptContent` ์˜ต์…˜์€ ํด๋ผ์ด์–ธํŠธ์—์„œ `window.assetMap` ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋Š” ์ธ๋ผ์ธ `<script>` ํƒœ๊ทธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋™์ผํ•œ `assetMap`์„ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค: +์œ„์˜ ์˜ˆ์‹œ์—์„œ, `bootstrapScriptContent` ์˜ต์…˜์€ ํด๋ผ์ด์–ธํŠธ์—์„œ `window.assetMap` ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋Š” ์ธ๋ผ์ธ `<script>` ํƒœ๊ทธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋™์ผํ•œ `assetMap`์„ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ```js {4} import { hydrateRoot } from 'react-dom/client'; @@ -206,7 +206,7 @@ import App from './App.js'; hydrateRoot(document, <App assetMap={window.assetMap} />); ``` -ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๋Š” ๋ชจ๋‘ ๊ฐ™์€ `assetMap` prop์„ ์ด์šฉํ•ด `App`์„ ๋ Œ๋”๋งํ•˜๋ฏ€๋กœ, hydration ์—๋Ÿฌ๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๋Š” ๋ชจ๋‘ ๊ฐ™์€ `assetMap` prop์„ ์ด์šฉํ•ด `App`์„ ๋ Œ๋”๋งํ•˜๋ฏ€๋กœ, hydration ์˜ค๋ฅ˜๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. </DeepDive> @@ -231,7 +231,7 @@ function ProfilePage() { } ``` -`<Posts />`์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š”๋ฐ ์•ฝ๊ฐ„์˜ ์‹œ๊ฐ„์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. ์ด ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž๊ฐ€ ํฌ์ŠคํŠธ ๋ชฉ๋ก์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ ๋„ ํ”„๋กœํ•„ ํŽ˜์ด์ง€์˜ ๋‚˜๋จธ์ง€ ์ปจํ…์ธ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด, [`<Suspense>`๋ฅผ ์‚ฌ์šฉํ•ด `Posts`๋ฅผ ๊ฐ์‹ธ์ฃผ์„ธ์š”:](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading) +`<Posts />`์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š”๋ฐ ์•ฝ๊ฐ„์˜ ์‹œ๊ฐ„์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. ์ด ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž๊ฐ€ ํฌ์ŠคํŠธ ๋ชฉ๋ก์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ ๋„ ํ”„๋กœํ•„ ํŽ˜์ด์ง€์˜ ๋‚˜๋จธ์ง€ ์ปจํ…์ธ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด, [`<Suspense>`๋ฅผ ์‚ฌ์šฉํ•ด `Posts`๋ฅผ ๊ฐ์‹ธ์ฃผ์„ธ์š”](/reference/react/Suspense#displaying-a-fallback-while-content-is-loading). ```js {9,11} function ProfilePage() { @@ -252,7 +252,7 @@ function ProfilePage() { ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด React๋Š” `Posts`๊ฐ€ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์ „๊นŒ์ง€, HTML ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. React๋Š” ๋จผ์ € ๋กœ๋”ฉ ๋Œ€์ฒด ์ปจํ…์ธ ์ธ `<PostsGlimmer />`๋ฅผ HTML๋กœ ๋ณด๋‚ด๊ณ , `Posts`์˜ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜๋ฉด, `<PostsGlimmer />`๋ฅผ `<Posts />`๋กœ ๊ต์ฒดํ•  HTML๊ณผ ์ธ๋ผ์ธ `<script>` ํƒœ๊ทธ๋ฅผ ํ•จ๊ป˜ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„ , ๋จผ์ € `<PostsGlimmer />`๋ฅผ ๋ณด๊ณ , ํ›„์— `<Posts />`๋ฅผ ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -๋” ์ •๋ฐ€ํ•œ ๋กœ๋”ฉ ์ˆœ์„œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด [`<Suspense>` ๊ฒฝ๊ณ„๋ฅผ ์ค‘์ฒฉ](/reference/react/Suspense#revealing-nested-content-as-it-loads) ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +๋” ์ •๋ฐ€ํ•œ ๋กœ๋”ฉ ์ˆœ์„œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด [`<Suspense>` ๊ฒฝ๊ณ„๋ฅผ ์ค‘์ฒฉ](/reference/react/Suspense#revealing-nested-content-as-it-loads)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {5,13} function ProfilePage() { @@ -282,17 +282,17 @@ function ProfilePage() { <Note> -Suspense-๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋งŒ์ด Suspense ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: +**Suspense๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋งŒ Suspense ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.** ์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. -- [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/)์™€ [Next.js](https://nextjs.org/docs/getting-started/react-essentials) ๊ฐ™์ด Suspense๊ฐ€ ๊ฐ€๋Šฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ -- [`lazy`](/reference/react/lazy)๋ฅผ ํ™œ์šฉํ•œ ์ง€์—ฐ ๋กœ๋”ฉ ์ปดํฌ๋„ŒํŠธ -- [`use`](/reference/react/use)๋ฅผ ์‚ฌ์šฉํ•ด์„œ Promise ๊ฐ’ ์ฝ๊ธฐ +- [Relay](https://relay.dev/docs/guided-tour/rendering/loading-states/)์™€ [Next.js](https://nextjs.org/docs/getting-started/react-essentials) ๊ฐ™์€ Suspense๊ฐ€ ๊ฐ€๋Šฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ. +- [`lazy`](/reference/react/lazy)๋ฅผ ํ™œ์šฉํ•œ ์ง€์—ฐ ๋กœ๋”ฉ ์ปดํฌ๋„ŒํŠธ. +- [`use`](/reference/react/use)๋ฅผ ์‚ฌ์šฉํ•ด์„œ Promise ๊ฐ’ ์ฝ๊ธฐ. -Suspense๋Š” Effect๋‚˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๊ฒฝ์šฐ, **์ด๋ฅผ, ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.** +Suspense๋Š” Effect ๋˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๊ฒฝ์šฐ, **์ด๋ฅผ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.** -`Posts` ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ •ํ™•ํ•œ ๋ฐฉ๋ฒ•์€, ์œ„์— ์„ค๋ช…๋œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. Suspense-๊ฐ€๋Šฅํ•œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐฉ๋ฒ•๊ณผ ๊ทธ ์ž์„ธํ•œ ์‚ฌํ•ญ์€ ํ•ด๋‹น ํ”„๋ ˆ์ž„์›Œํฌ ๋ฌธ์„œ์—์„œ ์ฐพ์œผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`Posts` ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ •ํ™•ํ•œ ๋ฐฉ๋ฒ•์€ ์•ž์„œ ์„ค๋ช…ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. Suspense๋ฅผ ์ง€์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ž์„ธํ•œ ๋ฐฉ๋ฒ•์€ ํ•ด๋‹น ํ”„๋ ˆ์ž„์›Œํฌ ๋ฌธ์„œ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -์ฃผ๊ด€์ ์œผ๋กœ ์ œ์‹œ๋œ ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด Suspense-๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฐฉ๋ฒ•์€ ์•„์ง ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด Suspense-๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค๊ณ  ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐฉ๋ฒ•์€ ์•„์ง ๋ถˆ์•ˆ์ •ํ•˜๊ณ  ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ Suspense์™€ ํ•จ๊ป˜ ์œตํ•ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ณต์‹์ ์ธ API๋Š” React์˜ ํ–ฅํ›„ ๋ฒ„์ „์—์„œ ์ง€์›๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. +๋…์ž์ ์ธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” Suspense ์ง€์› ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋Š” ์•„์ง ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Suspense๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋ถˆ์•ˆ์ •ํ•˜๊ณ  ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ Suspense์™€ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•œ ๊ณต์‹ API๋Š” React์˜ ํ–ฅํ›„ ๋ฒ„์ „์—์„œ ์ถœ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. </Note> @@ -300,7 +300,7 @@ Suspense๋Š” Effect๋‚˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ### Specifying what goes into the shell {/*specifying-what-goes-into-the-shell*/} -์•ฑ์—์„œ `<Suspense>` ๊ฒฝ๊ณ„ ๋ฐ–์— ์žˆ๋Š” ๋ถ€๋ถ„์„ *shell*์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค: +์•ฑ์—์„œ `<Suspense>` ๊ฒฝ๊ณ„ ๋ฐ–์— ์žˆ๋Š” ๋ถ€๋ถ„์„ *shell*์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ```js {3-5,13,14} @@ -322,7 +322,7 @@ function ProfilePage() { } ``` -์ด๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๋Š” ์ตœ์ดˆ์˜ ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ์ •ํ•ด์ค๋‹ˆ๋‹ค: +์ด๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๋Š” ์ตœ์ดˆ์˜ ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ์ •ํ•ด์ค๋‹ˆ๋‹ค. ```js {3-5,13} <ProfileLayout> @@ -331,7 +331,7 @@ function ProfilePage() { </ProfileLayout> ``` -๋งŒ์•ฝ, `<Suspense>` ๊ฒฝ๊ณ„๋ฅผ root์— ๊ฑธ์–ด ์•ฑ ์ „์ฒด๋ฅผ ๊ฐ์ŒŒ๋‹ค๋ฉด, shell์€ spinner๋งŒ์„ ๋ณด์—ฌ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ด๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ์žˆ์–ด์„œ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํฐ spinner๋ฅผ ๋ณด๋Š” ๊ฒƒ์€ ๋น„๋ก ๋” ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋  ์ง€ ์–ธ์ •, ์‹ค์ œ ๋ ˆ์ด์•„์›ƒ์ด ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋А๋ฆฌ๊ณ  ๋” ์งœ์ฆ๋‚˜๋Š” ๊ฒฝํ—˜์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด์œ ๋กœ ๊ฐœ๋ฐœ์ž๋“ค์€ `<Suspense>` ๊ฒฝ๊ณ„๋ฅผ ํ†ตํ•ด shell์„ ์ „์ฒด ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ์˜ ๋ผˆ๋Œ€์ฒ˜๋Ÿผ *์ตœ์†Œํ•œ์œผ๋กœ ์™„์„ฑ๋œ* ์ƒํƒœ์ด๋‹ค๋ผ๋Š” ๋А๋‚Œ์„ ์ค„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +๋งŒ์•ฝ, `<Suspense>` ๊ฒฝ๊ณ„๋ฅผ root์— ๊ฑธ์–ด ์•ฑ ์ „์ฒด๋ฅผ ๊ฐ์ŒŒ๋‹ค๋ฉด, shell์€ spinner๋งŒ์„ ๋ณด์—ฌ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ด๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ์žˆ์–ด์„œ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํฐ spinner๋ฅผ ๋ณด๋Š” ๊ฒƒ์€ ๋น„๋ก ๋” ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋  ์ง€ ์–ธ์ •, ์‹ค์ œ ๋ ˆ์ด์•„์›ƒ์ด ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋А๋ฆฌ๊ณ  ๋” ์งœ์ฆ๋‚˜๋Š” ๊ฒฝํ—˜์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด์œ ๋กœ ๊ฐœ๋ฐœ์ž๋“ค์€ `<Suspense>` ๊ฒฝ๊ณ„๋ฅผ ํ†ตํ•ด shell์„ ์ „์ฒด ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ์˜ ๋ผˆ๋Œ€์ฒ˜๋Ÿผ *์ตœ์†Œํ•œ์œผ๋กœ ์™„์„ฑ๋œ* ์ƒํƒœ๋ผ๋Š” ๋А๋‚Œ์„ ์ค„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. `renderToReadableStream`๋ฅผ ๋น„๋™๊ธฐ ํ˜ธ์ถœํ•˜์—ฌ ๋ชจ๋“  shell์ด ๋ Œ๋”๋ง๋  ๋•Œ๊นŒ์ง€ `stream`์œผ๋กœ ์œ„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๋ณดํ†ต, `stream`์„ ๊ฐ€์ง„ ์‘๋‹ต์„ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•จ์œผ๋กœ์„œ ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. @@ -350,9 +350,9 @@ async function handler(request) { --- -### ์„œ๋ฒ„์˜ ์ถฉ๋Œ์„ ๋กœ๊น…ํ•˜๊ธฐ {/*logging-crashes-on-the-server*/} +### ์„œ๋ฒ„์—์„œ์˜ ์ถฉ๋Œ์„ ๊ธฐ๋กํ•˜๊ธฐ {/*logging-crashes-on-the-server*/} -๊ธฐ๋ณธ์ ์œผ๋กœ, ์„œ๋ฒ„์˜ ๋ชจ๋“  ์—๋Ÿฌ๋Š” ์ฝ˜์†”์— ๋กœ๊น…๋ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋ณธ ๋™์ž‘์„ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ํฌ๋ž˜์‹œ ๋ฆฌํฌํŠธ๋ฅผ ๋กœ๊น…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +๊ธฐ๋ณธ์ ์œผ๋กœ ์„œ๋ฒ„์˜ ๋ชจ๋“  ์˜ค๋ฅ˜๋Š” ์ฝ˜์†”์— ๊ธฐ๋ก<sup>Logging</sup>๋ฉ๋‹ˆ๋‹ค. ์ด ๋™์ž‘์„ ์žฌ์ •์˜ํ•˜์—ฌ ์ถฉ๋Œ<sup>Crash</sup> ๋ณด๊ณ ์„œ๋ฅผ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {4-7} async function handler(request) { @@ -373,7 +373,7 @@ async function handler(request) { --- -### shell ๋‚ด๋ถ€์˜ ์—๋Ÿฌ๋กœ๋ถ€ํ„ฐ ํšŒ๋ณตํ•˜๊ธฐ {/*recovering-from-errors-inside-the-shell*/} +### shell ๋‚ด๋ถ€์˜ ์˜ค๋ฅ˜๋กœ๋ถ€ํ„ฐ ํšŒ๋ณตํ•˜๊ธฐ {/*recovering-from-errors-inside-the-shell*/} ์ด๋ฒˆ ์˜ˆ์‹œ์—์„œ, shell์€ `ProfileLayout`, `ProfileCover` ๊ทธ๋ฆฌ๊ณ  `PostsGlimmer`๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. @@ -390,7 +390,7 @@ function ProfilePage() { } ``` -๋งŒ์•ฝ, ์œ„์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๋ Œ๋”๋งํ•˜๋‹ค๊ฐ€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด, React๋Š” ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ผ ์˜๋ฏธ์žˆ๋Š” HTML์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋•Œ๋ฅผ ๋Œ€๋น„ํ•ด `renderToReadableStream`์„ `try...catch`๋กœ ๊ฐ์‹ธ ์„œ๋ฒ„ ๋ Œ๋”๋ง์— ์˜์กดํ•˜์ง€ ์•Š๋Š” ๋Œ€์ฒด HTML์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋„๋ก ํ•˜์„ธ์š”. +๋งŒ์•ฝ, ์œ„์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๋ Œ๋”๋งํ•˜๋‹ค๊ฐ€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด, React๋Š” ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ผ ์˜๋ฏธ์žˆ๋Š” HTML์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋•Œ๋ฅผ ๋Œ€๋น„ํ•ด `renderToReadableStream`์„ `try...catch`๋กœ ๊ฐ์‹ธ ์„œ๋ฒ„ ๋ Œ๋”๋ง์— ์˜์กดํ•˜์ง€ ์•Š๋Š” ๋Œ€์ฒด HTML์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋„๋ก ํ•˜์„ธ์š”. ```js {2,13-18} async function handler(request) { @@ -414,11 +414,11 @@ async function handler(request) { } ``` -shell์„ ๋ Œ๋”๋งํ•˜๋ฉด์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด, `onError`์™€ `catch` ๋ธ”๋ก์ด ๋™์‹œ์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. `onError`๋Š” ์—๋Ÿฌ๋ฅผ ๋ณด๊ณ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๊ณ , `catch` ๋ธ”๋ก์€ ๋Œ€์ฒด HTML ๋ฌธ์„œ๋ฅผ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜์„ธ์š”. ๋Œ€์ฒด HTML์€ ๋ฐ˜๋“œ์‹œ ์—๋Ÿฌ ํŽ˜์ด์ง€์ผ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , ํด๋ผ์ด์–ธํŠธ์—์„œ๋งŒ ๋ Œ๋”๋ง๋˜๋Š” ๋Œ€์ฒด shell์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +shell์„ ๋ Œ๋”๋งํ•˜๋ฉด์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด, `onError`์™€ `catch` ๋ธ”๋ก์ด ๋™์‹œ์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. `onError`๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ณด๊ณ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๊ณ , `catch` ๋ธ”๋ก์€ ๋Œ€์ฒด HTML ๋ฌธ์„œ๋ฅผ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜์„ธ์š”. ๋Œ€์ฒด HTML์€ ๋ฐ˜๋“œ์‹œ ์˜ค๋ฅ˜ ํŽ˜์ด์ง€์ผ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , ํด๋ผ์ด์–ธํŠธ์—์„œ๋งŒ ๋ Œ๋”๋ง๋˜๋Š” ๋Œ€์ฒด shell์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --- -### shell ์™ธ๋ถ€์˜ ์—๋Ÿฌ๋กœ๋ถ€ํ„ฐ ํšŒ๋ณตํ•˜๊ธฐ {/*recovering-from-errors-outside-the-shell*/} +### shell ์™ธ๋ถ€์˜ ์˜ค๋ฅ˜๋กœ๋ถ€ํ„ฐ ํšŒ๋ณตํ•˜๊ธฐ {/*recovering-from-errors-outside-the-shell*/} ์ด๋ฒˆ ์˜ˆ์‹œ์—์„œ, `<Posts />` ์ปดํฌ๋„ŒํŠธ๋Š” `<Suspense>`์— ๊ฐ์‹ธ์ ธ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, shell์˜ ์ผ๋ถ€๊ฐ€ *์•„๋‹™๋‹ˆ๋‹ค.* @@ -435,15 +435,15 @@ function ProfilePage() { } ``` -`Posts` ์ปดํฌ๋„ŒํŠธ ํ˜น์€ ๊ทธ ๋‚ด๋ถ€ ์–ด๋”˜๊ฐ€์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ, React๋Š” [์—๋Ÿฌ๋กœ ๋ถ€ํ„ฐ ํšŒ๋ณตํ•˜๋ ค๊ณ  ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค:](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content) +`Posts` ์ปดํฌ๋„ŒํŠธ ํ˜น์€ ๊ทธ ๋‚ด๋ถ€ ์–ด๋”˜๊ฐ€์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ, React๋Š” [์˜ค๋ฅ˜๋กœ ๋ถ€ํ„ฐ ํšŒ๋ณตํ•˜๋ ค๊ณ  ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content). 1. ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด `<Suspense>` ๊ฒฝ๊ณ„์˜ ๋กœ๋”ฉ ๋Œ€์ฒด์ธ (`PostsGlimmer`)๋ฅผ HTML๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. 2. ์„œ๋ฒ„์—์„œ ๋”์ด์ƒ์˜ `Posts`์™€ ๊ทธ ๋‚ด๋ถ€๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์„ "ํฌ๊ธฐ"ํ•ฉ๋‹ˆ๋‹ค. 3. ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ๋กœ๋”ฉ๋˜์—ˆ์„ ๋•Œ, React๋Š” `Posts`๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋ ค๊ณ  ์‹œ๋„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. -๋งŒ์•ฝ ํด๋ผ์ด์–ธํŠธ์—์„œ๋„ `Posts` ๋ Œ๋”๋ง ์žฌ์‹œ๋„๊ฐ€ ์‹คํŒจํ•œ๋‹ค๋ฉด, React๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์—๋Ÿฌ๋ฅผ ๋˜์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ์ค‘์— ์ผ์–ด๋‚œ ๋ชจ๋“  ์—๋Ÿฌ๊ณผ ํ•จ๊ป˜, [๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ถ€๋ชจ ์—๋Ÿฌ ๊ฒฝ๊ณ„](/reference/react/Component#static-getderivedstatefromerror)๋กœ ์‚ฌ์šฉ์ž์—๊ฒŒ ์–ด๋–ค ์—๋Ÿฌ๋ฅผ ๋ณด์—ฌ์ค˜์•ผํ•  ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋Š”, ์‚ฌ์šฉ์ž๊ฐ€ ์—๋Ÿฌ๊ฐ€ ๋ณต๊ตฌ๋  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด ํ™•์‹ค์‹œ ๋  ๋•Œ๊นŒ์ง€ ๋กœ๋”ฉ ํ‘œ์‹œ๊ธฐ๋ฅผ ๋ณด๊ณ ์žˆ์–ด์•ผ ํ•œ ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. +๋งŒ์•ฝ ํด๋ผ์ด์–ธํŠธ์—์„œ๋„ `Posts` ๋ Œ๋”๋ง ์žฌ์‹œ๋„๊ฐ€ ์‹คํŒจํ•œ๋‹ค๋ฉด, React๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์˜ค๋ฅ˜๋ฅผ ๋˜์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ์ค‘์— ์ผ์–ด๋‚œ ๋ชจ๋“  ์˜ค๋ฅ˜๊ณผ ํ•จ๊ป˜, [๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ถ€๋ชจ ์˜ค๋ฅ˜ ๊ฒฝ๊ณ„](/reference/react/Component#static-getderivedstatefromerror)๋กœ ์‚ฌ์šฉ์ž์—๊ฒŒ ์–ด๋–ค ์˜ค๋ฅ˜๋ฅผ ๋ณด์—ฌ์ค˜์•ผํ•  ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋Š”, ์‚ฌ์šฉ์ž๊ฐ€ ์˜ค๋ฅ˜๊ฐ€ ๋ณต๊ตฌ๋  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด ํ™•์‹ค์‹œ ๋  ๋•Œ๊นŒ์ง€ ๋กœ๋”ฉ ํ‘œ์‹œ๊ธฐ๋ฅผ ๋ณด๊ณ ์žˆ์–ด์•ผ ํ•œ ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -ํด๋ผ์ด์–ธํŠธ์—์„œ `Posts` ๋ Œ๋”๋ง ์žฌ์‹œ๋„๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด, ์„œ๋ฒ„์—์„œ ์˜จ ๋กœ๋”ฉ ๋Œ€์ฒด HTML์ด ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง๋œ ๊ฒฐ๊ณผ๋กœ ๊ต์ฒด๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์„œ๋ฒ„์—์„œ ์—๋Ÿฌ๊ฐ€ ์žˆ์—ˆ๋Š”์ง€ ๋ชจ๋ฅผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์„œ๋ฒ„์˜ `onError` ์ฝœ๋ฐฑ๊ณผ ํด๋ผ์ด์–ธํŠธ์˜ [`onRecoverableError`](/reference/react-dom/client/hydrateRoot#hydrateroot) ์ฝœ๋ฐฑ์€ ๊ทธ๋Œ€๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์—๋Ÿฌ ๋‚ด์šฉ์„ ๋ฐ›์•„์„œ ๋กœ๊น…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +ํด๋ผ์ด์–ธํŠธ์—์„œ `Posts` ๋ Œ๋”๋ง ์žฌ์‹œ๋„๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด, ์„œ๋ฒ„์—์„œ ์˜จ ๋กœ๋”ฉ ๋Œ€์ฒด HTML์ด ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง๋œ ๊ฒฐ๊ณผ๋กœ ๊ต์ฒด๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์„œ๋ฒ„์—์„œ ์˜ค๋ฅ˜๊ฐ€ ์žˆ์—ˆ๋Š”์ง€ ๋ชจ๋ฅผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์„œ๋ฒ„์˜ `onError` ์ฝœ๋ฐฑ๊ณผ ํด๋ผ์ด์–ธํŠธ์˜ [`onRecoverableError`](/reference/react-dom/client/hydrateRoot#hydrateroot) ์ฝœ๋ฐฑ์€ ๊ทธ๋Œ€๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์˜ค๋ฅ˜ ๋‚ด์šฉ์„ ๋ฐ›์•„์„œ ๋กœ๊น…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --- @@ -451,7 +451,7 @@ function ProfilePage() { ์ŠคํŠธ๋ฆฌ๋ฐ์€ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๋ฅผ ๋™๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ปจํ…์ธ ๋ฅผ ๋” ๋นจ๋ฆฌ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํŽ˜์ด์ง€๋ฅผ ์ŠคํŠธ๋ฆฌ๋ฐํ•˜๊ฒ ์ง€๋งŒ, ํ•œ๋ฒˆ ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์‹œ์ž‘ํ•˜๋ฉด, ์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -์•ฑ์„ shell(`<Suspense>` ๊ฒฝ๊ณ„ ๋ฐ”๊นฅ์˜ ๋ชจ๋“  ๊ฒƒ)๊ณผ ๋‚˜๋จธ์ง€ ์ปจํ…์ธ ๋“ค๋กœ [๋‚˜๋ˆ„๋Š” ๊ฒƒ](#specifying-what-goes-into-the-shell)์œผ๋กœ, ์ด ๋ฌธ์ œ๋Š” ์ด๋ฏธ ํ•ด๊ฒฐ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ shell์— ์—๋Ÿฌ๊ฐ€ ์žˆ๋‹ค๋ฉด, `catch` ๋ธ”๋ก์ด ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜น์€, ํด๋ผ์ด์–ธํŠธ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ณต๊ตฌ๋œ ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด, ๊ทธ๋ƒฅ "OK"๋ฅผ ๋ณด๋‚ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +์•ฑ์„ shell(`<Suspense>` ๊ฒฝ๊ณ„ ๋ฐ”๊นฅ์˜ ๋ชจ๋“  ๊ฒƒ)๊ณผ ๋‚˜๋จธ์ง€ ์ปจํ…์ธ ๋“ค๋กœ [๋‚˜๋ˆ„๋Š” ๊ฒƒ](#specifying-what-goes-into-the-shell)์œผ๋กœ, ์ด ๋ฌธ์ œ๋Š” ์ด๋ฏธ ํ•ด๊ฒฐ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ shell์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋‹ค๋ฉด, `catch` ๋ธ”๋ก์ด ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜น์€, ํด๋ผ์ด์–ธํŠธ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ณต๊ตฌ๋œ ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด, ๊ทธ๋ƒฅ "OK"๋ฅผ ๋ณด๋‚ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {11} async function handler(request) { @@ -476,9 +476,9 @@ async function handler(request) { } ``` -๋งŒ์•ฝ shell ๋ฐ”๊นฅ (`<Suspense>` ๊ฒฝ๊ณ„์˜ ์•ˆ์ชฝ)์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด, React๋Š” ๋ Œ๋”๋ง์„ ๋ฉˆ์ถ”์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, `onError` ์ฝœ๋ฐฑ์€ ์‹คํ–‰๋˜์ง€๋งŒ, `catch` ๋ธ”๋ก์€ ์‹คํ–‰๋˜์ง€ ์•Š์€ ์ฑ„๋กœ ์ฝ”๋“œ๊ฐ€ ๊ณ„์†ํ•ด์„œ ์‹คํ–‰๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š”, [์œ„์—์„œ ์„ค๋ช…ํ–ˆ๋˜ ๊ฒƒ ์ฒ˜๋Ÿผ](#recovering-from-errors-outside-the-shell), React๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ•ด๋‹น ์—๋Ÿฌ๋ฅผ ๋ณต๊ตฌํ•˜๋ ค๊ณ  ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +๋งŒ์•ฝ shell ๋ฐ”๊นฅ (`<Suspense>` ๊ฒฝ๊ณ„์˜ ์•ˆ์ชฝ)์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด, React๋Š” ๋ Œ๋”๋ง์„ ๋ฉˆ์ถ”์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, `onError` ์ฝœ๋ฐฑ์€ ์‹คํ–‰๋˜์ง€๋งŒ, `catch` ๋ธ”๋ก์€ ์‹คํ–‰๋˜์ง€ ์•Š์€ ์ฑ„๋กœ ์ฝ”๋“œ๊ฐ€ ๊ณ„์†ํ•ด์„œ ์‹คํ–‰๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š”, [์œ„์—์„œ ์„ค๋ช…ํ–ˆ๋˜ ๊ฒƒ ์ฒ˜๋Ÿผ](#recovering-from-errors-outside-the-shell), React๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—์„œ ํ•ด๋‹น ์˜ค๋ฅ˜๋ฅผ ๋ณต๊ตฌํ•˜๋ ค๊ณ  ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -ํ•˜์ง€๋งŒ, ๊ทธ๋ž˜๋„ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์ด์šฉํ•˜์—ฌ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +ํ•˜์ง€๋งŒ, ๊ทธ๋ž˜๋„ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์ด์šฉํ•˜์—ฌ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {3,7,13} async function handler(request) { @@ -505,13 +505,13 @@ async function handler(request) { } ``` -์ด๋Š”, ์ดˆ๊ธฐ shell ์ฝ˜ํ…์ธ ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋™์•ˆ ๋ฐœ์ƒํ•œ shell ์™ธ๋ถ€์—์„œ ์ผ์–ด๋‚œ ์—๋Ÿฌ๋งŒ ์žก์„ ๊ฒƒ์ด๋ฏ€๋กœ, ์™„์ „ํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋งŒ์•ฝ, ์–ด๋–ค ์ปจํ…์ธ ๊ฐ€ ์ •๋ง ์ค‘์š”ํ•ด์„œ ํ•ด๋‹น ์ปจํ…์ธ ์— ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด, ๊ทธ๊ฒƒ์„ shell ์•ˆ์œผ๋กœ ์˜ฎ๊ฒจ ์—๋Ÿฌ๋ฅผ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด๋Š”, ์ดˆ๊ธฐ shell ์ฝ˜ํ…์ธ ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋™์•ˆ ๋ฐœ์ƒํ•œ shell ์™ธ๋ถ€์—์„œ ์ผ์–ด๋‚œ ์˜ค๋ฅ˜๋งŒ ์žก์„ ๊ฒƒ์ด๋ฏ€๋กœ, ์™„์ „ํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋งŒ์•ฝ, ์–ด๋–ค ์ปจํ…์ธ ๊ฐ€ ์ •๋ง ์ค‘์š”ํ•ด์„œ ํ•ด๋‹น ์ปจํ…์ธ ์— ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜๋ฅผ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด, ๊ทธ๊ฒƒ์„ shell ์•ˆ์œผ๋กœ ์˜ฎ๊ฒจ ์˜ค๋ฅ˜๋ฅผ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --- -### ๊ฐ๊ธฐ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ {/*handling-different-errors-in-different-ways*/} +### ๊ฐ๊ธฐ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ {/*handling-different-errors-in-different-ways*/} -[`Error` ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์ง์ ‘ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ ](https://javascript.info/custom-errors), [`instanceof`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof) ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•ด ์–ด๋–ค ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `NotFoundError`๋ผ๋Š” ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์ •์˜ํ–ˆ๊ณ  ์ด๋ฅผ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐœ์ƒ์‹œ์ผฐ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด, `onError`์—์„œ ์—๋Ÿฌ๋ฅผ ์ €์žฅํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์ „์— ์—๋Ÿฌ ํƒ€์ž…์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋™์ž‘์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +[`Error` ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์ง์ ‘ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ ](https://javascript.info/custom-errors), [`instanceof`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof) ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•ด ์–ด๋–ค ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”์ง€ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `NotFoundError`๋ผ๋Š” ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ์ •์˜ํ–ˆ๊ณ  ์ด๋ฅผ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐœ์ƒ์‹œ์ผฐ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด, `onError`์—์„œ ์˜ค๋ฅ˜๋ฅผ ์ €์žฅํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์ „์— ์˜ค๋ฅ˜ ํƒ€์ž…์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋™์ž‘์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {2-3,5-15,22,28,33} async function handler(request) { @@ -563,7 +563,7 @@ async function handler(request) { ํ•˜์ง€๋งŒ, ํฌ๋กค๋Ÿฌ๊ฐ€ ์ด ํŽ˜์ด์ง€๋ฅผ ๋ฐฉ๋ฌธํ–ˆ์„ ๋•Œ, ํ˜น์€ ํŽ˜์ด์ง€๋ฅผ ๋นŒ๋“œํ–ˆ์„ ๋•Œ ์ •์ ์œผ๋กœ ์ƒ์„ฑํ•œ ๊ฒฝ์šฐ์—” ์ปจํ…์ธ ๊ฐ€ ์ ์ง„์ ์œผ๋กœ ๋“œ๋Ÿฌ๋‚˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ชจ๋“  ์ปจํ…์ธ ๊ฐ€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ชจ๋‘ ๋ถˆ๋Ÿฌ์™€์ง„ ๋‹ค์Œ ์ตœ์ข… HTML ์ถœ๋ ฅ๋ฌผ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. -`stream.allReady` Promise๋ฅผ ๊ธฐ๋‹ค๋ฆผ์œผ๋กœ์จ ๋ชจ๋“  ์ปจํ…์ธ ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +`stream.allReady` Promise๋ฅผ ๊ธฐ๋‹ค๋ฆผ์œผ๋กœ์จ ๋ชจ๋“  ์ปจํ…์ธ ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {12-15} async function handler(request) { @@ -594,7 +594,7 @@ async function handler(request) { } ``` -์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฌธ์ž๋ผ๋ฉด ์ปจํ…์ธ ๋ฅผ ์ ์ง„์ ์œผ๋กœ ๋ฐ›๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํฌ๋กค๋Ÿฌ๋ผ๋ฉด, ๋ชจ๋“  ์ปจํ…์ธ ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ํ›„์— ์ตœ์ข… HTML์„ ๋ฐ›๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ด๋Š” ํฌ๋กค๋Ÿฌ๊ฐ€ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์œผ๋กœ, ๊ทธ ์ค‘์— ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ๋˜๋Š”๋ฐ ๋А๋ฆฌ๊ฑฐ๋‚˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์•ฑ์˜ ํŠน์„ฑ์— ๋”ฐ๋ผ ํฌ๋กค๋Ÿฌ์—๊ฒŒ shell์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์ด ๋” ์ข‹์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฌธ์ž๋ผ๋ฉด ์ปจํ…์ธ ๋ฅผ ์ ์ง„์ ์œผ๋กœ ๋ฐ›๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํฌ๋กค๋Ÿฌ๋ผ๋ฉด, ๋ชจ๋“  ์ปจํ…์ธ ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ํ›„์— ์ตœ์ข… HTML์„ ๋ฐ›๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ด๋Š” ํฌ๋กค๋Ÿฌ๊ฐ€ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์œผ๋กœ, ๊ทธ ์ค‘์— ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ๋˜๋Š”๋ฐ ๋А๋ฆฌ๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์•ฑ์˜ ํŠน์„ฑ์— ๋”ฐ๋ผ ํฌ๋กค๋Ÿฌ์—๊ฒŒ shell์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์ด ๋” ์ข‹์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. --- From d2fd63f505c6dc18f3bb944bb35e58eb819edcbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 20:16:34 +0900 Subject: [PATCH 0393/1059] docs: update `renderToStaticMarkup.md` --- .../react-dom/server/renderToStaticMarkup.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/content/reference/react-dom/server/renderToStaticMarkup.md b/src/content/reference/react-dom/server/renderToStaticMarkup.md index af49f806a..9345b501a 100644 --- a/src/content/reference/react-dom/server/renderToStaticMarkup.md +++ b/src/content/reference/react-dom/server/renderToStaticMarkup.md @@ -4,7 +4,7 @@ title: renderToStaticMarkup <Intro> -`renderToStaticMarkup` ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” React ํŠธ๋ฆฌ๋ฅผ HTML ๋ฌธ์ž์—ด๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. +`renderToStaticMarkup`์€ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” React ํŠธ๋ฆฌ๋ฅผ HTML ๋ฌธ์ž์—ด๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ```js const html = renderToStaticMarkup(reactNode, options?) @@ -28,7 +28,7 @@ import { renderToStaticMarkup } from 'react-dom/server'; const html = renderToStaticMarkup(<Page />); ``` -์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” React ์ปดํฌ๋„ŒํŠธ์˜ HTML ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. +์ด๋Š” React ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” HTML ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. [์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) @@ -36,7 +36,7 @@ const html = renderToStaticMarkup(<Page />); * `reactNode`: HTML๋กœ ๋ Œ๋”๋งํ•  React ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `<Page />`์™€ ๊ฐ™์€ JSX ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. * **optional** `options`: ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์œ„ํ•œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. - * **optional** `identifierPrefix`: [`useId`.](/reference/react/useId)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ID์— ๋Œ€ํ•ด React๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ ‘๋‘์‚ฌ์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ ๋ฃจํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. + * **optional** `identifierPrefix`: [`useId`](/reference/react/useId)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ID์— ๋Œ€ํ•ด React๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ ‘๋‘์‚ฌ์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ ๋ฃจํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} @@ -44,11 +44,11 @@ HTML ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} -* `renderToStaticMarkup`์˜ ์ถœ๋ ฅ๊ฐ’์€ hydrate ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +* `renderToStaticMarkup`์˜ ์ถœ๋ ฅ๊ฐ’์€ Hydrate ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. -* `renderToStaticMarkup`์€ Suspense๋ฅผ ์ œํ•œ์ ์œผ๋กœ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ suspense ์ปดํฌ๋„ŒํŠธ๋ผ๋ฉด, `renderToStaticMarkup`์€ ์ฆ‰์‹œ HTML์„ fallback์œผ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. +* `renderToStaticMarkup`์€ Suspense๋ฅผ ์ œํ•œ์ ์œผ๋กœ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ Suspense ์ปดํฌ๋„ŒํŠธ๋ผ๋ฉด, `renderToStaticMarkup`์€ ์ฆ‰์‹œ HTML์„ Fallback์œผ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. -* `renderToStaticMarkup`์€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋™์ž‘ํ•˜์ง€๋งŒ, ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฑด ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ HTML๋กœ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, [HTML ์„ DOM ๋…ธ๋“œ๋กœ ๋ Œ๋”๋งํ•ด์„œ ๊ฐ€์ ธ์˜ค์„ธ์š”.](/reference/react-dom/server/renderToString#removing-rendertostring-from-the-client-code) +* `renderToStaticMarkup`์€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋™์ž‘ํ•˜์ง€๋งŒ, ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ HTML๋กœ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, [HTML์„ DOM ๋…ธ๋“œ๋กœ ๋ Œ๋”๋งํ•ด์„œ ๊ฐ€์ ธ์˜ค์„ธ์š”.](/reference/react-dom/server/renderToString#removing-rendertostring-from-the-client-code) --- @@ -56,7 +56,7 @@ HTML ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ### ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” React ํŠธ๋ฆฌ๋ฅผ HTML ๋ฌธ์ž์—ด๋กœ ๋ Œ๋”๋งํ•˜๊ธฐ {/*rendering-a-non-interactive-react-tree-as-html-to-a-string*/} -`renderToStaticMarkup`์„ ์„œ๋ฒ„ ์‘๋‹ต๊ณผ ํ•จ๊ป˜ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” HTML ๋ฌธ์ž์—ด๋กœ ์•ฑ์— ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ์ถœํ•˜์„ธ์š”: +`renderToStaticMarkup`์„ ์„œ๋ฒ„ ์‘๋‹ต๊ณผ ํ•จ๊ป˜ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” HTML ๋ฌธ์ž์—ด๋กœ ์•ฑ์— ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ์ถœํ•˜์„ธ์š”. ```js {5-6} import { renderToStaticMarkup } from 'react-dom/server'; @@ -68,12 +68,12 @@ app.use('/', (request, response) => { }); ``` -์ด๊ฒƒ์€ React ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” ์ดˆ๊ธฐ HTML ๊ฒฐ๊ณผ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. +์ด๊ฒƒ์€ React ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” ์ดˆ๊ธฐ HTML ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. <Pitfall> -์ด ๋ฉ”์„œ๋“œ๋Š” **hydrate ๋  ์ˆ˜ ์—†๊ณ  ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” HTML** ์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” React๋ฅผ ๊ฐ„๋‹จํ•œ ์ •์  ํŽ˜์ด์ง€ ์ƒ์„ฑ๊ธฐ๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ด๋ฉ”์ผ๊ณผ ๊ฐ™์€ ์™„์ „ํžˆ ์ •์ ์ธ ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. +์ด ๋ฉ”์„œ๋“œ๋Š” **Hydrate ๋  ์ˆ˜ ์—†๋Š” ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” HTML**์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” React๋ฅผ ๊ฐ„๋‹จํ•œ ์ •์  ํŽ˜์ด์ง€ ์ƒ์„ฑ๊ธฐ๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ์ด๋ฉ”์ผ๊ณผ ๊ฐ™์€ ์™„์ „ํžˆ ์ •์ ์ธ ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -์ƒํ˜ธ์ž‘์šฉ์„ ์œ„ํ•œ ์•ฑ์€ ์„œ๋ฒ„์—์„œ [`renderToString`](/reference/react-dom/server/renderToString)์„, ํด๋ผ์ด์–ธํŠธ์—์„œ [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์ƒํ˜ธ์ž‘์šฉ์„ ์œ„ํ•œ ์•ฑ์€ ์„œ๋ฒ„์—์„œ [`renderToString`](/reference/react-dom/server/renderToString), ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. </Pitfall> From f8ae01ad98d020f118784d5d41a6e2de772fe9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 20:38:58 +0900 Subject: [PATCH 0394/1059] docs: update `renderToString.md` --- .../react-dom/server/renderToString.md | 48 +++++++------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/src/content/reference/react-dom/server/renderToString.md b/src/content/reference/react-dom/server/renderToString.md index 0bb71bbe3..522fe407c 100644 --- a/src/content/reference/react-dom/server/renderToString.md +++ b/src/content/reference/react-dom/server/renderToString.md @@ -34,15 +34,15 @@ import { renderToString } from 'react-dom/server'; const html = renderToString(<App />); ``` -ํด๋ผ์ด์–ธํŠธ์—์„œ [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)์„ ํ˜ธ์ถœํ•˜๋ฉด ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ HTML์„ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. +ํด๋ผ์ด์–ธํŠธ์—์„œ [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ HTML์„ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. -[์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) +[์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} * `reactNode`: HTML๋กœ ๋ Œ๋”๋งํ•  React ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด `<App />`๊ณผ ๊ฐ™์€ JSX ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. * **optional** `options`: ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์œ„ํ•œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. - * **optional** `identifierPrefix`: [`useId`.](/reference/react/useId)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ID์— ๋Œ€ํ•ด React๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ ‘๋‘์‚ฌ์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ ๋ฃจํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters)์— ์ „๋‹ฌ๋œ ์ ‘๋‘์‚ฌ์™€ ๋™์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + * **optional** `identifierPrefix`: [`useId`](/reference/react/useId)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ID์— ๋Œ€ํ•ด React๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ ‘๋‘์‚ฌ์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ ๋ฃจํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters)์— ์ „๋‹ฌ๋œ ์ ‘๋‘์‚ฌ์™€ ๋™์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} @@ -60,7 +60,7 @@ HTML ๋ฌธ์ž์—ด. ### React ํŠธ๋ฆฌ๋ฅผ HTML ๋ฌธ์ž์—ด๋กœ ๋ Œ๋”๋งํ•˜๊ธฐ {/*rendering-a-react-tree-as-html-to-a-string*/} -์„œ๋ฒ„ ์‘๋‹ต๊ณผ ํ•จ๊ป˜ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” HTML ๋ฌธ์ž์—ด๋กœ ์•ฑ์„ ๋ Œ๋”๋งํ•˜๋ ค๋ฉด `renderToString`์„ ํ˜ธ์ถœํ•˜์„ธ์š”: +์„œ๋ฒ„ ์‘๋‹ต๊ณผ ํ•จ๊ป˜ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” HTML ๋ฌธ์ž์—ด๋กœ ์•ฑ์„ ๋ Œ๋”๋งํ•˜๋ ค๋ฉด `renderToString`์„ ํ˜ธ์ถœํ•˜์„ธ์š”. ```js {5-6} import { renderToString } from 'react-dom/server'; @@ -72,7 +72,7 @@ app.use('/', (request, response) => { }); ``` -์ด๋ ‡๊ฒŒ ํ•˜๋ฉด React ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ๋น„๋Œ€ํ™”ํ˜• HTML ์ถœ๋ ฅ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ HTML์„ *hydrate*ํ•˜์—ฌ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) ๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์ด๋Š” React ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” HTML ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ HTML์„ *Hydrate*ํ•˜์—ฌ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. <Pitfall> @@ -85,43 +85,33 @@ app.use('/', (request, response) => { ## ๋Œ€์•ˆ {/*alternatives*/} -<<<<<<< HEAD -### ์„œ๋ฒ„์—์„œ `renderToString`์„ ์ŠคํŠธ๋ฆฌ๋ฐ ํ•จ์ˆ˜๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ {/*migrating-from-rendertostring-to-a-streaming-method-on-the-server*/} +### ์„œ๋ฒ„์—์„œ `renderToString`์„ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ Œ๋”๋ง์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ {/*migrating-from-rendertostring-to-a-streaming-method-on-the-server*/} -`renderToString`์€ ๋ฌธ์ž์—ด์„ ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ์ด๋‚˜ ๋ฐ์ดํ„ฐ ๋Œ€๊ธฐ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -======= -### Migrating from `renderToString` to a streaming render on the server {/*migrating-from-rendertostring-to-a-streaming-method-on-the-server*/} +`renderToString`์€ ๋ฌธ์ž์—ด์„ ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ, ๋กœ๋”ฉ ์ค‘์ธ ์ฝ˜ํ…์ธ ๋ฅผ ์ŠคํŠธ๋ฆฌ๋ฐํ•˜๋Š” ๊ฒƒ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -`renderToString` returns a string immediately, so it does not support streaming content as it loads. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +๊ฐ€๋Šฅํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์™„์ „ํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ–์ถ˜ ๋Œ€์•ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. -๊ฐ€๋Šฅํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์™„์ „ํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ–์ถ˜ ๋Œ€์•ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค: - -* Node.js๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream) ์„ ์‚ฌ์šฉํ•˜์„ธ์š”. -* Deno์™€ ์ตœ์‹  ์—ฃ์ง€ ๋Ÿฐํƒ€์ž„์—์„œ [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream) ์„ ์‚ฌ์šฉํ•˜์„ธ์š” +* Node.js๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)์„ ์‚ฌ์šฉํ•˜์„ธ์š”. +* Deno์™€ ์ตœ์‹  ์—ฃ์ง€ ๋Ÿฐํƒ€์ž„์—์„œ [Web Stream](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream)์„ ์‚ฌ์šฉํ•˜์„ธ์š”. ์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ ์ŠคํŠธ๋ฆผ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋„ `renderToString`์„ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --- -<<<<<<< HEAD -### ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ `renderToString` ์ œ๊ฑฐํ•˜๊ธฐ {/*removing-rendertostring-from-the-client-code*/} -======= ### Migrating from `renderToString` to a static prerender on the server {/*migrating-from-rendertostring-to-a-static-prerender-on-the-server*/} `renderToString` returns a string immediately, so it does not support waiting for data to load for static HTML generation. We recommend using these fully-featured alternatives: -* If you use Node.js, use [`prerenderToNodeStream`.](/reference/react-dom/static/prerenderToNodeStream) -* If you use Deno or a modern edge runtime with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), use [`prerender`.](/reference/react-dom/static/prerender) +* If you use Node.js, use [`prerenderToNodeStream`](/reference/react-dom/static/prerenderToNodeStream). +* If you use Deno or a modern edge runtime with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), use [`prerender`](/reference/react-dom/static/prerender). You can continue using `renderToString` if your static site generation environment does not support streams. --- -### Removing `renderToString` from the client code {/*removing-rendertostring-from-the-client-code*/} ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +### ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—์„œ `renderToString` ์ œ๊ฑฐํ•˜๊ธฐ {/*removing-rendertostring-from-the-client-code*/} ํด๋ผ์ด์–ธํŠธ์—์„œ ์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ HTML๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด `renderToString`์„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. @@ -133,7 +123,7 @@ const html = renderToString(<MyIcon />); console.log(html); // ์˜ˆ๋ฅผ ๋“ค์–ด, "<svg>...</svg>" ``` -**ํด๋ผ์ด์–ธํŠธ์—์„œ** `react-dom/server`๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ์ปค์ง€๋ฏ€๋กœ ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ HTML๋กœ ๋ Œ๋”๋งํ•ด์•ผ ํ•  ๊ฒฝ์šฐ [`createRoot`](/reference/react-dom/client/createRoot)์„ ์‚ฌ์šฉํ•˜๊ณ  DOM์—์„œ HTML์„ ์ฝ์œผ์„ธ์š”: +**ํด๋ผ์ด์–ธํŠธ์—์„œ** `react-dom/server`๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ์ปค์ง€๋ฏ€๋กœ ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ HTML๋กœ ๋ Œ๋”๋งํ•ด์•ผ ํ•  ๊ฒฝ์šฐ [`createRoot`](/reference/react-dom/client/createRoot)๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  DOM์—์„œ HTML์„ ์ฝ์œผ์„ธ์š”. ```js import { createRoot } from 'react-dom/client'; @@ -157,12 +147,6 @@ console.log(div.innerHTML); // ์˜ˆ๋ฅผ ๋“ค์–ด, "<svg>...</svg>" `renderToString`์€ Suspense๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -<<<<<<< HEAD -์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ผ์‹œ ์ค‘๋‹จ๋˜๊ฑฐ๋‚˜ (์˜ˆ๋ฅผ ๋“ค์–ด, [`lazy`](/reference/react/lazy)์™€ ํ•จ๊ป˜ ์ •์˜๋˜๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ) `renderToString`์€ ์ฝ˜ํ…์ธ ๊ฐ€ ํ•ด๊ฒฐ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `renderToString`๋Š” ๊ทธ ์œ„์— ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด [`<Suspense>`](/reference/react/Suspense) ๊ฒฝ๊ณ„๋ฅผ ์ฐพ์•„ `fallback` ํ”„๋กœํผํ‹ฐ๋ฅผ HTML์— ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ๋‚ด์šฉ์€ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -======= -If some component suspends (for example, because it's defined with [`lazy`](/reference/react/lazy) or fetches data), `renderToString` will not wait for its content to resolve. Instead, `renderToString` will find the closest [`<Suspense>`](/reference/react/Suspense) boundary above it and render its `fallback` prop in the HTML. The content will not appear until the client code loads. - -To solve this, use one of the [recommended streaming solutions.](#alternatives) For server side rendering, they can stream content in chunks as it resolves on the server so that the user sees the page being progressively filled in before the client code loads. For static site generation, they can wait for all the content to resolve before generating the static HTML. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ผ์‹œ ์ค‘๋‹จ<sup>Suspend</sup>๋˜๊ฑฐ๋‚˜ (์˜ˆ๋ฅผ ๋“ค์–ด, [`lazy`](/reference/react/lazy)์™€ ํ•จ๊ป˜ ์ •์˜๋˜๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ) `renderToString`์€ ์ฝ˜ํ…์ธ ๊ฐ€ ํ•ด๊ฒฐ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. `renderToString`๋Š” ๊ทธ ์œ„์— ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด [`<Suspense>`](/reference/react/Suspense) ๊ฒฝ๊ณ„๋ฅผ ์ฐพ์•„ `fallback` ํ”„๋กœํผํ‹ฐ๋ฅผ HTML์— ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ๋‚ด์šฉ<sup>Content</sup>์€ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. -์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด [๊ถŒ์žฅํ•˜๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ ์†”๋ฃจ์…˜](#migrating-from-rendertostring-to-a-streaming-method-on-the-server) ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์— ํŽ˜์ด์ง€๊ฐ€ ์ ์ง„์ ์œผ๋กœ ์ฑ„์›Œ์ง€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ์„œ๋ฒ„์—์„œ ํ•ด๊ฒฐํ•  ๋•Œ ์ปจํ…์ธ ๋ฅผ ์ฒญํฌ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +To solve this, use one of the [recommended streaming solutions](#alternatives). For server side rendering, they can stream content in chunks as it resolves on the server so that the user sees the page being progressively filled in before the client code loads. For static site generation, they can wait for all the content to resolve before generating the static HTML. From 4c2a77b8cd10c71703f698fae960eee3e40ae886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 20:42:08 +0900 Subject: [PATCH 0395/1059] docs: remove `renderToNodeStream.md` and `renderToStaticNodeStream.md` --- .../react-dom/server/renderToNodeStream.md | 78 ------------------ .../server/renderToStaticNodeStream.md | 82 ------------------- 2 files changed, 160 deletions(-) delete mode 100644 src/content/reference/react-dom/server/renderToNodeStream.md delete mode 100644 src/content/reference/react-dom/server/renderToStaticNodeStream.md diff --git a/src/content/reference/react-dom/server/renderToNodeStream.md b/src/content/reference/react-dom/server/renderToNodeStream.md deleted file mode 100644 index d4daf1a4b..000000000 --- a/src/content/reference/react-dom/server/renderToNodeStream.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: renderToNodeStream ---- - -<Deprecated> - -์ด API๋Š” ํ–ฅํ›„ React์˜ ์ฃผ์š” ๋ฒ„์ „์—์„œ ์ œ๊ฑฐ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๋Œ€์‹  [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)์„ ์‚ฌ์šฉํ•˜์„ธ์š”. - -</Deprecated> - -<Intro> - -`renderToNodeStream`์€ React ํŠธ๋ฆฌ๋ฅผ [Node.js Readable Stream.](https://nodejs.org/api/stream.html#readable-streams)์œผ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. - -```js -const stream = renderToNodeStream(reactNode, options?) -``` - -</Intro> - -<InlineToc /> - ---- - -## ๋ ˆํผ๋Ÿฐ์Šค {/*reference*/} - -### `renderToNodeStream(reactNode, options?)` {/*rendertonodestream*/} - -์„œ๋ฒ„์—์„œ `renderToNodeStream`์„ ํ˜ธ์ถœํ•˜์—ฌ ์‘๋‹ต์œผ๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams)์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. - -```js -import { renderToNodeStream } from 'react-dom/server'; - -const stream = renderToNodeStream(<App />) -stream.pipe(response); -``` - -ํด๋ผ์ด์–ธํŠธ์—์„œ [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ HTML์„ ์ƒํ˜ธ์ž‘์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“œ์„ธ์š”. - -[์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) - -#### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} - -* `reactNode`: HTML๋กœ ๋ Œ๋”๋งํ•˜๋ ค๋Š” React ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, `<App />`๊ณผ ๊ฐ™์€ JSX ์—˜๋ฆฌ๋จผํŠธ์ž…๋‹ˆ๋‹ค. -* **optional** `options`: ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์œ„ํ•œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. - * **optional** `identifierPrefix`: [`useId`.](/reference/react/useId)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ID์— ๋Œ€ํ•ด React๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ ‘๋‘์‚ฌ์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ ๋ฃจํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters)์— ์ „๋‹ฌ๋œ ์ ‘๋‘์‚ฌ์™€ ๋™์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. - -#### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} - -HTML ๋ฌธ์ž์—ด์„ ์ถœ๋ ฅํ•˜๋Š” [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams)๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - -#### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} - -* ์ด ๋ฉ”์„œ๋“œ๋Š” ์ถœ๋ ฅ๋ฌผ์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์ „์— ๋ชจ๋“  [Suspense boundaries](/reference/react/Suspense))๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค. - -* React 18๋ถ€ํ„ฐ ์ด ๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋“  ์ถœ๋ ฅ๊ฐ’์„ ๋ฒ„ํผ๋งํ•˜๋ฏ€๋กœ ์‹ค์ œ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ ์ด์ ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•  ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. - -* ๋ฐ˜ํ™˜๋œ ์ŠคํŠธ๋ฆผ์€ utf-8๋กœ ์ธ์ฝ”๋”ฉ๋œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ธ์ฝ”๋”ฉ ์ŠคํŠธ๋ฆผ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ํ…์ŠคํŠธ ๋ณ€ํ™˜์„ ์œ„ํ•œ ๋ณ€ํ™˜ ์ŠคํŠธ๋ฆผ์„ ์ œ๊ณตํ•˜๋Š” [iconv-lite](https://www.npmjs.com/package/iconv-lite)์™€ ๊ฐ™์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”. - ---- - -## ์‚ฌ์šฉ๋ฒ• {/*usage*/} - -### React ํŠธ๋ฆฌ๋ฅผ HTML๋กœ Node.js Readable Stream์— ๋ Œ๋”๋งํ•˜๊ธฐ {/*rendering-a-react-tree-as-html-to-a-nodejs-readable-stream*/} - -`renderToNodeStream` ์„ ํ˜ธ์ถœํ•˜์—ฌ ์„œ๋ฒ„ ์‘๋‹ต์œผ๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams)์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. - -```js {5-6} -import { renderToNodeStream } from 'react-dom/server'; - -// ๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ ๊ตฌ๋ฌธ์€ ๋ฐฑ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. -app.use('/', (request, response) => { - const stream = renderToNodeStream(<App />); - stream.pipe(response); -}); -``` - -์ŠคํŠธ๋ฆผ์€ React ์ปดํฌ๋„ŒํŠธ์˜ ์ดˆ๊ธฐ์— ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” HTML ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ HTML์„ *hydrate* ์ฒ˜๋ฆฌํ•˜๊ณ  ์ƒํ˜ธ์ž‘์šฉํ•˜๋„๋ก ํ•˜๋ ค๋ฉด [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. diff --git a/src/content/reference/react-dom/server/renderToStaticNodeStream.md b/src/content/reference/react-dom/server/renderToStaticNodeStream.md deleted file mode 100644 index 488f403ba..000000000 --- a/src/content/reference/react-dom/server/renderToStaticNodeStream.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: renderToStaticNodeStream ---- - -<Intro> - -`renderToStaticNodeStream`์€ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” React ํŠธ๋ฆฌ๋ฅผ [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams)์œผ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. - -```js -const stream = renderToStaticNodeStream(reactNode, options?) -``` - -</Intro> - -<InlineToc /> - ---- - -## ๋ ˆํผ๋Ÿฐ์Šค {/*reference*/} - -### `renderToStaticNodeStream(reactNode, options?)` {/*rendertostaticnodestream*/} - -์„œ๋ฒ„์—์„œ `renderToStaticNodeStream`์„ ํ˜ธ์ถœํ•˜์—ฌ [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams)์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. - -```js -import { renderToStaticNodeStream } from 'react-dom/server'; - -const stream = renderToStaticNodeStream(<Page />); -stream.pipe(response); -``` - -[์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) - -stream์€ React ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” HTML ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. - -#### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} - -* `reactNode`: HTML๋กœ ๋ Œ๋”๋งํ•  React ๋…ธ๋“œ. ์˜ˆ๋ฅผ ๋“ค์–ด `<Page />` ์™€ ๊ฐ™์€ JSX ์—˜๋ฆฌ๋จผํŠธ. -* **optional** `options`: ์„œ๋ฒ„ ๋ Œ๋”๋ง์„ ์œ„ํ•œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. - * **optional** `identifierPrefix`: [`useId`.](/reference/react/useId)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ID์— ๋Œ€ํ•ด React๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ ‘๋‘์‚ฌ์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ ๋ฃจํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. - -#### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} - -HTML ๋ฌธ์ž์—ด์„ ์ถœ๋ ฅํ•˜๋Š” [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams)์ž…๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ HTML์€ ํด๋ผ์ด์–ธํŠธ์—์„œ hydrate ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. - -#### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} - -* `renderToStaticNodeStream`์˜ ์ถœ๋ ฅ๊ฐ’์€ hydrate ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. - -* ์ด ๋ฉ”์„œ๋“œ๋Š” ์ถœ๋ ฅ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜๊ธฐ ์ „์— ๋ชจ๋“  [Suspense boundaries](/reference/react/Suspense)๊ฐ€ ์™„๋ฃŒ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. - -* React 18๋ถ€ํ„ฐ ์ด ๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋“  ์ถœ๋ ฅ๊ฐ’์„ ๋ฒ„ํผ๋งํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ŠคํŠธ๋ฆฌ๋ฐ์˜ ์ด์ ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. - -* ๋ฐ˜ํ™˜๋œ ์ŠคํŠธ๋ฆผ์€ UTF-8๋กœ ์ธ์ฝ”๋”ฉ๋œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ธ์ฝ”๋”ฉ๋œ ์ŠคํŠธ๋ฆผ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด, ํŠธ๋žœ์Šค์ฝ”๋”ฉ์„ ์œ„ํ•œ ๋ณ€ํ™˜ ์ŠคํŠธ๋ฆผ์„ ์ œ๊ณตํ•˜๋Š” [iconv-lite](https://www.npmjs.com/package/iconv-lite)์™€ ๊ฐ™์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”. - ---- - -## ์‚ฌ์šฉ๋ฒ• {/*usage*/} - -### React ํŠธ๋ฆฌ๋ฅผ ์ •์  HTML๋กœ Node.js Readable Stream์— ๋ Œ๋”๋ง ํ•˜๊ธฐ {/*rendering-a-react-tree-as-static-html-to-a-nodejs-readable-stream*/} - -`renderToStaticNodeStream`์„ ํ˜ธ์ถœํ•˜์—ฌ ์„œ๋ฒ„ ์‘๋‹ต์œผ๋กœ ํŒŒ์ดํ”„ ํ†ต์‹  ํ•  ์ˆ˜ ์žˆ๋Š” [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams)์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. - -```js {5-6} -import { renderToStaticNodeStream } from 'react-dom/server'; - -// ๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ ๋ฌธ๋ฒ•์€ ๋ฐฑ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. -app.use('/', (request, response) => { - const stream = renderToStaticNodeStream(<Page />); - stream.pipe(response); -}); -``` - -stream์€ React ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” ์ดˆ๊ธฐ HTML ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. - -<Pitfall> - -์ด ๋ฉ”์„œ๋“œ๋Š” **hydrate ๋  ์ˆ˜ ์—†๊ณ  ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” HTML** ์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” React๋ฅผ ๊ฐ„๋‹จํ•œ ์ •์  ํŽ˜์ด์ง€ ์ƒ์„ฑ๊ธฐ๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ด๋ฉ”์ผ๊ณผ ๊ฐ™์€ ์™„์ „ํžˆ ์ •์ ์ธ ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. - -์ƒํ˜ธ์ž‘์šฉ์„ ์œ„ํ•œ ์•ฑ์€ ์„œ๋ฒ„์—์„œ [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream)์„, ํด๋ผ์ด์–ธํŠธ์—์„œ [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. - -</Pitfall> From 1b108ffc226c55d8adfa6e956a11334b679827c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= <rpfos@naver.com> Date: Fri, 3 Jan 2025 21:02:57 +0900 Subject: [PATCH 0396/1059] docs: delete `findDomNode`, `hydrate`, `render`, `unmountComponentAtNode` for deprecation --- .../reference/react-dom/findDOMNode.md | 435 ------------------ src/content/reference/react-dom/hydrate.md | 201 -------- src/content/reference/react-dom/render.md | 218 --------- .../react-dom/unmountComponentAtNode.md | 112 ----- 4 files changed, 966 deletions(-) delete mode 100644 src/content/reference/react-dom/findDOMNode.md delete mode 100644 src/content/reference/react-dom/hydrate.md delete mode 100644 src/content/reference/react-dom/render.md delete mode 100644 src/content/reference/react-dom/unmountComponentAtNode.md diff --git a/src/content/reference/react-dom/findDOMNode.md b/src/content/reference/react-dom/findDOMNode.md deleted file mode 100644 index 26b04965d..000000000 --- a/src/content/reference/react-dom/findDOMNode.md +++ /dev/null @@ -1,435 +0,0 @@ ---- -title: findDOMNode ---- - -<Deprecated> - -์ด API๋Š” ํ–ฅํ›„ React์˜ ์ฃผ์š” ๋ฒ„์ „์—์„œ ์ œ๊ฑฐ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. [๋Œ€์•ˆ๋“ค์„ ์‚ดํŽด๋ณด์„ธ์š”.](#alternatives) - -</Deprecated> - -<Intro> - -`findDOMNode`๋Š” React์˜ [ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ](/reference/react/Component)์—์„œ ๋ธŒ๋ผ์šฐ์ €์˜ DOM ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. - -```js -const domNode = findDOMNode(componentInstance) -``` - -</Intro> - -<InlineToc /> - ---- - -## ๋ ˆํผ๋Ÿฐ์Šค {/*reference*/} - -### `findDOMNode(componentInstance)` {/*finddomnode*/} - -`findDOMNode`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ฃผ์–ด์ง„ [ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ](/reference/react/Component)์—์„œ ๋ธŒ๋ผ์šฐ์ €์˜ DOM ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. - -```js -import { findDOMNode } from 'react-dom'; - -const domNode = findDOMNode(componentInstance); -``` - -[์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) - -#### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} - -* `componentInstance`: [`์ปดํฌ๋„ŒํŠธ`](/reference/react/Component) ํ•˜์œ„ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฝ์šฐ `this`๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. - - -#### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} - -`findDOMNode`๋Š” ์ฃผ์–ด์ง„ `componentInstance`์—์„œ ๊ฐ€์žฅ ์ฒ˜์Œ ๋“ฑ์žฅํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ `null`์ด๋‚˜ `false`๋ฅผ ๋ Œ๋”๋งํ•  ๊ฒฝ์šฐ `findDOMNode`๋Š” `null`์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฌธ์ž์—ด์„ ๋ Œ๋”๋งํ•˜๋ฉด `findDOMNode`๋Š” ๊ทธ ๊ฐ’์„ ํฌํ•จํ•œ ํ…์ŠคํŠธ DOM ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - -#### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} - -* ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐฐ์—ด์ด๋‚˜ ๋‹ค์ˆ˜์˜ ์ž์‹์„ ๊ฐ€์ง„ [Fragment](/reference/react/Fragment)๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ `findDOMNode`๋Š” ํ•ด๋‹นํ•˜๋Š” DOM ๋…ธ๋“œ ์ค‘ ๋น„์–ด์žˆ์ง€ ์•Š์€ ์ฒซ ๋ฒˆ์งธ ์ž์‹์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - -* `findDOMNode`๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ๋˜์—ˆ์„ ๋•Œ(์ฆ‰, ์ปดํฌ๋„ŒํŠธ๊ฐ€ DOM์— ๋ฐฐ์น˜๋˜์—ˆ์„ ๋•Œ)๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•„์ง ๋งˆ์šดํŠธ ๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ (์˜ˆ์‹œ๋กœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๊ธฐ ์ „์ธ `render()` ๋‚ด์—์„œ `findDOMNode()`๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ) ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. - -* `findDOMNode`๋Š” ํ˜ธ์ถœํ•  ๋‹น์‹œ์˜ ๊ฒฐ๊ณผ๋งŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„์— ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค๋ฅธ ๋…ธ๋“œ๋ฅผ ๋ Œ๋”๋งํ•˜๋”๋ผ๋„, ๊ทธ ๋ณ€ํ™”์— ๋Œ€ํ•ด ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. - -* `findDOMNode`๋Š” ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. - ---- - -## ์‚ฌ์šฉ๋ฒ• {/*usage*/} - -### ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ root DOM ๋…ธ๋“œ๋ฅผ ์ฐพ๊ธฐ {/*finding-the-root-dom-node-of-a-class-component*/} - -[ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ](/reference/react/Component) ์ธ์Šคํ„ด์Šค์—์„œ `findDOMNode`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ (์ฃผ๋กœ `this`) ์ด๋ฅผ ๋ Œ๋”๋งํ•œ DOM ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. - -```js {3} -class AutoselectingInput extends Component { - componentDidMount() { - const input = findDOMNode(this); - input.select() - } - - render() { - return <input defaultValue="Hello" /> - } -} -``` - -์—ฌ๊ธฐ์„œ `input` ๋ณ€์ˆ˜๋Š” `<input>` DOM ์š”์†Œ๋ฅผ ๊ฐ’์œผ๋กœ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด์ œ ์ด๊ฒƒ์„ ํ†ตํ•ด ์ž‘์—…์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "Show example"์„ ํด๋ฆญํ•˜์—ฌ ์ž…๋ ฅ์ฐฝ์„ ๋งˆ์šดํŠธํ•˜๊ณ , [`input.select()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select)๋กœ ์ž…๋ ฅ์ฐฝ์˜ ๋ชจ๋“  ๋ฌธ์ž๋ฅผ ์„ ํƒํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. - -<Sandpack> - -```js src/App.js -import { useState } from 'react'; -import AutoselectingInput from './AutoselectingInput.js'; - -export default function App() { - const [show, setShow] = useState(false); - return ( - <> - <button onClick={() => setShow(true)}> - Show example - </button> - <hr /> - {show && <AutoselectingInput />} - </> - ); -} -``` - -```js src/AutoselectingInput.js active -import { Component } from 'react'; -import { findDOMNode } from 'react-dom'; - -class AutoselectingInput extends Component { - componentDidMount() { - const input = findDOMNode(this); - input.select() - } - - render() { - return <input defaultValue="Hello" /> - } -} - -export default AutoselectingInput; -``` - -</Sandpack> - ---- - -## ๋Œ€์•ˆ {/*alternatives*/} - -### ref๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ์˜ DOM ๋…ธ๋“œ ์ฝ๊ธฐ {/*reading-components-own-dom-node-from-a-ref*/} - -`findDOMNode`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋Š” JSX ๋…ธ๋“œ์™€ ์ด์— ํ•ด๋‹นํ•˜๋Š” ์ฝ”๋“œ ์‚ฌ์ด์˜ ์—ฐ๊ฒฐ์ด ๋ช…์‹œ์ ์ด์ง€ ์•Š์•„ ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋กœ `<input />`๋ฅผ `<div>`๋กœ ๊ฐ์‹ธ๋ณด์„ธ์š”. - -<Sandpack> - -```js src/App.js -import { useState } from 'react'; -import AutoselectingInput from './AutoselectingInput.js'; - -export default function App() { - const [show, setShow] = useState(false); - return ( - <> - <button onClick={() => setShow(true)}> - Show example - </button> - <hr /> - {show && <AutoselectingInput />} - </> - ); -} -``` - -```js src/AutoselectingInput.js active -import { Component } from 'react'; -import { findDOMNode } from 'react-dom'; - -class AutoselectingInput extends Component { - componentDidMount() { - const input = findDOMNode(this); - input.select() - } - render() { - return <input defaultValue="Hello" /> - } -} - -export default AutoselectingInput; -``` - -</Sandpack> - -์ด์ œ ์ฝ”๋“œ๊ฐ€ ๊นจ์งˆ ํ…๋ฐ, ์ฝ”๋“œ๋Š” `findDOMNode(this)`๊ฐ€ `<input>` DOM ๋…ธ๋“œ๋ฅผ ์ฐพ์„ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜๊ณ  ์žˆ์—ˆ์ง€๋งŒ ์‹ค์ œ๋กœ ์ฐพ์€ ๊ฒƒ์€ `<div>` DOM ๋…ธ๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ • DOM ๋…ธ๋“œ๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ๋Š” [`createRef`](/reference/react/createRef)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. - -์ด ์˜ˆ์‹œ์—์„  `findDOMNode`๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  `inputRef = createRef(null)`๋ฅผ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ํ•„๋“œ์— ์ •์˜ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ `this.inputRef.current`๋ฅผ ํ†ตํ•ด DOM ๋…ธ๋“œ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ JSX์— ๋ถ™์ด๋ ค๋ฉด, `<input ref={this.inputRef} />`๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ์ž‘์—…์€ DOM ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ์™€ JSX๋ฅผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. - -<Sandpack> - -```js src/App.js -import { useState } from 'react'; -import AutoselectingInput from './AutoselectingInput.js'; - -export default function App() { - const [show, setShow] = useState(false); - return ( - <> - <button onClick={() => setShow(true)}> - Show example - </button> - <hr /> - {show && <AutoselectingInput />} - </> - ); -} -``` - -```js src/AutoselectingInput.js active -import { createRef, Component } from 'react'; - -class AutoselectingInput extends Component { - inputRef = createRef(null); - - componentDidMount() { - const input = this.inputRef.current; - input.select() - } - - render() { - return ( - <input ref={this.inputRef} defaultValue="Hello" /> - ); - } -} - -export default AutoselectingInput; -``` - -</Sandpack> - -ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ตœ์‹  React์—์„œ๋Š”, [`useRef`](/reference/react/useRef)๋ฅผ ๋Œ€์‹  ํ˜ธ์ถœํ•˜์—ฌ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. - -<Sandpack> - -```js src/App.js -import { useState } from 'react'; -import AutoselectingInput from './AutoselectingInput.js'; - -export default function App() { - const [show, setShow] = useState(false); - return ( - <> - <button onClick={() => setShow(true)}> - Show example - </button> - <hr /> - {show && <AutoselectingInput />} - </> - ); -} -``` - -```js src/AutoselectingInput.js active -import { useRef, useEffect } from 'react'; - -export default function AutoselectingInput() { - const inputRef = useRef(null); - - useEffect(() => { - const input = inputRef.current; - input.select(); - }, []); - - return <input ref={inputRef} defaultValue="Hello" /> -} -``` - -</Sandpack> - -[refs๋ฅผ ์‚ฌ์šฉํ•œ DOM ์กฐ์ž‘์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด์„ธ์š”.](/learn/manipulating-the-dom-with-refs) - ---- - -### forwarded ref๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ DOM ๋…ธ๋“œ๋ฅผ ์ฝ๊ธฐ {/*reading-a-child-components-dom-node-from-a-forwarded-ref*/} - -์ด ์˜ˆ์‹œ์—์„œ๋Š” `findDOMNode(this)`๊ฐ€ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์— ์†ํ•œ DOM ๋…ธ๋“œ๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. `AutoselectingInput` ์ปดํฌ๋„ŒํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ `<input>`์„ ๋ Œ๋”๋งํ•˜๋Š” `MyInput` ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. - -<Sandpack> - -```js src/App.js -import { useState } from 'react'; -import AutoselectingInput from './AutoselectingInput.js'; - -export default function App() { - const [show, setShow] = useState(false); - return ( - <> - <button onClick={() => setShow(true)}> - Show example - </button> - <hr /> - {show && <AutoselectingInput />} - </> - ); -} -``` - -```js src/AutoselectingInput.js active -import { Component } from 'react'; -import { findDOMNode } from 'react-dom'; -import MyInput from './MyInput.js'; - -class AutoselectingInput extends Component { - componentDidMount() { - const input = findDOMNode(this); - input.select() - } - render() { - return <MyInput />; - } -} - -export default AutoselectingInput; -``` - -```js src/MyInput.js -export default function MyInput() { - return <input defaultValue="Hello" />; -} -``` - -</Sandpack> - -`AutoselectingInput` ์ปดํฌ๋„ŒํŠธ์˜ ๋‚ด๋ถ€์—์„œ `findDOMNode(this)`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, `<input>`์— ๋Œ€ํ•œ JSX๊ฐ€ `MyInput` ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ์ˆจ๊ฒจ์ ธ ์žˆ๋”๋ผ๋„ ๋ฌธ์ œ์—†์ด `<input>` DOM ๋…ธ๋“œ๋ฅผ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋™์ž‘์ด ์œ„ ์˜ˆ์‹œ์—์„œ๋Š” ํŽธ๋ฆฌํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ, ๊ฒฐ๊ตญ์€ ์ทจ์•ฝํ•œ ์ฝ”๋“œ๋กœ ๊ฐ€๋Š” ๋ฐ‘๊ฑฐ๋ฆ„์ด ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋‚˜์ค‘์— ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉฐ `MyInput`์„ `<div>`๋กœ ๊ฐ์‹ผ๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ณด์„ธ์š”. `<input>`์„ ์ฐพ์„ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜๋˜ `AutoselectingInput`์˜ ์ฝ”๋“œ๋ฅผ ๊นจ๋œจ๋ฆฌ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. - -์œ„ ์˜ˆ์‹œ์˜ `findDOMNode`๋ฅผ ๋Œ€์ฒดํ•˜๋ ค๋ฉด, ๋‘ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ˜‘๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. - -1. `AutoSelectingInput`์—์„œ๋Š” ref๋ฅผ ์„ ์–ธํ•ด์•ผ ํ•˜๊ณ , [์ด์ „์˜ ์˜ˆ์‹œ](#reading-components-own-dom-node-from-a-ref)์ฒ˜๋Ÿผ `<MyInput>`์œผ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. -2. `MyInput`์€ [`forwardRef`](/reference/react/forwardRef)๋กœ ์„ ์–ธํ•ด์•ผ ํ•˜๋ฉฐ, ํ•ด๋‹น ref๋ฅผ ๊ฐ€์ ธ์™€ `<input>` ๋…ธ๋“œ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. - -์•„๋ž˜ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋” ์ด์ƒ `findDOMNode`๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. - -<Sandpack> - -```js src/App.js -import { useState } from 'react'; -import AutoselectingInput from './AutoselectingInput.js'; - -export default function App() { - const [show, setShow] = useState(false); - return ( - <> - <button onClick={() => setShow(true)}> - Show example - </button> - <hr /> - {show && <AutoselectingInput />} - </> - ); -} -``` - -```js src/AutoselectingInput.js active -import { createRef, Component } from 'react'; -import MyInput from './MyInput.js'; - -class AutoselectingInput extends Component { - inputRef = createRef(null); - - componentDidMount() { - const input = this.inputRef.current; - input.select() - } - - render() { - return ( - <MyInput ref={this.inputRef} /> - ); - } -} - -export default AutoselectingInput; -``` - -```js src/MyInput.js -import { forwardRef } from 'react'; - -const MyInput = forwardRef(function MyInput(props, ref) { - return <input ref={ref} defaultValue="Hello" />; -}); - -export default MyInput; -``` - -</Sandpack> - -ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ ๋Œ€์‹  ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์ด๋Ÿฐ ์ฝ”๋“œ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. - -<Sandpack> - -```js src/App.js -import { useState } from 'react'; -import AutoselectingInput from './AutoselectingInput.js'; - -export default function App() { - const [show, setShow] = useState(false); - return ( - <> - <button onClick={() => setShow(true)}> - Show example - </button> - <hr /> - {show && <AutoselectingInput />} - </> - ); -} -``` - -```js src/AutoselectingInput.js active -import { useRef, useEffect } from 'react'; -import MyInput from './MyInput.js'; - -export default function AutoselectingInput() { - const inputRef = useRef(null); - - useEffect(() => { - const input = inputRef.current; - input.select(); - }, []); - - return <MyInput ref={inputRef} defaultValue="Hello" /> -} -``` - -```js src/MyInput.js -import { forwardRef } from 'react'; - -const MyInput = forwardRef(function MyInput(props, ref) { - return <input ref={ref} defaultValue="Hello" />; -}); - -export default MyInput; -``` - -</Sandpack> - ---- - -### ๊ฐ์‹ธ์ฃผ๋Š” `<div>` ์š”์†Œ ์ถ”๊ฐ€ํ•˜๊ธฐ {/*adding-a-wrapper-div-element*/} - -์ปดํฌ๋„ŒํŠธ๋Š” ์ข…์ข… ์ž์‹์˜ ์œ„์น˜์™€ ํฌ๊ธฐ๋ฅผ ์•Œ์•„์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋•Œ๋ฌธ์— `findDOMNode(this)`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž์‹๋“ค์„ ์ฐพ๊ณ , ์ธก์ •์„ ์œ„ํ•ด [`getBoundingClientRect`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect)์™€ ๊ฐ™์€ DOM ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. - -์ด๋Ÿฌํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ง์ ‘์ ์œผ๋กœ ๋Œ€์‘๋˜๋Š” ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— `findDOMNode`๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ์—๋„ React์—์„œ ์™„์ „ํžˆ ์‚ฌ๋ผ์ง€์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋™์•ˆ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ฝ˜ํ…์ธ  ์ฃผ์œ„๋ฅผ `<div>` ๋…ธ๋“œ๋กœ ๊ฐ์‹ธ์ฃผ๊ณ , ๊ทธ ๋…ธ๋“œ์˜ ref๋ฅผ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ์‹ธ๋Š” ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์Šคํƒ€์ผ์„ ์†์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -```js -<div ref={someRef}> - {children} -</div> -``` - -์ด๋Š” ํŠน์ • ํ•ญ๋ชฉ์— ์ดˆ์ ์„ ๋งž์ถ”๊ณ  ์Šคํฌ๋กค์„ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. diff --git a/src/content/reference/react-dom/hydrate.md b/src/content/reference/react-dom/hydrate.md deleted file mode 100644 index 9d0a90fc8..000000000 --- a/src/content/reference/react-dom/hydrate.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -title: hydrate ---- - -<Deprecated> - -์ด API๋Š” ํ–ฅํ›„ React์˜ ์ฃผ์š” ๋ฒ„์ „์—์„œ ์ œ๊ฑฐ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. - -`hydrate`๋Š” React 18์—์„œ [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋กœ ๋ฐ”๋€Œ์—ˆ์Šต๋‹ˆ๋‹ค. React 18์—์„œ `hydrate`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•ฑ์ด React 17์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•  ๊ฒƒ์ด๋ผ๋Š” ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ [์—ฌ๊ธฐ](/blog/2022/03/08/react-18-upgrade-guide#updates-to-client-rendering-apis)๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”. - -</Deprecated> - -<Intro> - -React 17 ์ดํ•˜์—์„œ, `hydrate`๋Š” [`react-dom/server`](/reference/react-dom/server)๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋œ React ์ปดํฌ๋„ŒํŠธ์˜ HTML ์ฝ˜ํ…์ธ ๋ฅผ ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ์— ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. - -```js -hydrate(reactNode, domNode, callback?) -``` - -</Intro> - -<InlineToc /> - ---- - -## ๋ ˆํผ๋Ÿฐ์Šค {/*reference*/} - -### `hydrate(reactNode, domNode, callback?)` {/*hydrate*/} - -React 17 ์ดํ•˜์—์„œ `hydrate`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด React๊ฐ€ ์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ ๋ฏธ๋ฆฌ ๋ Œ๋”๋งํ•œ HTML์— React๋ฅผ ์—ฐ๊ฒฐ(attach)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -```js -import { hydrate } from 'react-dom'; - -hydrate(reactNode, domNode); -``` - -React๋Š” `domNode`์— ์žˆ๋Š” HTML์— ์—ฐ๊ฒฐ๋˜๊ณ , ๊ทธ ๋‚ด๋ถ€์˜ DOM ๊ด€๋ฆฌ๋ฅผ ๋งก์Šต๋‹ˆ๋‹ค. React๋กœ ๋นŒ๋“œ๋œ ์•ฑ์€ ๋ณดํ†ต `hydrate`๋ฅผ ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋”ฑ ํ•œ ๋ฒˆ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. - -[๋” ๋‹ค์–‘ํ•œ ์˜ˆ์‹œ๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”.](#usage) - -#### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} - -* `reactNode`: HTML์„ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” React ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. React 17์˜ `renderToString(<App />)`๊ฐ™์€ `ReactDOM Server` ๋ฉ”์„œ๋“œ๋กœ ๋ Œ๋”๋ง ๋œ `<App />`์ฒ˜๋Ÿผ, ์ผ๋ฐ˜์ ์œผ๋กœ JSX ์กฐ๊ฐ ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค. - -* `domNode`: ์„œ๋ฒ„์—์„œ ๋ฃจํŠธ ์š”์†Œ๋กœ ๋ Œ๋”๋ง ๋œ [DOM ์š”์†Œ](https://developer.mozilla.org/en-US/docs/Web/API/Element)์ž…๋‹ˆ๋‹ค. - -* **optional**: `callback`: ์ปดํฌ๋„ŒํŠธ๊ฐ€ hydrate ๋œ ํ›„ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. - -#### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} - -`hydrate`๋Š” null์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - -#### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} -* `hydrate`๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง ๋œ ์ฝ˜ํ…์ธ ๊ฐ€ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋œ ์ฝ˜ํ…์ธ ์™€ ๋™์ผํ•  ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ์ฝ˜ํ…์ธ ์˜ ์ฐจ์ด ์ •๋„๋Š” React๊ฐ€ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๊ธด ํ•˜์ง€๋งŒ, ๋ถˆ์ผ์น˜๋Š” ๋ฒ„๊ทธ๋กœ ๊ฐ„์ฃผํ•˜๊ณ  ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -* ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ React๋Š” hydration ์ค‘ ์ผ์–ด๋‚œ ๋ถˆ์ผ์น˜์— ๋Œ€ํ•ด ๊ฒฝ๊ณ ํ•ฉ๋‹ˆ๋‹ค. ๋ถˆ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์ฐจ์ด๊ฐ€ ์กฐ์ •๋œ๋‹ค๋Š” ๋ณด์žฅ์€ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์„ฑ๋Šฅ์ƒ์˜ ์ด์œ ๋กœ ์ค‘์š”ํ•œ๋ฐ, ๋Œ€๋ถ€๋ถ„์˜ ์•ฑ์—์„œ ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๋“œ๋ฌผ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๋งˆํฌ์—…์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐ ์—„์ฒญ๋‚œ ๋น„์šฉ์ด ๋“ค๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. -* ๊ฐ ์•ฑ์—์„œ `hydrate`๋Š” ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰ํ•˜์„ธ์š”. ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋Œ€์‹  ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -* ์•ฑ์ด ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋œ HTML ์—†์ด ํด๋ผ์ด์–ธํŠธ์—์„œ๋งŒ ๋ Œ๋”๋ง ๋˜๋Š” ๊ฒฝ์šฐ์—” `hydrate()`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿด ๋•Œ๋Š” [render()](/reference/react-dom/render)(React 17 ์ดํ•˜) ๋˜๋Š” [createRoot()](/reference/react-dom/client/createRoot)(React 18+)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. - ---- - -## ์‚ฌ์šฉ๋ฒ• {/*usage*/} - -`hydrate`๋กœ <CodeStep step={1}>React ์ปดํฌ๋„ŒํŠธ</CodeStep>๋ฅผ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋œ <CodeStep step={2}>๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ</CodeStep>์— ์—ฐ๊ฒฐํ•˜์„ธ์š”. - -```js [[1, 3, "<App />"], [2, 3, "document.getElementById('root')"]] -import { hydrate } from 'react-dom'; - -hydrate(<App />, document.getElementById('root')); -``` - -`hydrate()`๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ๋งŒ ๋™์ž‘ํ•˜๋Š” (์„œ๋ฒ„ ์ธก์—์„œ ๋ Œ๋”๋ง ๋˜๋Š” HTML์ด ์—†๋Š”) ์•ฑ์„ ๋งŒ๋“ค ์ˆœ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿด ๋•Œ๋Š” [render()](/reference/react-dom/render)(React 17 ์ดํ•˜) ๋˜๋Š” [createRoot()](/reference/react-dom/client/createRoot)(React 18+)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. - -### ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋œ HTML Hydrate ํ•˜๊ธฐ {/*hydrating-server-rendered-html*/} - -React์—์„œ "hydration"์€ React๊ฐ€ ์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ ๋ฏธ๋ฆฌ ๋ Œ๋”๋งํ•œ HTML์— ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ์‹์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ hydration์ด ์ผ์–ด๋‚˜๋ฉด React๋Š” ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ ๋งˆํฌ์—…์— ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ์•ฑ ๋ Œ๋”๋ง์„ ์ด์–ด๋ฐ›์œผ๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. - -React๋กœ ๋นŒ๋“œ๋œ ์•ฑ์—์„œ๋Š” **๋ณดํ†ต ์•ฑ์ด ์‹œ์ž‘๋  ๋•Œ ๋‹จ ํ•œ ๋ฒˆ ํ•˜๋‚˜์˜ ๋ฃจํŠธ๋งŒ hydate ํ•ฉ๋‹ˆ๋‹ค**. - -<Sandpack> - -```html public/index.html -<!-- - <div id="root">...</div> ๋‚ด์˜ HTML ์ฝ˜ํ…์ธ ๋Š” - react-dom/server์„ ํ†ตํ•ด App์œผ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ---> -<div id="root"><h1>Hello, world!</h1></div> -``` - -```js src/index.js active -import './styles.css'; -import { hydrate } from 'react-dom'; -import App from './App.js'; - -hydrate(<App />, document.getElementById('root')); -``` - -```js src/App.js -export default function App() { - return <h1>Hello, world!</h1>; -} -``` - -</Sandpack> - -๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ `hydrate`๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋” ํ˜ธ์ถœํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. React๋Š” `hydrate`๊ฐ€ ํ˜ธ์ถœ๋œ ์‹œ์ ๋ถ€ํ„ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ DOM์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. UI๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•œ๋‹ค๋ฉด [state๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.](/reference/react/useState) - -hydration์— ๋Œ€ํ•œ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ [`hydrateRoot` ๋ฌธ์„œ](/reference/react-dom/client/hydrateRoot)๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”. - ---- - -### ๋ถˆ๊ฐ€ํ”ผํ•œ hydration ๋ถˆ์ผ์น˜ ์—๋Ÿฌ ๋ฌด์‹œํ•˜๊ธฐ {/*suppressing-unavoidable-hydration-mismatch-errors*/} - -๋‹จ์ผ ์š”์†Œ์˜ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋‚˜ ํ…์ŠคํŠธ ์ฝ˜ํ…์ธ ๊ฐ€ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„ ๋‹ค๋ฅผ ์ˆ˜๋ฐ–์— ์—†๋Š” ๊ฒฝ์šฐ(์˜ˆ: ํƒ€์ž„์Šคํƒฌํ”„), hydration ๋ถˆ์ผ์น˜ ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์‹œํ•˜๋„๋ก ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -hydration ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์‹œํ•˜๋ ค๋ฉด `suppressHydrationWarning={true}`๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”. - -<Sandpack> - -```html public/index.html -<!-- - <div id="root">...</div> ๋‚ด์˜ HTML ์ฝ˜ํ…์ธ ๋Š” - react-dom/server์„ ํ†ตํ•ด App์œผ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ---> -<div id="root"><h1>Current Date: 01/01/2020</h1></div> -``` - -```js src/index.js -import './styles.css'; -import { hydrate } from 'react-dom'; -import App from './App.js'; - -hydrate(<App />, document.getElementById('root')); -``` - -```js src/App.js active -export default function App() { - return ( - <h1 suppressHydrationWarning={true}> - Current Date: {new Date().toLocaleDateString()} - </h1> - ); -} -``` - -</Sandpack> - -์ด ๋ฐฉ๋ฒ•์€ ํ•œ ๋ ˆ๋ฒจ ๊นŠ์ด์—์„œ๋งŒ ์ž‘๋™ํ•˜๋ฉฐ ์ž„์‹œ๋ฐฉํŽธ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ์ฝ˜ํ…์ธ ๊ฐ€ ์•„๋‹Œ ์ด์ƒ React๋Š” ์กฐ์ •์„ ์‹œ๋„ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ฏ€๋กœ ํ–ฅํ›„ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์„ ๋•Œ๊นŒ์ง€ ์ผ๊ด€์ ์ด์ง€ ์•Š์€ ์ƒํƒœ๋กœ ๋‚จ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚จ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”. - ---- - -### ์„œ๋กœ ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ ๋ฐ ์„œ๋ฒ„ ์ฝ˜ํ…์ธ  ์ฒ˜๋ฆฌํ•˜๊ธฐ {/*handling-different-client-and-server-content*/} - -์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์˜๋„์ ์œผ๋กœ ๋‹ค๋ฅธ ๊ฒƒ์„ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒฝ์šฐ, ํˆฌ ํŒจ์Šค ๋ Œ๋”๋ง(two-pass rendering)์„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `isClient` ๊ฐ™์€ [state variable](/reference/react/useState)๋ฅผ ์„ ์–ธํ•ด [Effect](/reference/react/useEffect)์—์„œ `true`๋กœ ๋ฐ”๊ฟ” ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. - -<Sandpack> - -```html public/index.html -<!-- - <div id="root">...</div> ๋‚ด์˜ HTML ์ฝ˜ํ…์ธ ๋Š” - react-dom/server์„ ํ†ตํ•ด App์œผ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ---> -<div id="root"><h1>Is Server</h1></div> -``` - -```js src/index.js -import './styles.css'; -import { hydrate } from 'react-dom'; -import App from './App.js'; - -hydrate(<App />, document.getElementById('root')); -``` - -```js src/App.js active -import { useState, useEffect } from "react"; - -export default function App() { - const [isClient, setIsClient] = useState(false); - - useEffect(() => { - setIsClient(true); - }, []); - - return ( - <h1> - {isClient ? 'Is Client' : 'Is Server'} - </h1> - ); -} -``` - -</Sandpack> - -์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฒซ ๋ฒˆ์งธ ๋ Œ๋”๋ง ํŒจ์Šค(render pass)์—์„œ ์„œ๋ฒ„์™€ ๊ฐ™์€ ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•˜๋ฏ€๋กœ ๋ถˆ์ผ์น˜๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์œผ๋ฉด์„œ๋„, hydration ์งํ›„ ์ถ”๊ฐ€ ๋ Œ๋”๋ง ํŒจ์Šค๊ฐ€ ๋™๊ธฐ์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -<Pitfall> - -์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‘ ๋ฒˆ ๋ Œ๋”๋ง ๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ hydration ์†๋„๊ฐ€ ๋А๋ ค์ง‘๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋Š” ์ดˆ๊ธฐ HTML ๋ Œ๋”๋ง๋ณด๋‹ค ์ƒ๋‹นํžˆ ๋Šฆ๊ฒŒ ๋กœ๋“œ๋  ์ˆ˜ ์žˆ๊ณ , hydration ์งํ›„์— ๋‹ค๋ฅธ UI๋ฅผ ๋ Œ๋”๋งํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์–ด์ƒ‰ํ•˜๊ฒŒ ๋А๋‚„ ์—ฌ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธํ„ฐ๋„ท ์†๋„๊ฐ€ ๋А๋ฆฐ ์‚ฌ์šฉ์ž์˜ ๊ฒฝํ—˜์— ์œ ์˜ํ•˜์„ธ์š”. - -</Pitfall> diff --git a/src/content/reference/react-dom/render.md b/src/content/reference/react-dom/render.md deleted file mode 100644 index 24cfb26b6..000000000 --- a/src/content/reference/react-dom/render.md +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: ๋ Œ๋”๋งํ•˜๊ธฐ ---- - -<Deprecated> - -์ด API๋Š” ํ–ฅํ›„ React ๋ฉ”์ด์ € ๋ฒ„์ „์—์„œ ์‚ญ์ œ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. - -React 18์—์„œ `render`๋Š” [`createRoot`](/reference/react-dom/client/createRoot)๋กœ ๊ต์ฒด๋˜์—ˆ์Šต๋‹ˆ๋‹ค. React 18์—์„œ `render`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•ฑ์ด React 17์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋ฏ€๋กœ ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ [ํด๋ผ์ด์–ธํŠธ ๋ Œ๋”๋ง API ์—…๋ฐ์ดํŠธ](/blog/2022/03/08/react-18-upgrade-guide#updates-to-client-rendering-apis)๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. - -</Deprecated> - -<Intro> - -`render`๋Š” [JSX](/learn/writing-markup-with-jsx) ("React node")๋ฅผ ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. - -```js -render(reactNode, domNode, callback?) -``` - -</Intro> - -<InlineToc /> - ---- - -## ๋ ˆํผ๋Ÿฐ์Šค {/*reference*/} - -### `render(reactNode, domNode, callback?)` {/*render*/} - -React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ธŒ๋ผ์šฐ์ € DOM ์š”์†Œ ๋‚ด์— ํ‘œ์‹œํ•˜๋ ค๋ฉด `render`๋ฅผ ํ˜ธ์ถœํ•˜์„ธ์š”. - -```js -import { render } from 'react-dom'; - -const domNode = document.getElementById('root'); -render(<App />, domNode); -``` - -React๋Š” `domNode` ๋‚ด์— `<App />`์„ ํ‘œ์‹œํ•˜๊ณ  ํ•ด๋‹น DOM์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. - -๋ณดํ†ต React๋กœ ์™„์ „ํžˆ ๊ตฌ์ถ•๋œ ์•ฑ์€ `render`๋ฅผ ์ตœ์ƒ ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ๊ป˜ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์ง€์˜ "์ผ๋ถ€๋ถ„"์— React๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ•„์š”ํ•œ ๋งŒํผ `render`๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -[์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) - -#### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} - -* `reactNode`: ํ‘œ์‹œํ•˜๋ ค๋Š” *React node*์ž…๋‹ˆ๋‹ค. ๋ณดํ†ต `<App />`๊ณผ ๊ฐ™์€ JSX๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ [`createElement()`](/reference/react/createElement)๋กœ ๊ตฌ์„ฑ๋œ React ์š”์†Œ, ๋ฌธ์ž์—ด, ์ˆซ์ž, `null`, ๋˜๋Š” `undefined`๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -* `domNode`: [DOM ์š”์†Œ](https://developer.mozilla.org/ko/docs/Web/API/Element)์ž…๋‹ˆ๋‹ค. React๋Š” ์ „๋‹ฌํ•œ `reactNode`๋ฅผ ์ด DOM ์š”์†Œ ๋‚ด์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„๋กœ React๋Š” `domNode` ๋‚ด๋ถ€์˜ DOM์„ ๊ด€๋ฆฌํ•˜๊ณ  React ํŠธ๋ฆฌ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. - -* **optional** `callback`: ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ „๋‹ฌํ•˜๋ฉด React๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ DOM์— ๋ฐฐ์น˜๋œ ํ›„์— ์ด๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. - - -#### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} - -`render`๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ `null`์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ „๋‹ฌํ•œ `reactNode`๊ฐ€ *ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ*์ธ ๊ฒฝ์šฐ, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - -#### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} - -* React 18์—์„œ `render`๋Š” [`createRoot`](/reference/react-dom/client/createRoot)๋กœ ๊ต์ฒด๋˜์—ˆ์Šต๋‹ˆ๋‹ค. React 18 ์ด์ƒ์—์„œ๋Š” `createRoot`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. - -* ์ฒ˜์Œ `render`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด React๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ธฐ ์ „์— ํ•ด๋‹น `domNode` ๋‚ด ์กด์žฌํ•˜๋Š” HTML์„ ๋ชจ๋‘ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ํ˜น์€ ๋นŒ๋“œ ์ค‘์— React์— ์˜ํ•ด ์ƒ์„ฑ๋œ HTML์ด `domNode`์— ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด ๊ธฐ์กด HTML์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” [`hydrate()`](/reference/react-dom/hydrate)๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•˜์„ธ์š”. - -* ๋™์ผํ•œ `domNode`์—์„œ `render`๋ฅผ ๋‘ ๋ฒˆ ์ด์ƒ ํ˜ธ์ถœํ•˜๋ฉด React๋Š” ์ตœ์‹  JSX๋ฅผ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋งŒํผ DOM์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. React๋Š” ์ด์ „์— ๋ Œ๋”๋ง ๋œ ํŠธ๋ฆฌ์™€ ["๋งž์ถฐ๋ณด๋ฉฐ"](/learn/preserving-and-resetting-state) ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” DOM ๋ถ€๋ถ„๊ณผ ์žฌ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š” DOM ๋ถ€๋ถ„์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ `domNode`์— `render`๋ฅผ ์žฌํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ์ตœ์ƒ๋‹จ ์ปดํฌ๋„ŒํŠธ์—์„œ [`set` ํ•จ์ˆ˜](/reference/react/useState#setstate)๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. React๋Š” ๋ถˆํ•„์š”ํ•œ DOM ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. - -* ์•ฑ ์ „์ฒด๊ฐ€ React๋กœ ๊ตฌ์ถ•๋œ ๊ฒฝ์šฐ, `render` ํ˜ธ์ถœ์€ ์•ฑ์—์„œ ํ•œ ๋ฒˆ๋งŒ ๋ฐœ์ƒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. (ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ์ด ํ˜ธ์ถœ์„ ๋Œ€์‹  ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค) ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ DOM ํŠธ๋ฆฌ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„(์˜ˆ์‹œ: ๋ชจ๋‹ฌ ๋˜๋Š” ํˆดํŒ)์— JSX๋ฅผ ๋ Œ๋”๋งํ•˜๋ ค๋ฉด `render` ๋Œ€์‹  [`createPortal`](/reference/react-dom/createPortal)์„ ์‚ฌ์šฉํ•˜์„ธ์š”. - ---- - -## ์‚ฌ์šฉ๋ฒ• {/*usage*/} - -<CodeStep step={1}>React ์ปดํฌ๋„ŒํŠธ</CodeStep>๋ฅผ <CodeStep step={2}>๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ</CodeStep> ์•ˆ์— ํ‘œ์‹œํ•˜๋ ค๋ฉด `render`๋ฅผ ํ˜ธ์ถœํ•˜์„ธ์š”. - -```js [[1, 4, "<App />"], [2, 4, "document.getElementById('root')"]] -import { render } from 'react-dom'; -import App from './App.js'; - -render(<App />, document.getElementById('root')); -``` - -### ์ตœ์ƒ๋‹จ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋งํ•˜๊ธฐ {/*rendering-the-root-component*/} - -React๋กœ ์™„์ „ํžˆ ๊ตฌ์ถ•๋œ ์•ฑ์—์„œ๋Š” "์ตœ์ƒ๋‹จ('root')" ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด--**์ผ๋ฐ˜์ ์œผ๋กœ ์‹œ์ž‘ํ•  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.** - -<Sandpack> - -```js src/index.js active -import './styles.css'; -import { render } from 'react-dom'; -import App from './App.js'; - -render(<App />, document.getElementById('root')); -``` - -```js src/App.js -export default function App() { - return <h1>Hello, world!</h1>; -} -``` - -</Sandpack> - -๋ณดํ†ต `render`๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๊ณณ์—์„œ ํ˜ธ์ถœํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ด ์‹œ์ ๋ถ€ํ„ฐ React๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ DOM์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. UI๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ ค๋ฉด ์ปดํฌ๋„ŒํŠธ์—์„œ [state๋ฅผ ์‚ฌ์šฉ](/reference/react/useState)ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. - ---- - -### ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ตœ์ƒ๋‹จ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋งํ•˜๊ธฐ {/*rendering-multiple-roots*/} - -[์™„์ „ํžˆ React๋กœ ๊ตฌ์ถ•๋œ](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page) ํŽ˜์ด์ง€๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด React๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ์ตœ์ƒ์œ„ UI๋งˆ๋‹ค `render`๋ฅผ ํ˜ธ์ถœํ•˜์„ธ์š”. - -<Sandpack> - -```html public/index.html -<nav id="navigation"></nav> -<main> - <p>This paragraph is not rendered by React (open index.html to verify).</p> - <section id="comments"></section> -</main> -``` - -```js src/index.js active -import './styles.css'; -import { render } from 'react-dom'; -import { Comments, Navigation } from './Components.js'; - -render( - <Navigation />, - document.getElementById('navigation') -); - -render( - <Comments />, - document.getElementById('comments') -); -``` - -```js src/Components.js -export function Navigation() { - return ( - <ul> - <NavLink href="/">Home</NavLink> - <NavLink href="/about">About</NavLink> - </ul> - ); -} - -function NavLink({ href, children }) { - return ( - <li> - <a href={href}>{children}</a> - </li> - ); -} - -export function Comments() { - return ( - <> - <h2>Comments</h2> - <Comment text="Hello!" author="Sophie" /> - <Comment text="How are you?" author="Sunil" /> - </> - ); -} - -function Comment({ text, author }) { - return ( - <p>{text} โ€” <i>{author}</i></p> - ); -} -``` - -```css -nav ul { padding: 0; margin: 0; } -nav ul li { display: inline-block; margin-right: 20px; } -``` - -</Sandpack> - -[`unmountComponentAtNode()`](/reference/react-dom/unmountComponentAtNode)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋ง ๋œ ํŠธ๋ฆฌ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ---- - -### ๋ Œ๋”๋ง ๋œ ํŠธ๋ฆฌ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ {/*updating-the-rendered-tree*/} - -๋™์ผํ•œ DOM ๋…ธ๋“œ์—์„œ `render`๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์— ๋ Œ๋”๋ง ๋œ ๊ตฌ์กฐ์™€ ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ๊ฐ€ ์ผ์น˜ํ•œ๋‹ค๋ฉด React๋Š” [state๋ฅผ ๋ณด์กด](/learn/preserving-and-resetting-state)ํ•ฉ๋‹ˆ๋‹ค. - -<Sandpack> - -```js src/index.js active -import { render } from 'react-dom'; -import './styles.css'; -import App from './App.js'; - -let i = 0; -setInterval(() => { - render( - <App counter={i} />, - document.getElementById('root') - ); - i++; -}, 1000); -``` - -```js src/App.js -export default function App({counter}) { - return ( - <> - <h1>Hello, world! {counter}</h1> - <input placeholder="Type something here" /> - </> - ); -} -``` - -</Sandpack> - -`render`๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณดํ†ต ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ [์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ](/reference/react/useState)ํ•ฉ๋‹ˆ๋‹ค. diff --git a/src/content/reference/react-dom/unmountComponentAtNode.md b/src/content/reference/react-dom/unmountComponentAtNode.md deleted file mode 100644 index 0ed8e433d..000000000 --- a/src/content/reference/react-dom/unmountComponentAtNode.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: unmountComponentAtNode ---- - -<Deprecated> - -์ด API๋Š” ํ–ฅํ›„ React์˜ ์ฃผ์š” ๋ฒ„์ „์—์„œ ์ œ๊ฑฐ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. - -React 18์—์„œ `unmountComponentAtNode`๋Š” [`root.unmount()`](/reference/react-dom/client/createRoot#root-unmount)๋กœ ๊ต์ฒด๋˜์—ˆ์Šต๋‹ˆ๋‹ค. - -</Deprecated> - -<Intro> - -`unmountComponentAtNode`๋Š” DOM์— ๋งˆ์šดํŠธ๋œ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. - -```js -unmountComponentAtNode(domNode) -``` - -</Intro> - -<InlineToc /> - ---- - -## ๋ ˆํผ๋Ÿฐ์Šค {/*reference*/} - -### `unmountComponentAtNode(domNode)` {/*unmountcomponentatnode*/} - -`unmountComponentAtNode`๋ฅผ ํ˜ธ์ถœํ•ด์„œ DOM์— ๋งˆ์šดํŠธ๋œ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๊ด€๋ จ๋œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์™€ state๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. - -```js -import { unmountComponentAtNode } from 'react-dom'; - -const domNode = document.getElementById('root'); -render(<App />, domNode); - -unmountComponentAtNode(domNode); -``` - -[์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.](#usage) - -#### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} - -* `domNode`: [DOM ์—˜๋ฆฌ๋จผํŠธ์ž…๋‹ˆ๋‹ค.](https://developer.mozilla.org/en-US/docs/Web/API/Element) React๋Š” ์ด ์—˜๋ฆฌ๋จผํŠธ์— ๋งˆ์šดํŠธ๋œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. - -#### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} - -`unmountComponentAtNode`๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋˜๋ฉด `true`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด `false`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - ---- - -## ์‚ฌ์šฉ๋ฒ• {/*usage*/} - -`unmountComponentAtNode`๋ฅผ ํ˜ธ์ถœํ•ด์„œ <CodeStep step={2}>๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ</CodeStep>์—์„œ <CodeStep step={1}>๋งˆ์šดํŠธ๋œ React ์ปดํฌ๋„ŒํŠธ</CodeStep>๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๊ด€๋ จ๋œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์™€ state๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. - -```js [[1, 5, "<App />"], [2, 5, "rootNode"], [2, 8, "rootNode"]] -import { render, unmountComponentAtNode } from 'react-dom'; -import App from './App.js'; - -const rootNode = document.getElementById('root'); -render(<App />, rootNode); - -// ... -unmountComponentAtNode(rootNode); -``` - -### DOM ์—˜๋ฆฌ๋จผํŠธ์—์„œ React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ œ๊ฑฐํ•˜๊ธฐ {/*removing-a-react-app-from-a-dom-element*/} - -๋•Œ๋•Œ๋กœ ๊ธฐ์กด ํŽ˜์ด์ง€๋‚˜ ์ผ๋ถ€๋งŒ React๋กœ ์ž‘์„ฑ๋œ ํŽ˜์ด์ง€์—์„œ React๋ฅผ "ํฌํ•จ"ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ ๋ Œ๋”๋ง ๋œ DOM ๋…ธ๋“œ์—์„œ UI์™€ state ๋ฐ ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋ชจ๋‘ ์ œ๊ฑฐํ•ด์„œ React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ "์ค‘์ง€"ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - -์•„๋ž˜ ์˜ˆ์‹œ์—์„œ๋Š” "Render React App"์„ ํด๋ฆญํ•˜๋ฉด React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. "Unmount React App"์„ ํด๋ฆญํ•˜๋ฉด React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. - -<Sandpack> - -```html index.html -<!DOCTYPE html> -<html> - <head><title>My app - - - - -
- - -``` - -```js src/index.js active -import './styles.css'; -import { render, unmountComponentAtNode } from 'react-dom'; -import App from './App.js'; - -const domNode = document.getElementById('root'); - -document.getElementById('render').addEventListener('click', () => { - render(, domNode); -}); - -document.getElementById('unmount').addEventListener('click', () => { - unmountComponentAtNode(domNode); -}); -``` - -```js src/App.js -export default function App() { - return

Hello, world!

; -} -``` - - From c5ed7b8972bed810e962aea411a6e9594975b47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Fri, 3 Jan 2025 21:06:30 +0900 Subject: [PATCH 0397/1059] docs: update `client/index.md` --- src/content/reference/react-dom/client/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/reference/react-dom/client/index.md b/src/content/reference/react-dom/client/index.md index 498d78760..16bbf609a 100644 --- a/src/content/reference/react-dom/client/index.md +++ b/src/content/reference/react-dom/client/index.md @@ -4,7 +4,7 @@ title: Client React DOM APIs -`react-dom/client` API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์—์„œ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋ง ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ API๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์•ฑ์˜ ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ React ํŠธ๋ฆฌ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. [ํ”„๋ ˆ์ž„์›Œํฌ](/learn/start-a-new-react-project#production-grade-react-frameworks)๊ฐ€ ๋Œ€์‹  ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ปดํฌ๋„ŒํŠธ๋Š” ์ด๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. +`react-dom/client` API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์—์„œ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋ง ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ API๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์•ฑ์˜ ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ React ํŠธ๋ฆฌ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. [ํ”„๋ ˆ์ž„์›Œํฌ](/learn/start-a-new-react-project#production-grade-react-frameworks)๊ฐ€ ๋Œ€์‹  ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ปดํฌ๋„ŒํŠธ๋Š” ์ด๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. --- @@ -12,7 +12,7 @@ title: Client React DOM APIs ## Client APIs {/*client-apis*/} * [`createRoot`](/reference/react-dom/client/createRoot)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ ์•ˆ์— React ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฃจํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -* [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด์ „์— [`react-dom/server`.](/reference/react-dom/server)์— ์˜ํ•ด ์ƒ์„ฑ๋œ HTML ์ฝ˜ํ…์ธ ๊ฐ€ ์žˆ๋Š” ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ ์•ˆ์— React ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +* [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด์ „์— [`react-dom/server`](/reference/react-dom/server)์— ์˜ํ•ด ์ƒ์„ฑ๋œ HTML ์ฝ˜ํ…์ธ ๊ฐ€ ์žˆ๋Š” ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ ์•ˆ์— React ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --- ## ์ง€์› ๋ธŒ๋ผ์šฐ์ € {/*browser-support*/} From 77e99b60dfe178b1a9e8c129e9a844372ac85bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sat, 4 Jan 2025 01:23:54 +0900 Subject: [PATCH 0398/1059] docs: update `createRoot.md` --- .../reference/react-dom/client/createRoot.md | 57 +++++++++++-------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index 6a8435aa3..584020571 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -36,25 +36,17 @@ root.render(); ์˜จ์ „ํžˆ React๋งŒ์œผ๋กœ ์ž‘์„ฑ๋œ ์•ฑ์—์„œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ `createRoot` ํ˜ธ์ถœ์ด ํ•˜๋‚˜๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค. ํŽ˜์ด์ง€์˜ ์ผ๋ถ€์— React๋ฅผ "๋ฟŒ๋ ค์„œ" ์‚ฌ์šฉํ•˜๋Š” ํŽ˜์ด์ง€์˜ ๊ฒฝ์šฐ์—๋Š” ๋ฃจํŠธ๋ฅผ ํ•„์š”๋กœ ํ•˜๋Š” ๋งŒํผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -[์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.](#usage) +[์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} -* `domNode`: [DOM ์—˜๋ฆฌ๋จผํŠธ.](https://developer.mozilla.org/en-US/docs/Web/API/Element) React๋Š” DOM ์—˜๋ฆฌ๋จผํŠธ์— ๋Œ€ํ•œ ๋ฃจํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ Œ๋”๋ง๋œ React ์ฝ˜ํ…์ธ ๋ฅผ ํ‘œ์‹œํ•˜๋Š” `render`์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ๋ฃจํŠธ์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. +* `domNode`: [DOM ์—˜๋ฆฌ๋จผํŠธ](https://developer.mozilla.org/en-US/docs/Web/API/Element). React๋Š” DOM ์—˜๋ฆฌ๋จผํŠธ์— ๋Œ€ํ•œ ๋ฃจํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ Œ๋”๋ง๋œ React ์ฝ˜ํ…์ธ ๋ฅผ ํ‘œ์‹œํ•˜๋Š” `render`์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ๋ฃจํŠธ์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. * **optional** `options`: React ๋ฃจํŠธ์— ๋Œ€ํ•œ ์˜ต์…˜์„ ๊ฐ€์ง„ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. - -<<<<<<< HEAD - * **optional** `onCaughtError`: Callback called when React catches an error in an Error Boundary. Called with the `error` caught by the Error Boundary, and an `errorInfo` object containing the `componentStack`. - * **optional** `onUncaughtError`: Callback called when an error is thrown and not caught by an Error Boundary. Called with the `error` that was thrown, and an `errorInfo` object containing the `componentStack`. - * **optional** `onRecoverableError`: React๊ฐ€ ์˜ค๋ฅ˜๋กœ๋ถ€ํ„ฐ ์ž๋™์œผ๋กœ ๋ณต๊ตฌ๋  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑ. - * **optional** `identifierPrefix` : React๊ฐ€ [`useId`](/reference/react/useId)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ID์— ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ ‘๋‘์‚ฌ. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฃจํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•˜๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. -======= * **optional** `onCaughtError`: Callback called when React catches an error in an Error Boundary. Called with the `error` caught by the Error Boundary, and an `errorInfo` object containing the `componentStack`. * **optional** `onUncaughtError`: Callback called when an error is thrown and not caught by an Error Boundary. Called with the `error` that was thrown, and an `errorInfo` object containing the `componentStack`. - * **optional** `onRecoverableError`: Callback called when React automatically recovers from errors. Called with an `error` React throws, and an `errorInfo` object containing the `componentStack`. Some recoverable errors may include the original error cause as `error.cause`. - * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc + * **optional** `onRecoverableError`: React๊ฐ€ ์˜ค๋ฅ˜๋กœ๋ถ€ํ„ฐ ์ž๋™์œผ๋กœ ๋ณต๊ตฌ๋  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑ. Called with an `error` React throws, and an `errorInfo` object containing the `componentStack`. Some recoverable errors may include the original error cause as `error.cause`. + * **optional** `identifierPrefix`: React๊ฐ€ [`useId`](/reference/react/useId)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ID์— ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ ‘๋‘์‚ฌ. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฃจํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•˜๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} @@ -69,7 +61,7 @@ root.render(); ### `root.render(reactNode)` {/*root-render*/} -`root.render`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ [JSX](/learn/writing-markup-with-jsx)์กฐ๊ฐ("React ๋…ธ๋“œ")์„ React ๋ฃจํŠธ์˜ ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. +`root.render`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ [JSX](/learn/writing-markup-with-jsx) ์กฐ๊ฐ("React ๋…ธ๋“œ")์„ React ๋ฃจํŠธ์˜ ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ```js root.render(); @@ -77,7 +69,7 @@ root.render(); React๋Š” `root`์— ``์„ ํ‘œ์‹œํ•˜๊ณ  ๊ทธ ์•ˆ์— ์žˆ๋Š” DOM์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. -[์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.](#usage) +[์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*root-render-parameters*/} @@ -110,7 +102,7 @@ root.unmount(); ์ด ํ•จ์ˆ˜๋Š” ์ฃผ๋กœ React ๋ฃจํŠธ์˜ DOM ๋…ธ๋“œ(๋˜๋Š” ๊ทธ ์กฐ์ƒ ๋…ธ๋“œ)๊ฐ€ ๋‹ค๋ฅธ ์ฝ”๋“œ์— ์˜ํ•ด DOM์—์„œ ์ œ๊ฑฐ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด DOM์—์„œ ๋น„ํ™œ์„ฑ ํƒญ์„ ์ œ๊ฑฐํ•˜๋Š” jQuery ํƒญ ํŒจ๋„์„ ์ƒ์ƒํ•ด ๋ณด์„ธ์š”. ํƒญ์ด ์ œ๊ฑฐ๋˜๋ฉด ๊ทธ ์•ˆ์— ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ(๋‚ด๋ถ€์˜ React ๋ฃจํŠธ๋ฅผ ํฌํ•จ)์ด DOM์—์„œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ `root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ œ๊ฑฐ๋œ ๋ฃจํŠธ์˜ ์ฝ˜ํ…์ธ  ๊ด€๋ฆฌ๋ฅผ "์ค‘์ง€"ํ•˜๋„๋ก React์— ์ง€์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ œ๊ฑฐ๋œ ๋ฃจํŠธ ๋‚ด๋ถ€์˜ ์ปดํฌ๋„ŒํŠธ๋Š” ๊ตฌ๋…๊ณผ ๊ฐ™์€ ์ „์—ญ ๋ฆฌ์†Œ์Šค๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ํ™•๋ณดํ•˜๋Š” ๋ฒ•์„ ๋ชจ๋ฅด๋Š” ์ฑ„๋กœ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -`root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฃจํŠธ์— ์žˆ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋˜๊ณ , ํŠธ๋ฆฌ์ƒ์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋‚˜ state๊ฐ€ ์ œ๊ฑฐ๋˜๋ฉฐ, ๋ฃจํŠธ DOM ๋…ธ๋“œ์—์„œ React๊ฐ€ "๋ถ„๋ฆฌ"๋ฉ๋‹ˆ๋‹ค. +`root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฃจํŠธ์— ์žˆ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋˜๊ณ , ํŠธ๋ฆฌ์ƒ์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋‚˜ State๊ฐ€ ์ œ๊ฑฐ๋˜๋ฉฐ, ๋ฃจํŠธ DOM ๋…ธ๋“œ์—์„œ React๊ฐ€ "๋ถ„๋ฆฌ"๋ฉ๋‹ˆ๋‹ค. #### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*root-unmount-parameters*/} @@ -126,7 +118,7 @@ root.unmount(); * `root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํŠธ๋ฆฌ์˜ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋˜๊ณ  ๋ฃจํŠธ DOM ๋…ธ๋“œ์—์„œ React๊ฐ€ "๋ถ„๋ฆฌ"๋ฉ๋‹ˆ๋‹ค. -* `root.unmount`๋ฅผ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•œ ํ›„์—๋Š” ๊ฐ™์€ ๋ฃจํŠธ์—์„œ `root.render`๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๋ฃจํŠธ์—์„œ `root.render`๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๊ณ  ํ•˜๋ฉด "๋งˆ์šดํŠธ ํ•ด์ œ๋œ root๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค." ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๋‹น ๋…ธ๋“œ์˜ ์ด์ „ ๋ฃจํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ํ›„ ๋™์ผํ•œ DOM ๋…ธ๋“œ์— ์ƒˆ๋กœ์šด ๋ฃจํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค. +* `root.unmount`๋ฅผ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•œ ํ›„์—๋Š” ๊ฐ™์€ ๋ฃจํŠธ์—์„œ `root.render`๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๋ฃจํŠธ์—์„œ `root.render`๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๊ณ  ํ•˜๋ฉด "๋งˆ์šดํŠธ ํ•ด์ œ๋œ root๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.Cannot update an unmounted root" ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๋‹น ๋…ธ๋“œ์˜ ์ด์ „ ๋ฃจํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ํ›„ ๋™์ผํ•œ DOM ๋…ธ๋“œ์— ์ƒˆ๋กœ์šด ๋ฃจํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค. --- @@ -196,7 +188,7 @@ function Counter() { **์•ฑ์ด ์˜จ์ „ํžˆ React๋งŒ์œผ๋กœ ์ž‘์„ฑ๋œ ๊ฒฝ์šฐ, ์ถ”๊ฐ€์ ์œผ๋กœ ๋ฃจํŠธ๋ฅผ ๋” ๋งŒ๋“ค๊ฑฐ๋‚˜ [`root.render`](#root-render)๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.** -์ด ์‹œ์ ๋ถ€ํ„ฐ React๋Š” ์ „์ฒด ์•ฑ์˜ DOM์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋” ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด [ `App` ์ปดํฌ๋„ŒํŠธ ์•ˆ์— ์ค‘์ฒฉ](/learn/importing-and-exporting-components)์‹œํ‚ค์„ธ์š”. UI ์—…๋ฐ์ดํŠธ๋Š” ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ [state๋ฅผ ํ†ตํ•ด](/reference/react/useState) ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋‹ฌ์ด๋‚˜ ํˆดํŒ๊ณผ ๊ฐ™์€ ์ถ”๊ฐ€ ์ฝ˜ํ…์ธ ๋ฅผ DOM ๋…ธ๋“œ ์™ธ๋ถ€์— ํ‘œ์‹œํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ [portal๋กœ ๋ Œ๋”๋ง](/reference/react-dom/createPortal)ํ•˜์„ธ์š”. +์ด ์‹œ์ ๋ถ€ํ„ฐ React๋Š” ์ „์ฒด ์•ฑ์˜ DOM์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋” ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด [ `App` ์ปดํฌ๋„ŒํŠธ ์•ˆ์— ์ค‘์ฒฉ](/learn/importing-and-exporting-components)์‹œํ‚ค์„ธ์š”. UI ์—…๋ฐ์ดํŠธ๋Š” ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ [State๋ฅผ ํ†ตํ•ด](/reference/react/useState) ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋‹ฌ์ด๋‚˜ ํˆดํŒ๊ณผ ๊ฐ™์€ ์ถ”๊ฐ€ ์ฝ˜ํ…์ธ ๋ฅผ DOM ๋…ธ๋“œ ์™ธ๋ถ€์— ํ‘œ์‹œํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ [Portal๋กœ ๋ Œ๋”๋ง](/reference/react-dom/createPortal)ํ•˜์„ธ์š”. @@ -206,13 +198,13 @@ HTML์ด ๋น„์–ด์žˆ์œผ๋ฉด, ์•ฑ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋˜๊ณ  ์‹คํ–‰
``` -์ด๊ฒƒ์€ ๋งค์šฐ ๋А๋ฆฌ๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด [์„œ๋ฒ„์—์„œ ๋˜๋Š” ๋นŒ๋“œ ์ค‘์—](/reference/react-dom/server) ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ์ดˆ๊ธฐ HTML์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฐฉ๋ฌธ์ž๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์— ํ…์ŠคํŠธ๋ฅผ ์ฝ๊ณ , ์ด๋ฏธ์ง€๋ฅผ ๋ณด๊ณ , ๋งํฌ๋ฅผ ํด๋ฆญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ตœ์ ํ™”๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” [ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉ](/learn/start-a-new-react-project#production-grade-react-frameworks)ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์‹คํ–‰ ์‹œ์ ์— ๋”ฐ๋ผ ์ด๋ฅผ *์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง(SSR)* ๋˜๋Š” *์ •์  ์‚ฌ์ดํŠธ ์ƒ์„ฑ(SSG)* ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. +์ด๊ฒƒ์€ ๋งค์šฐ ๋А๋ฆฌ๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด [์„œ๋ฒ„์—์„œ ๋˜๋Š” ๋นŒ๋“œ ์ค‘์—](/reference/react-dom/server) ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ์ดˆ๊ธฐ HTML์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋ฐฉ๋ฌธ์ž๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์— ํ…์ŠคํŠธ๋ฅผ ์ฝ๊ณ , ์ด๋ฏธ์ง€๋ฅผ ๋ณด๊ณ , ๋งํฌ๋ฅผ ํด๋ฆญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ตœ์ ํ™”๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” [ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉ](/learn/start-a-new-react-project#production-grade-react-frameworks)ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์‹คํ–‰ ์‹œ์ ์— ๋”ฐ๋ผ ์ด๋ฅผ *์„œ๋ฒ„ ์ธก ๋ Œ๋”๋งSSR* ๋˜๋Š” *์ •์  ์‚ฌ์ดํŠธ ์ƒ์„ฑSSG* ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
-**์„œ๋ฒ„ ๋ Œ๋”๋ง์ด๋‚˜ ์ •์  ์ƒ์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ์•ฑ์€ `createRoot` ๋Œ€์‹  [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** ๊ทธ๋Ÿฌ๋ฉด React๋Š” DOM ๋…ธ๋“œ๋ฅผ ํŒŒ๊ดดํ•˜๊ณ  ๋‹ค์‹œ ์ƒ์„ฑํ•˜๋Š” ๋Œ€์‹  HTML์œผ๋กœ๋ถ€ํ„ฐ *hydrate*(์žฌ์‚ฌ์šฉ)ํ•ฉ๋‹ˆ๋‹ค. +**์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง์ด๋‚˜ ์ •์  ์‚ฌ์ดํŠธ ์ƒ์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ์•ฑ์€ `createRoot` ๋Œ€์‹  [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.** ๊ทธ๋Ÿฌ๋ฉด React๋Š” DOM ๋…ธ๋“œ๋ฅผ ํŒŒ๊ดดํ•˜๊ณ  ๋‹ค์‹œ ์ƒ์„ฑํ•˜๋Š” ๋Œ€์‹  HTML์œผ๋กœ๋ถ€ํ„ฐ *Hydrate*(์žฌ์‚ฌ์šฉ)ํ•ฉ๋‹ˆ๋‹ค. --- @@ -221,7 +213,7 @@ HTML์ด ๋น„์–ด์žˆ์œผ๋ฉด, ์•ฑ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋˜๊ณ  ์‹คํ–‰ ํŽ˜์ด์ง€๊ฐ€ [React๋งŒ์œผ๋กœ ์ž‘์„ฑ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page), React๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ ์ตœ์ƒ์œ„ UI์— ๋Œ€ํ•œ ๋ฃจํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด `createRoot`๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฃจํŠธ๋งˆ๋‹ค [`root.render`](#root-render)๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ๊ฐ๊ฐ ๋‹ค๋ฅธ ์ฝ˜ํ…์ธ ๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -๋‹ค์Œ ์˜ˆ์‹œ์—์„œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ React ์ปดํฌ๋„ŒํŠธ๊ฐ€ `index.html` ํŒŒ์ผ์— ์ •์˜๋œ ๋‘ ๊ฐœ์˜ DOM ๋…ธ๋“œ์— ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. +๋‹ค์Œ ์˜ˆ์‹œ์—์„œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐœ์˜ React ์ปดํฌ๋„ŒํŠธ๋ฅผ `index.html` ํŒŒ์ผ์— ์ •์˜๋œ ๋‘ ๊ฐœ์˜ DOM ๋…ธ๋“œ์— ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. @@ -316,7 +308,7 @@ root.unmount(); ### Updating a root component {/*updating-a-root-component*/} -๊ฐ™์€ ๋ฃจํŠธ์—์„œ `render`๋ฅผ ๋‘ ๋ฒˆ ์ด์ƒ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ ๊ตฌ์กฐ๊ฐ€ ์ด์ „ ๋ Œ๋”๋ง๊ณผ ์ผ์น˜ํ•˜๋Š” ํ•œ, React๋Š” [๊ธฐ์กด state๋ฅผ ์œ ์ง€](/learn/preserving-and-resetting-state)ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์˜ˆ์‹œ์—์„œ input์— ์–ด๋–ป๊ฒŒ ํƒ€์ดํ•‘ํ•˜๋“  ๊ด€๊ณ„์—†์ด, ๋งค ์ดˆ ๋ฐ˜๋ณต๋˜๋Š” `render` ํ˜ธ์ถœ๋กœ ์ธํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค์ง€ ์•Š์Œ์„ ์ฃผ๋ชฉํ•˜์„ธ์š”. +๊ฐ™์€ ๋ฃจํŠธ์—์„œ `render`๋ฅผ ๋‘ ๋ฒˆ ์ด์ƒ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ ๊ตฌ์กฐ๊ฐ€ ์ด์ „ ๋ Œ๋”๋ง๊ณผ ์ผ์น˜ํ•˜๋Š” ํ•œ, React๋Š” [๊ธฐ์กด State๋ฅผ ์œ ์ง€](/learn/preserving-and-resetting-state)ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์˜ˆ์‹œ์—์„œ ์ž…๋ ฅ ์ฐฝ์— ์–ด๋–ป๊ฒŒ ํƒ€์ดํ•‘ํ•˜๋“  ๊ด€๊ณ„์—†์ด, ๋งค ์ดˆ ๋ฐ˜๋ณต๋˜๋Š” `render` ํ˜ธ์ถœ๋กœ ์ธํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค์ง€ ์•Š์Œ์„ ์ฃผ๋ชฉํ•˜์„ธ์š”. @@ -347,7 +339,7 @@ export default function App({counter}) { -`render`๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ํ”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ๋Š”, ์ปดํฌ๋„ŒํŠธ๊ฐ€ [state๋ฅผ ์—…๋ฐ์ดํŠธ](/reference/react/useState)ํ•ฉ๋‹ˆ๋‹ค. +`render`๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ํ”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ๋Š”, ์ปดํฌ๋„ŒํŠธ๊ฐ€ [State๋ฅผ ์—…๋ฐ์ดํŠธ](/reference/react/useState)ํ•ฉ๋‹ˆ๋‹ค. ### Show a dialog for uncaught errors {/*show-a-dialog-for-uncaught-errors*/} @@ -1136,7 +1128,7 @@ root.render(); --- -### "๋Œ€์ƒ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ DOM ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค" ๋ผ๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. {/*im-getting-an-error-target-container-is-not-a-dom-element*/} +### I'm getting an error: "You passed a second argument to root.render" {/*im-getting-an-error-you-passed-a-second-argument-to-root-render*/} A common mistake is to pass the options for `createRoot` to `root.render(...)`: @@ -1156,6 +1148,21 @@ const root = createRoot(container, {onUncaughtError}); root.render(); ``` +--- + +### "๋Œ€์ƒ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ DOM ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค" ๋ผ๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. {/*im-getting-an-error-target-container-is-not-a-dom-element*/} + +This error means that whatever you're passing to `createRoot` is not a DOM node. + +If you're not sure what's happening, try logging it: + +```js {2} +const domNode = document.getElementById('root'); +console.log(domNode); // ??? +const root = createRoot(domNode); +root.render(); +``` + ์˜ˆ๋ฅผ ๋“ค์–ด `domNode`๊ฐ€ `null`์ด๋ฉด [`getElementById`](https://developer.mozilla.org/ko/docs/Web/API/Document/getElementById) ๊ฐ€ `null`์„ ๋ฐ˜ํ™˜ํ–ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ˜ธ์ถœ ์‹œ์ ์— ๋ฌธ์„œ์— ์ง€์ •๋œ ID๋ฅผ ๊ฐ€์ง„ ๋…ธ๋“œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋ช‡ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1. ์ฐพ๊ณ ์ž ํ•˜๋Š” ID๊ฐ€ HTML ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•œ ID์™€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜คํƒ€๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”! @@ -1169,7 +1176,7 @@ root.render(); ์ด ์˜ค๋ฅ˜๋Š” `root.render`์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•„๋‹˜์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. -์ด ์˜ค๋ฅ˜๋Š” `` ๋Œ€์‹  `Component`๋กœ `root.render`๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค +์ด ์˜ค๋ฅ˜๋Š” `` ๋Œ€์‹  `Component`๋กœ `root.render`๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {2,5} // ๐Ÿšฉ Wrong: App is a function, not a Component. @@ -1193,7 +1200,7 @@ root.render(createApp()); ### ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ HTML์ด ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค {/*my-server-rendered-html-gets-re-created-from-scratch*/} -์•ฑ์ด ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋˜๊ณ  React์˜ ์ดˆ๊ธฐ HTML์„ ํฌํ•จํ•˜๋Š” ๊ฒฝ์šฐ์—, ๋ฃจํŠธ๋ฅผ ์ƒ์„ฑํ•ด์„œ `root.render`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ๋ชจ๋“  HTML์ด ์‚ญ์ œ๋˜๊ณ  ๋ชจ๋“  DOM ๋…ธ๋“œ๊ฐ€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์†๋„๊ฐ€ ๋А๋ ค์ง€๊ณ , ํฌ์ปค์Šค์™€ ์Šคํฌ๋กค ์œ„์น˜๊ฐ€ ์žฌ์„ค์ •๋˜๋ฉฐ, ๊ทธ ๋ฐ–์˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ์ž…๋ ฅ๋“ค์ด ์†์‹ค๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์•ฑ์ด ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋˜๊ณ  React์˜ ์ดˆ๊ธฐ HTML์„ ํฌํ•จํ•˜๋Š” ๊ฒฝ์šฐ์—, ๋ฃจํŠธ๋ฅผ ์ƒ์„ฑํ•ด์„œ `root.render`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ๋ชจ๋“  HTML์ด ์‚ญ์ œ๋˜๊ณ  ๋ชจ๋“  DOM ๋…ธ๋“œ๊ฐ€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์†๋„๊ฐ€ ๋А๋ ค์ง€๊ณ , ํฌ์ปค์Šค์™€ ์Šคํฌ๋กค ์œ„์น˜๊ฐ€ ์žฌ์„ค์ •๋˜๋ฉฐ, ๊ทธ ๋ฐ–์˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ์ž…๋ ฅ๋“ค์ด ์†์‹ค๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ ์•ฑ์€ `createRoot` ๋Œ€์‹  [`hydrateRoot`](/reference/react-dom/client/hydrateRoot)๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. From bbb67f5577f01322f520055ae198ed678a0d3290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sat, 4 Jan 2025 15:02:18 +0900 Subject: [PATCH 0399/1059] docs: update `hydrateRoot.md` --- .../reference/react-dom/client/createRoot.md | 8 +- .../reference/react-dom/client/hydrateRoot.md | 196 ++++++++---------- 2 files changed, 90 insertions(+), 114 deletions(-) diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index 584020571..3215ac45d 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -50,11 +50,11 @@ root.render(); #### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} -`createRoot`๋Š” [`render`](#root-render)์™€ [`unmount`](#root-unmount) ๋‘ ๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. +`createRoot`๋Š” [`render`](#root-render)์™€ [`unmount`](#root-unmount) ๋‘ ๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๋ฅผ ํฌํ•จํ•œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} * ์•ฑ์ด ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ๋˜๋Š” ๊ฒฝ์šฐ `createRoot()`๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  [`hydrateRoot()`](/reference/react-dom/client/hydrateRoot)๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. -* ์•ฑ์— `createRoot` ํ˜ธ์ถœ์ด ๋‹จ ํ•˜๋‚˜๋งŒ ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ด ํ˜ธ์ถœ์„ ๋Œ€์‹  ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +* ์•ฑ์—์„œ `createRoot` ํ˜ธ์ถœ์ด ๋‹จ ํ•œ๋ฒˆ๋งŒ ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ด ํ˜ธ์ถœ์„ ๋Œ€์‹  ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. * ์ปดํฌ๋„ŒํŠธ์˜ ์ž์‹์ด ์•„๋‹Œ DOM ํŠธ๋ฆฌ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„(์˜ˆ: ๋ชจ๋‹ฌ ๋˜๋Š” ํˆดํŒ)์— JSX ์กฐ๊ฐ์„ ๋ Œ๋”๋งํ•˜๋ ค๋Š” ๊ฒฝ์šฐ, `createRoot` ๋Œ€์‹  [`createPortal`](/reference/react-dom/createPortal)์„ ์‚ฌ์šฉํ•˜์„ธ์š”. --- @@ -92,7 +92,7 @@ React๋Š” `root`์— ``์„ ํ‘œ์‹œํ•˜๊ณ  ๊ทธ ์•ˆ์— ์žˆ๋Š” DOM์„ ๊ด€๋ฆฌํ•ฉ ### `root.unmount()` {/*root-unmount*/} -`root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด React ๋ฃจํŠธ ๋‚ด๋ถ€์—์„œ ๋ Œ๋”๋ง ๋œ ํŠธ๋ฆฌ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. +`root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด React ๋ฃจํŠธ ๋‚ด๋ถ€์—์„œ ๋ Œ๋”๋ง๋œ ํŠธ๋ฆฌ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ```js root.unmount(); @@ -118,7 +118,7 @@ root.unmount(); * `root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํŠธ๋ฆฌ์˜ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋˜๊ณ  ๋ฃจํŠธ DOM ๋…ธ๋“œ์—์„œ React๊ฐ€ "๋ถ„๋ฆฌ"๋ฉ๋‹ˆ๋‹ค. -* `root.unmount`๋ฅผ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•œ ํ›„์—๋Š” ๊ฐ™์€ ๋ฃจํŠธ์—์„œ `root.render`๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๋ฃจํŠธ์—์„œ `root.render`๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๊ณ  ํ•˜๋ฉด "๋งˆ์šดํŠธ ํ•ด์ œ๋œ root๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.Cannot update an unmounted root" ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๋‹น ๋…ธ๋“œ์˜ ์ด์ „ ๋ฃจํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ํ›„ ๋™์ผํ•œ DOM ๋…ธ๋“œ์— ์ƒˆ๋กœ์šด ๋ฃจํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค. +* `root.unmount`๋ฅผ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•œ ํ›„์—๋Š” ๊ฐ™์€ ๋ฃจํŠธ์—์„œ `root.render`๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๋ฃจํŠธ์—์„œ `root.render`๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๊ณ  ํ•˜๋ฉด "๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๋ฃจํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.Cannot update an unmounted root" ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๋‹น ๋…ธ๋“œ์˜ ์ด์ „ ๋ฃจํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ํ›„ ๋™์ผํ•œ DOM ๋…ธ๋“œ์— ์ƒˆ๋กœ์šด ๋ฃจํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค. --- diff --git a/src/content/reference/react-dom/client/hydrateRoot.md b/src/content/reference/react-dom/client/hydrateRoot.md index 34fd04f4b..db0a3b9d7 100644 --- a/src/content/reference/react-dom/client/hydrateRoot.md +++ b/src/content/reference/react-dom/client/hydrateRoot.md @@ -4,7 +4,7 @@ title: hydrateRoot -`hydrateRoot`๋Š” [`react-dom/server`](/reference/react-dom/server)๋ฅผ ํ†ตํ•ด ์‚ฌ์ „์— ๋งŒ๋“ค์–ด์ง„ HTML๋กœ ๊ทธ๋ ค์ง„ ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ ๋‚ด๋ถ€์— React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. +`hydrateRoot`๋Š” ์ด์ „์— [`react-dom/server`](/reference/react-dom/server)๋กœ ์ƒ์„ฑ๋œ HTML ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ€์ง„ ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ ์•ˆ์— React ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ```js const root = hydrateRoot(domNode, reactNode, options?) @@ -20,7 +20,7 @@ const root = hydrateRoot(domNode, reactNode, options?) ### `hydrateRoot(domNode, reactNode, options?)` {/*hydrateroot*/} -์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ React๋กœ ์•ž์„œ ๋งŒ๋“ค์–ด์ง„ HTML์— ํ›„์— ๋งŒ๋“ค์–ด์ง„ React๋ฅผ `hydrateRoot`๋ฅผ ํ˜ธ์ถœํ•ด "๋ถ™์ž…๋‹ˆ๋‹ค". +`hydrateRoot`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ด๋ฏธ ์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ ๋ Œ๋”๋ง๋œ ๊ธฐ์กด HTML์— React๋ฅผ "๋ถ™์—ฌ๋„ฃ๊ธฐ" ํ•ฉ๋‹ˆ๋‹ค. ```js import { hydrateRoot } from 'react-dom/client'; @@ -29,82 +29,78 @@ const domNode = document.getElementById('root'); const root = hydrateRoot(domNode, reactNode); ``` -React๋Š” `domNode` ๋‚ด๋ถ€์˜ HTML์— ๋ถ™์–ด, ๋‚ด๋ถ€ DOM์„ ์ง์ ‘ ๊ด€๋ฆฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. App์„ React๋กœ ์ „๋ถ€ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด ๋ณดํ†ต์€ ๋‹จ ํ•˜๋‚˜์˜ root ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ๊ป˜ `hydrateRoot`๋ฅผ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. +React๋Š” `domNode` ๋‚ด๋ถ€์— ์กด์žฌํ•˜๋Š” HTML์— ์—ฐ๊ฒฐ๋˜์–ด, ๊ทธ ๋‚ด๋ถ€์˜ DOM ๊ด€๋ฆฌ๋ฅผ ๋งก๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. React๋กœ ์™„์ „ํžˆ ๊ตฌ์ถ•๋œ ์•ฑ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ๊ป˜ ํ•˜๋‚˜์˜ `hydrateRoot` ํ˜ธ์ถœ๋งŒ ๊ฐ€์ง‘๋‹ˆ๋‹ค. -[์•„๋ž˜ ์—ฌ๋Ÿฌ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•ด๋ณด์„ธ์š”.](#usage) +[์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) -#### Parameters {/*parameters*/} +#### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*parameters*/} -* `domNode`: ์„œ๋ฒ„์—์„œ root ์—˜๋ฆฌ๋จผํŠธ๋กœ ๋ Œ๋”๋ง๋œ [DOM ์—˜๋ฆฌ๋จผํŠธ](https://developer.mozilla.org/en-US/docs/Web/API/Element) +* `domNode`: ์„œ๋ฒ„์—์„œ ๋ฃจํŠธ ์š”์†ŒElement๋กœ ๋ Œ๋”๋ง๋œ [DOM ์š”์†Œ](https://developer.mozilla.org/en-US/docs/Web/API/Element). -* `reactNode`: ์•ž์„œ ์กด์žฌํ•˜๋Š” HTML์— ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•œ "React ๋…ธ๋“œ" ์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ `ReactDOM Server`์˜ `renderToPipeableStream()`์™€ ๊ฐ™์€ ๋ฉ”์†Œ๋“œ๋กœ ๋ Œ๋”๋ง๋œ ``๊ฐ™์€ JSX ์กฐ๊ฐ๋“ค์ž…๋‹ˆ๋‹ค. - -* **optional** `options`: React root์— ์˜ต์…˜์„ ์ฃผ๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. +* `reactNode`: ๊ธฐ์กด HTML์— ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•œ "React ๋…ธ๋“œ" ์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ `ReactDOM Server`์˜ `renderToPipeableStream()`์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋กœ ๋ Œ๋”๋ง๋œ ``๊ณผ ๊ฐ™์€ JSX ์กฐ๊ฐ๋“ค์ž…๋‹ˆ๋‹ค. +* **optional** `options`: React ๋ฃจํŠธ์— ๋Œ€ํ•œ ์˜ต์…˜์„ ๊ฐ€์ง„ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. * **optional** `onCaughtError`: Callback called when React catches an error in an Error Boundary. Called with the `error` caught by the Error Boundary, and an `errorInfo` object containing the `componentStack`. * **optional** `onUncaughtError`: Callback called when an error is thrown and not caught by an Error Boundary. Called with the `error` that was thrown and an `errorInfo` object containing the `componentStack`. - * **optional** `onRecoverableError`: Callback called when React automatically recovers from errors. Called with the `error` React throws, and an `errorInfo` object containing the `componentStack`. Some recoverable errors may include the original error cause as `error.cause`. - * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as used on the server. - - * **optional** `onRecoverableError`: React๊ฐ€ ์—๋Ÿฌ์—์„œ ์ž๋™์œผ๋กœ ํšŒ๋ณต๋˜์—ˆ์„ ๋•Œ ํ˜ธ์ถœํ•˜๋Š” ์ฝœ๋ฐฑํ•จ์ˆ˜. - * **optional** `identifierPrefix`: React๊ฐ€ ID๋กœ ์‚ฌ์šฉํ•˜๋Š” ์ ‘๋‘์‚ฌ๋กœ [`useId`](/reference/react/useId)๋กœ ๋งŒ๋“ค์–ด์ง„ ๊ฐ’์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ root๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•  ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉํ•œ ๊ฐ’๊ณผ ๋ฐ˜๋“œ์‹œ ๋™์ผํ•œ ๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + * **optional** `onRecoverableError`: React๊ฐ€ ์˜ค๋ฅ˜๋กœ๋ถ€ํ„ฐ ์ž๋™์œผ๋กœ ๋ณต๊ตฌ๋  ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑ. Called with the `error` React throws, and an `errorInfo` object containing the `componentStack`. Some recoverable errors may include the original error cause as `error.cause`. + * **optional** `identifierPrefix`: React๊ฐ€ [`useId`](/reference/react/useId)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ID์— ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž์—ด ์ ‘๋‘์‚ฌ. ๊ฐ™์€ ํŽ˜์ด์ง€์—์„œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฃจํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถฉ๋Œ์„ ํ”ผํ•˜๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉํ•œ ๊ฐ’๊ณผ ๋ฐ˜๋“œ์‹œ ๋™์ผํ•œ ๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -#### Returns {/*returns*/} +#### ๋ฐ˜ํ™˜๊ฐ’ {/*returns*/} -`hydrateRoot`๋Š” 2๊ฐ€์ง€ ๋ฉ”์†Œ๋“œ๊ฐ€ ํฌํ•จ๋œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค : [`render`](#root-render) ๊ทธ๋ฆฌ๊ณ  [`unmount`.](#root-unmount) +`hydrateRoot`๋Š” [`render`](#root-render)์™€ [`unmount`](#root-unmount) ๋‘ ๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๋ฅผ ํฌํ•จํ•œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. #### ์ฃผ์˜ ์‚ฌํ•ญ {/*caveats*/} -* `hydrateRoot()`๋Š” ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ ๋‚ด์šฉ๊ณผ ํ›„์— ๋ Œ๋”๋ง๋œ ๋‚ด์šฉ์ด ๋™์ผํ•  ๊ฒƒ์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋™์ผํ•˜์ง€ ์•Š์€ ๋ถ€๋ถ„๋“ค์€ ์ง์ ‘ ๋ฒ„๊ทธ๋กœ ์ทจ๊ธ‰ํ•ด์ฃผ๊ฑฐ๋‚˜ ๊ณ ์ณ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. -* ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„ , React๊ฐ€ hydration ์ค‘์— ๋™์ผํ•˜์ง€ ์•Š์€ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ๊ฒฝ๊ณ ํ•ด์ค๋‹ˆ๋‹ค. ์†์„ฑ์ด ๋™์ผํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ์— ํ•ด๋‹น ์†์„ฑ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ ์šฉ๋  ๊ฒƒ์ด๋ผ๊ณ  ๋ณด์žฅํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๋งˆํฌ์—…์„ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ์„ฑ๋Šฅ๋ฉด์—์„œ ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋งˆํฌ์—…์ด ๋™์ผํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋Š” ๋“œ๋ฌผ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๋งˆํฌ์—…์„ ๊ฒ€์ฆํ•˜๋Š” ๋น„์šฉ์€ ๊ต‰์žฅํžˆ ๋น„์Œ‰๋‹ˆ๋‹ค. -* ์—ฌ๋Ÿฌ๋ถ„์€ App์—์„œ `hydrateRoot`๋ฅผ ๋‹จ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋Œ€์‹  ํ˜ธ์ถœํ•ด ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -* App์„ ์‚ฌ์ „์— ๋ Œ๋”๋ง๋œ HTML ์—†์ด ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ ๋ Œ๋”๋ง์„ ํ•œ๋‹ค๋ฉด `hydrateRoot()`์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. [`createRoot()`](/reference/react-dom/client/createRoot)๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•ด์ฃผ์„ธ์š”. +* `hydrateRoot()`๋Š” ๋ Œ๋”๋ง๋œ ์ปจํ…์ธ ๊ฐ€ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ ์ปจํ…์ธ ์™€ ๋™์ผํ•  ๊ฒƒ์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ถˆ์ผ์น˜ ์‚ฌํ•ญ์€ ๋ฒ„๊ทธ๋กœ ์ทจ๊ธ‰ํ•˜๊ณ  ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +* ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ๋Š” React๊ฐ€ Hydration ์ค‘ ๋ถˆ์ผ์น˜์— ๋Œ€ํ•ด ๊ฒฝ๊ณ ํ•ฉ๋‹ˆ๋‹ค. ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ ์†์„ฑ ์ฐจ์ด๊ฐ€ ์ˆ˜์ •๋  ๊ฒƒ์ด๋ผ๋Š” ๋ณด์žฅ์€ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์„ฑ๋Šฅ์ƒ์˜ ์ด์œ ๋กœ ์ค‘์š”ํ•œ๋ฐ, ๋Œ€๋ถ€๋ถ„์˜ ์•ฑ์—์„œ ๋ถˆ์ผ์น˜๋Š” ๋“œ๋ฌผ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๋งˆํฌ์—…์„ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ๋น„ํšจ์œจ์ ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. +* ์•ฑ์—์„œ `hydrateRoot` ํ˜ธ์ถœ์ด ๋‹จ ํ•œ๋ฒˆ๋งŒ ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ด ํ˜ธ์ถœ์„ ๋Œ€์‹  ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. +* ์•ฑ์„ ์‚ฌ์ „์— ๋ Œ๋”๋ง๋œ HTML ์—†์ด ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ ๋ Œ๋”๋งํ•œ๋‹ค๋ฉด, `hydrateRoot()`๋Š” ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. [`createRoot()`](/reference/react-dom/client/createRoot)๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•ด์ฃผ์„ธ์š”. --- ### `root.render(reactNode)` {/*root-render*/} -hydrate๋œ React root๋ถ€ํ„ฐ ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒˆ๋กœ์šด React ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฐฑ์‹ ํ•˜๊ธฐ ์œ„ํ•ด `root.render`๋ฅผ ํ˜ธ์ถœํ•ด์ฃผ์„ธ์š”. ๋ธŒ๋ผ์šฐ์ € DOM ์š”์†Œ๋“ค๋„ ํ•จ๊ป˜ ๊ฐฑ์‹ ๋ฉ๋‹ˆ๋‹ค. +๋ธŒ๋ผ์šฐ์ € DOM ์š”์†Œ ๋‚ด์—์„œ Hydrate๋œ React ๋ฃจํŠธ ์•ˆ์˜ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๋ ค๋ฉด `root.render`๋ฅผ ํ˜ธ์ถœํ•˜์„ธ์š”. ```js root.render(); ``` -React๋Š” hydrate๋œ `root`๋ถ€ํ„ฐ ๋‚ด๋ถ€๋ฅผ ``์œผ๋กœ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค. +React๋Š” Hydrate๋œ `root`์—์„œ ``์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. -[์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ํ™•์ธํ•ด๋ณด์„ธ์š”.](#usage) +[์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.](#usage) -#### Parameters {/*root-render-parameters*/} +#### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*root-render-parameters*/} -* `reactNode`: ๊ฐฑ์‹ ํ•˜๊ณ  ์‹ถ์€ "React ๋…ธ๋“œ"์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ``๊ฐ™์€ JSX๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„˜๊ธฐ์ง€๋งŒ, [`createElement()`](/reference/react/createElement)๋กœ ๋งŒ๋“  React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋„˜๊ฒจ๋„ ๋˜๊ณ  ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž, `null`, ํ˜น์€ `undefined`๋ฅผ ๋„˜๊ฒจ๋„ ๋ฉ๋‹ˆ๋‹ค. +* `reactNode`: ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์‹ถ์€ "React ๋…ธ๋“œ"์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ``๊ฐ™์€ JSX๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„˜๊ธฐ์ง€๋งŒ, [`createElement()`](/reference/react/createElement)๋กœ ๋งŒ๋“  React ์š”์†Œ ํ˜น์€ ๋ฌธ์ž์—ด, ์ˆซ์ž, `null`, `undefined`๋ฅผ ๋„˜๊ฒจ๋„ ๋ฉ๋‹ˆ๋‹ค. -#### Returns {/*root-render-returns*/} +#### ๋ฐ˜ํ™˜๊ฐ’ {/*root-render-returns*/} `root.render`๋Š” `undefined`๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. #### ์ฃผ์˜ ์‚ฌํ•ญ {/*root-render-caveats*/} -* hydrate๊ฐ€ ๋๋‚˜๊ธฐ ์ „์— `root.render`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด React๋Š” ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ HTML์„ ๋ชจ๋‘ ์—†์• ๊ณ  ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง๋œ ์ปดํฌ๋„ŒํŠธ๋“ค๋กœ ์™„์ „ํžˆ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค. +* ๋ฃจํŠธ๊ฐ€ Hydrate๋ฅผ ์™„๋ฃŒํ•˜๊ธฐ ์ „์— `root.render`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, React๋Š” ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ HTML์„ ๋ชจ๋‘ ์—†์• ๊ณ  ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง๋œ ์ปดํฌ๋„ŒํŠธ๋“ค๋กœ ์™„์ „ํžˆ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค. --- ### `root.unmount()` {/*root-unmount*/} -`root.unmount`๋ฅผ ํ˜ธ์ถœํ•ด React root๋ถ€ํ„ฐ ๊ทธ ํ•˜์œ„์— ๋ Œ๋”๋ง๋œ ํŠธ๋ฆฌ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. +`root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด React ๋ฃจํŠธ ๋‚ด๋ถ€์—์„œ ๋ Œ๋”๋ง๋œ ํŠธ๋ฆฌ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ```js root.unmount(); ``` -์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ React๋กœ ๋งŒ๋“  ์•ฑ์€ `root.unmount`๋ฅผ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ๊ฐ€ ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. +์˜จ์ „ํžˆ React๋งŒ์œผ๋กœ ์ž‘์„ฑ๋œ ์•ฑ์—๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ `root.unmount`์— ๋Œ€ํ•œ ํ˜ธ์ถœ์ด ์—†์Šต๋‹ˆ๋‹ค. -์ฃผ๋กœ React root๋ถ€ํ„ฐ ํ˜น์€ ๊ทธ ์ƒ์œ„์—์„œ๋ถ€ํ„ฐ ์‹œ์ž‘๋œ DOM node๋“ค์„ ๋‹ค๋ฅธ ์ฝ”๋“œ์— ์˜ํ•ด DOM์—์„œ ์‚ญ์ œ๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, jQuery ํƒญ ํŒจ๋„์ด ํ™œ์„ฑํ™” ๋˜์–ด ์žˆ์ง€ ์•Š์€ ํƒญ์„ DOM์—์„œ ์ง€์šด๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค. ํƒญ์ด ์ง€์›Œ์ง€๋ฉด, React root์™€ ๊ทธ ๋‚ด๋ถ€๋ฅผ ํฌํ•จํ•ด ๊ทธ ์•ˆ์˜ ๋ชจ๋“  ๊ฒƒ์ด ์ง€์›Œ์ง€๊ฒŒ ๋˜๊ณ  DOM์—์„œ ๋˜ํ•œ ์ง€์›Œ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. `root.unmount`๋ฅผ ํ˜ธ์ถœํ•ด React์—๊ฒŒ ์‚ญ์ œ๋œ ์ปจํ…์ธ ๋“ค์„ "๊ทธ๋งŒ" ๋‹ค๋ฃจ๋ผ๊ณ  ์•Œ๋ ค์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์‚ญ์ œ๋˜์–ด๋ฒ„๋ฆฐ React root ๋‚ด๋ถ€์˜ ์ปดํฌ๋„ŒํŠธ๋“ค์€ ์‚ญ์ œ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ, "๊ตฌ๋…"์ฒ˜๋Ÿผ ์ปดํ“จํŒ… ์ž์›์„ ์ž์œ ๋กญ๊ฒŒ ๋†“์•„์ฃผ์ง€ ๋ชปํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +์ด ํ•จ์ˆ˜๋Š” ์ฃผ๋กœ React ๋ฃจํŠธ์˜ DOM ๋…ธ๋“œ(๋˜๋Š” ๊ทธ ์กฐ์ƒ ๋…ธ๋“œ)๊ฐ€ ๋‹ค๋ฅธ ์ฝ”๋“œ์— ์˜ํ•ด DOM์—์„œ ์ œ๊ฑฐ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด DOM์—์„œ ๋น„ํ™œ์„ฑ ํƒญ์„ ์ œ๊ฑฐํ•˜๋Š” jQuery ํƒญ ํŒจ๋„์„ ์ƒ์ƒํ•ด ๋ณด์„ธ์š”. ํƒญ์ด ์ œ๊ฑฐ๋˜๋ฉด ๊ทธ ์•ˆ์— ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ(๋‚ด๋ถ€์˜ React ๋ฃจํŠธ๋ฅผ ํฌํ•จ)์ด DOM์—์„œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ `root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ œ๊ฑฐ๋œ ๋ฃจํŠธ์˜ ์ฝ˜ํ…์ธ  ๊ด€๋ฆฌ๋ฅผ "์ค‘์ง€"ํ•˜๋„๋ก React์— ์ง€์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ œ๊ฑฐ๋œ ๋ฃจํŠธ ๋‚ด๋ถ€์˜ ์ปดํฌ๋„ŒํŠธ๋Š” ๊ตฌ๋…๊ณผ ๊ฐ™์€ ์ „์—ญ ๋ฆฌ์†Œ์Šค๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ํ™•๋ณดํ•˜๋Š” ๋ฒ•์„ ๋ชจ๋ฅด๋Š” ์ฑ„๋กœ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. -`root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด root ๋‚ด๋ถ€์˜ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  root DOM node์—์„œ React๋ฅผ "๋–ผ์–ด"๋ƒ…๋‹ˆ๋‹ค. root ๋‚ด๋ถ€์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์™€ state๊นŒ์ง€ ๋ชจ๋‘ ํฌํ•จํ•ด ๋งˆ์šดํŠธ ํ•ด์ œ ๋ฐ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค. +`root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฃจํŠธ์— ์žˆ๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋˜๊ณ , ํŠธ๋ฆฌ์ƒ์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋‚˜ State๊ฐ€ ์ œ๊ฑฐ๋˜๋ฉฐ, ๋ฃจํŠธ DOM ๋…ธ๋“œ์—์„œ React๊ฐ€ "๋ถ„๋ฆฌ"๋ฉ๋‹ˆ๋‹ค. -#### Parameters {/*root-unmount-parameters*/} +#### ๋งค๊ฐœ๋ณ€์ˆ˜ {/*root-unmount-parameters*/} -`root.unmount`๋Š” ๊ทธ ์–ด๋–ค ๋งค๊ฐœ๋ณ€์ˆ˜๋„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. +`root.unmount`๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. #### Returns {/*root-unmount-returns*/} @@ -113,17 +109,17 @@ root.unmount(); #### ์ฃผ์˜ ์‚ฌํ•ญ {/*root-unmount-caveats*/} -* `root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด root๋ถ€ํ„ฐ ๊ทธ ์•ˆ์˜ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋˜๊ณ  root DOM node์—์„œ React๋ฅผ ๋–ผ์–ด๋ƒ…๋‹ˆ๋‹ค. +* `root.unmount`๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํŠธ๋ฆฌ์˜ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋˜๊ณ  ๋ฃจํŠธ DOM ๋…ธ๋“œ์—์„œ React๊ฐ€ "๋ถ„๋ฆฌ"๋ฉ๋‹ˆ๋‹ค. -* `root.unmount`๋ฅผ ํ•œ๋ฒˆ ํ˜ธ์ถœํ•œ ์ดํ›„์—” `root.render`๋ฅผ root์— ๋‹ค์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋งˆ์šดํŠธ ํ•ด์ œ๋œ root์— ๋‹ค์‹œ `root.render`๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๊ณ  ํ•œ๋‹ค๋ฉด "Cannot update an unmounted root" ์—๋Ÿฌ๋ฅผ throwํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +* `root.unmount`๋ฅผ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•œ ํ›„์—๋Š” ๊ฐ™์€ ๋ฃจํŠธ์—์„œ `root.render`๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๋ฃจํŠธ์—์„œ `root.render`๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๊ณ  ํ•˜๋ฉด "๋งˆ์šดํŠธ ํ•ด์ œ๋œ ๋ฃจํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.Cannot update an unmounted root" ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. --- -## ์‚ฌ์šฉ ์˜ˆ์‹œ {/*usage*/} +## ์‚ฌ์šฉ๋ฒ• {/*usage*/} -### ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ HTML์„ hydrateํ•˜๊ธฐ {/*hydrating-server-rendered-html*/} +### ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ HTML์„ Hydrateํ•˜๊ธฐ {/*hydrating-server-rendered-html*/} -[`react-dom/server`](/reference/react-dom/client/createRoot)๋กœ ์•ฑ์˜ HTML์„ ์ƒ์„ฑํ–ˆ๋‹ค๋ฉด, ํด๋ผ์ด์–ธํŠธ์—์„œ *hydrate*ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +[`react-dom/server`](/reference/react-dom/client/createRoot)๋กœ ์•ฑ์˜ HTML์„ ์ƒ์„ฑํ–ˆ๋‹ค๋ฉด, ํด๋ผ์ด์–ธํŠธ์—์„œ *Hydrate* ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ```js [[1, 3, "document.getElementById('root')"], [2, 3, ""]] import { hydrateRoot } from 'react-dom/client'; @@ -131,9 +127,9 @@ import { hydrateRoot } from 'react-dom/client'; hydrateRoot(document.getElementById('root'), ); ``` -์œ„ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ HTML์„ ๋ธŒ๋ผ์šฐ์ € DOM node์—์„œ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์šฉํ•ด hydrate ํ•ด์ค„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ์•ฑ์„ ์‹œ์ž‘ํ•  ๋•Œ ๋‹จ ํ•œ ๋ฒˆ ์‹คํ–‰ํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉ์ค‘์ด๋ผ๋ฉด ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์•Œ์•„์„œ ์‹คํ–‰ํ•ด ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์œ„ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ HTML์„ ๋ธŒ๋ผ์šฐ์ € DOM ๋…ธ๋“œ์—์„œ React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์šฉํ•ด Hydrate ํ•ด์ค„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ์•ฑ์„ ์‹œ์ž‘ํ•  ๋•Œ ๋‹จ ํ•œ ๋ฒˆ ์‹คํ–‰ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉ์ค‘์ด๋ผ๋ฉด ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋Œ€์‹  ์‹คํ–‰ํ•ด ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. -์•ฑ์„ hydrateํ•˜๊ธฐ ์œ„ํ•ด์„œ React๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๋กœ์ง์„ ์‚ฌ์ „์— ์„œ๋ฒ„์—์„œ ๋งŒ๋“ค์–ด ์ง„ HTML์— "๋ถ™์ผ"๊ฒƒ ์ž…๋‹ˆ๋‹ค. Hydration์„ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ๋งŒ๋“ค์–ด์ง„ ์ตœ์ดˆ์˜ HTML ์Šค๋ƒ…์ƒท์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์™„์ „ํžˆ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒํ•œ ์•ฑ์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. +์•ฑ์„ Hydrate ํ•˜๊ธฐ ์œ„ํ•ด์„œ React๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๋กœ์ง์„ ์‚ฌ์ „์— ์„œ๋ฒ„์—์„œ ๋งŒ๋“ค์–ด ์ง„ HTML์— "๋ถ™์—ฌ๋„ฃ์„"๊ฒƒ ์ž…๋‹ˆ๋‹ค. Hydration์„ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ๋งŒ๋“ค์–ด์ง„ ์ตœ์ดˆ์˜ HTML ์Šค๋ƒ…์ƒท์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์™„์ „ํžˆ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒํ•œ ์•ฑ์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. @@ -180,30 +176,30 @@ function Counter() { -`hydrateRoot`๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋” ํ˜ธ์ถœํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ด ์‹œ์ ๋ถ€ํ„ฐ React๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ DOM์„ ๋‹ค๋ฃจ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  UI๋ฅผ ๊ฐฑ์‹ ํ•˜๊ธฐ ์œ„ํ•ด์„  [state๋ฅผ ์‚ฌ์šฉ](/reference/react/useState)ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +`hydrateRoot`๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋” ํ˜ธ์ถœํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ด ์‹œ์ ๋ถ€ํ„ฐ React๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ DOM์„ ๋‹ค๋ฃจ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  UI๋ฅผ ๊ฐฑ์‹ ํ•˜๊ธฐ ์œ„ํ•ด์„  [State๋ฅผ ์‚ฌ์šฉ](/reference/react/useState)ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. `hydrateRoot`์— ์ „๋‹ฌํ•œ React ํŠธ๋ฆฌ๋Š” ์„œ๋ฒ„์—์„œ ๋งŒ๋“ค์—ˆ๋˜ React ํŠธ๋ฆฌ ๊ฒฐ๊ณผ๋ฌผ๊ณผ ๋™์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. -์ด๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์œ„ํ•ด์„œ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์„œ๋ฒ„์—์„œ ๋งŒ๋“ค์–ด์ง„ HTML์„ JavaScript ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๋‘˜๋Ÿฌ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์•ฑ์˜ ๋กœ๋”ฉ์„ ๋” ๋น ๋ฅด๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„๋Š” ์ผ์ข…์˜ ์‹ ๊ธฐ๋ฃจ๋กœ์„œ React ๊ฒฐ๊ณผ๋ฌผ์ธ HTML ์Šค๋ƒ…์ƒท์„ ๋งŒ๋“ค์–ด ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๊ฐ‘์ž๊ธฐ ๋‹ค๋ฅธ ์ปจํ…์ธ ๋ฅผ ๋ณด์—ฌ์ฃผ๊ฒŒ ๋˜๋ฉด ์‹ ๊ธฐ๋ฃจ๊ฐ€ ๊นจ์ ธ๋ฒ„๋ฆฌ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด์œ ๋กœ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•œ ๊ฒฐ๊ณผ๋ฌผ๊ณผ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ตœ์ดˆ๋กœ ๋ Œ๋”๋งํ•œ ๊ฒฐ๊ณผ๋ฌผ์ด ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. +์ด๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์œ„ํ•ด์„œ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์„œ๋ฒ„์—์„œ ๋งŒ๋“ค์–ด์ง„ HTML์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๋‘˜๋Ÿฌ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์•ฑ์˜ ๋กœ๋”ฉ์„ ๋” ๋น ๋ฅด๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„๋Š” ์ผ์ข…์˜ ์‹ ๊ธฐ๋ฃจ๋กœ์„œ React ๊ฒฐ๊ณผ๋ฌผ์ธ HTML ์Šค๋ƒ…์ƒท์„ ๋งŒ๋“ค์–ด ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๊ฐ‘์ž๊ธฐ ๋‹ค๋ฅธ ์ปจํ…์ธ ๋ฅผ ๋ณด์—ฌ์ฃผ๊ฒŒ ๋˜๋ฉด ์‹ ๊ธฐ๋ฃจ๊ฐ€ ๊นจ์ ธ๋ฒ„๋ฆฌ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด์œ ๋กœ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•œ ๊ฒฐ๊ณผ๋ฌผ๊ณผ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ตœ์ดˆ๋กœ ๋ Œ๋”๋งํ•œ ๊ฒฐ๊ณผ๋ฌผ์ด ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. -์ฃผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ์›์ธ์œผ๋กœ hydration ์—๋Ÿฌ๊ฐ€ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. +์ฃผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ์›์ธ๋“ค๋กœ Hydration ์˜ค๋ฅ˜๊ฐ€ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. -* React๋ฅผ ํ†ตํ•ด ๋งŒ๋“ค์–ด์ง„ HTML์˜ root node์•ˆ์— ์ƒˆ ์ค„๊ฐ™์€ ์ถ”๊ฐ€์ ์ธ ๊ณต๋ฐฑ. -* `typeof window !== 'undefined'`๊ณผ ๊ฐ™์€ ์กฐ๊ฑด์„ ๋ Œ๋”๋ง ๋กœ์ง์—์„œ ์‚ฌ์šฉํ•จ. -* [`window.matchMedia`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia)๊ฐ™์€ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ API๋ฅผ ๋ Œ๋”๋ง ๋กœ์ง์— ์‚ฌ์šฉํ•จ. -* ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ Œ๋”๋งํ•จ. +* React๋ฅผ ํ†ตํ•ด ๋งŒ๋“ค์–ด์ง„ HTML์˜ ๋ฃจํŠธ ๋…ธ๋“œ์•ˆ์— ๊ณต๋ฐฑ ํ˜น์€ ๊ฐœํ–‰๊ฐ™์€ ์ถ”๊ฐ€์ ์ธ ๊ณต๋ฐฑ. +* `typeof window !== 'undefined'`๊ณผ ๊ฐ™์€ ์กฐ๊ฑด์„ ๋ Œ๋”๋ง ๋กœ์ง์—์„œ ์‚ฌ์šฉ. +* [`window.matchMedia`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia)๊ฐ™์€ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ API๋ฅผ ๋ Œ๋”๋ง ๋กœ์ง์— ์‚ฌ์šฉ. +* ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ Œ๋”๋ง. -React๋Š” hydration ์—๋Ÿฌ์—์„œ ๋ณต๊ตฌ๋ฉ๋‹ˆ๋‹ค, ํ•˜์ง€๋งŒ **๋‹ค๋ฅธ ๋ฒ„๊ทธ๋“ค๊ณผ ๊ฐ™์ด ๋ฐ˜๋“œ์‹œ ๊ณ ์ณ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.** ๊ฐ€์žฅ ๋‚˜์€ ๊ฒฝ์šฐ๋Š” ๊ทธ์ € ๋А๋ ค์ง€๊ธฐ๋งŒ ํ•  ๋ฟ์ด์ง€๋งŒ, ์ตœ์•…์˜ ๊ฒฝ์šฐ์—” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋‹ค๋ฅธ ์—˜๋ฆฌ๋จผํŠธ์— ๋ถ™์–ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. +React๋Š” Hydration ์˜ค๋ฅ˜์—์„œ ๋ณต๊ตฌ๋ฉ๋‹ˆ๋‹ค, ํ•˜์ง€๋งŒ **๋‹ค๋ฅธ ๋ฒ„๊ทธ๋“ค๊ณผ ๊ฐ™์ด ๋ฐ˜๋“œ์‹œ ๊ณ ์ณ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.** ๊ฐ€์žฅ ๋‚˜์€ ๊ฒฝ์šฐ๋Š” ๊ทธ์ € ๋А๋ ค์ง€๊ธฐ๋งŒ ํ•  ๋ฟ์ด์ง€๋งŒ, ์ตœ์•…์˜ ๊ฒฝ์šฐ์—” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋‹ค๋ฅธ ์š”์†ŒElement์— ๋ถ™์–ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค. --- -### document ์ „์ฒด๋ฅผ hydrateํ•˜๊ธฐ {/*hydrating-an-entire-document*/} +### `document` ์ „์ฒด๋ฅผ Hydrateํ•˜๊ธฐ {/*hydrating-an-entire-document*/} -React๋กœ ์•ฑ์„ ๋ชจ๋‘ ๋งŒ๋“ค์—ˆ์„ ๊ฒฝ์šฐ [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html)ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•ด JSX๋กœ ๋œ ์ „์ฒด document๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +React๋กœ ์•ฑ์„ ๋ชจ๋‘ ๋งŒ๋“ค์—ˆ์„ ๊ฒฝ์šฐ [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html) ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•ด JSX๋กœ ๋œ ์ „์ฒด `document`๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js {3,13} function App() { @@ -223,7 +219,7 @@ function App() { } ``` -์ „์ฒด document๋ฅผ hydrateํ•˜๊ธฐ ์œ„ํ•ด์„  ๊ธ€๋กœ๋ฒŒ ๋ณ€์ˆ˜์ธ [`document`](https://developer.mozilla.org/en-US/docs/Web/API/Window/document)๋ฅผ `hydrateRoot`์˜ ์ฒซ๋ฒˆ์งธ ์ธ์ž๋กœ ๋„˜๊น๋‹ˆ๋‹ค: +์ „์ฒด `document`๋ฅผ Hydrateํ•˜๊ธฐ ์œ„ํ•ด์„  ์ „์—ญ ๋ณ€์ˆ˜์ธ [`document`](https://developer.mozilla.org/en-US/docs/Web/API/Window/document)๋ฅผ `hydrateRoot`์˜ ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ๋„˜๊น๋‹ˆ๋‹ค. ```js {4} import { hydrateRoot } from 'react-dom/client'; @@ -234,11 +230,11 @@ hydrateRoot(document, ); --- -### ์–ด์ฉ” ์ˆ˜ ์—†๋Š” hydration ๋ถˆ์ผ์น˜ ์—๋Ÿฌ ์–ต์ œํ•˜๊ธฐ {/*suppressing-unavoidable-hydration-mismatch-errors*/} +### ์–ด์ฉ” ์ˆ˜ ์—†๋Š” Hydration ๋ถˆ์ผ์น˜ ์˜ค๋ฅ˜ ์–ต์ œํ•˜๊ธฐ {/*suppressing-unavoidable-hydration-mismatch-errors*/} -์–ด๋–ค ์—˜๋ฆฌ๋จผํŠธ์˜ ์†์„ฑ์ด๋‚˜ text content๊ฐ€ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์–ด์ฉ” ์ˆ˜ ์—†์ด ๋‹ค๋ฅผ ๋•(์˜ˆ๋ฅผ ๋“ค์–ด, timestamp๋ฅผ ์ด์šฉํ–ˆ๋‹ค๊ฑฐ๋‚˜), hydration ๋ถˆ์ผ์น˜ ๊ฒฝ๊ณ ๋ฅผ ์•ˆ๋ณด์ด๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์–ด๋–ค ์š”์†ŒElement์˜ ์†์„ฑ์ด๋‚˜ ํ…์ŠคํŠธ ์ปจํ…์ธ ๊ฐ€ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์–ด์ฉ” ์ˆ˜ ์—†์ด ๋‹ค๋ฅผ ๋•(์˜ˆ๋ฅผ ๋“ค์–ด, timestamp๋ฅผ ์ด์šฉํ–ˆ๋‹ค๊ฑฐ๋‚˜), Hydration ๋ถˆ์ผ์น˜ ๊ฒฝ๊ณ ๋ฅผ ์•ˆ๋ณด์ด๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -ํ•ด๋‹น ์—˜๋ฆฌ๋จผํŠธ์—์„œ hydration ๊ฒฝ๊ณ ๋ฅผ ๋„๊ธฐ ์œ„ํ•ด์„  `suppressHydrationWarning={true}`๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. +ํ•ด๋‹น ์š”์†Œ์—์„œ Hydration ๊ฒฝ๊ณ ๋ฅผ ๋„๊ธฐ ์œ„ํ•ด์„  `suppressHydrationWarning={true}`๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. @@ -270,13 +266,13 @@ export default function App() { -์ด๊ฒƒ์€ ํ•œ ๋‹จ๊ณ„ ์•„๋ž˜๊นŒ์ง€๋งŒ ์ ์šฉ๋˜๋ฉฐ ๋น„์ƒ ํƒˆ์ถœ๊ตฌ๋ฅผ ์˜๋„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚จ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”. text context๊ฐ€ ์•„๋‹Œ ํ•œ, React๋Š” ์ž˜๋ชป๋œ ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ ๊ฐฑ์‹ ์ด ์ผ์–ด๋‚˜๊ธฐ ์ „๊นŒ์ง€๋Š” ๋ถˆ์ผ์น˜ํ•œ ์ƒํƒœ๋กœ ๋‚จ์•„์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. +์ด๊ฒƒ์€ ํ•œ ๋‹จ๊ณ„ ์•„๋ž˜๊นŒ์ง€๋งŒ ์ ์šฉ๋˜๋ฉฐ ํƒˆ์ถœ๊ตฌEscape Hatch๋ฅผ ์˜๋„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚จ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”. ํ…์ŠคํŠธ ์ปจํ…์ธ ๊ฐ€ ์•„๋‹Œ ํ•œ React๋Š” ์ž˜๋ชป๋œ ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ, ๊ฐฑ์‹ ์ด ์ผ์–ด๋‚˜๊ธฐ ์ „๊นŒ์ง€๋Š” ๋ถˆ์ผ์น˜ ์ƒํƒœ๋กœ ๋‚จ์•„์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. --- ### ์„œ๋กœ ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์ปจํ…์ธ  ๋‹ค๋ฃจ๊ธฐ {/*handling-different-client-and-server-content*/} -์˜๋„์ ์œผ๋กœ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋‚ด์šฉ์„ ๋ Œ๋”๋งํ•˜๊ธธ ์›ํ•œ๋‹ค๋ฉด, ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ Œ๋”๋งํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„์™€๋Š” ๋‹ค๋ฅธ ๊ฒƒ์„ ๋ Œ๋”๋งํ•  ๋•Œ ํด๋ผ์ด์–ธํŠธ์—์„  [Effect](/reference/react/useEffect)์—์„œ `true`๋กœ ํ• ๋‹น๋˜๋Š” `isClient`๊ฐ™์€ [์ƒํƒœ ๋ณ€์ˆ˜](/reference/react/useState)๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์˜๋„์ ์œผ๋กœ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋‚ด์šฉ์„ ๋ Œ๋”๋งํ•˜๊ธธ ์›ํ•œ๋‹ค๋ฉด, ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ Œ๋”๋งํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„์™€๋Š” ๋‹ค๋ฅธ ๊ฒƒ์„ ๋ Œ๋”๋งํ•  ๋•Œ ํด๋ผ์ด์–ธํŠธ์—์„  [Effect](/reference/react/useEffect)์—์„œ `true`๋กœ ํ• ๋‹น๋˜๋Š” `isClient`๊ฐ™์€ [State ๋ณ€์ˆ˜](/reference/react/useState)๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -316,21 +312,21 @@ export default function App() { -์ด ๋ฐฉ๋ฒ•์€ ์ฒ˜์Œ์—” ์„œ๋ฒ„์™€ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ Œ๋”๋งํ•˜๊ฒŒ ๋˜์–ด ๋ถˆ์ผ์น˜ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ฒŒ ๋˜๊ณ , hydrationํ›„์— ์ƒˆ๋กœ์šด ๊ฒฐ๊ณผ๋ฌผ์ด ๋™๊ธฐ์ ์œผ๋กœ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. +์ด ๋ฐฉ๋ฒ•์€ ์ฒ˜์Œ์—” ์„œ๋ฒ„์™€ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ Œ๋”๋งํ•˜์—ฌ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ณ , Hydration ํ›„์— ์ƒˆ๋กœ์šด ๊ฒฐ๊ณผ๋ฌผ์ด ๋™๊ธฐ์ ์œผ๋กœ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. -์ด ๋ฐฉ๋ฒ•์€ 2๋ฒˆ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— hydration์„ ๋А๋ฆฌ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋А๋ฆฐ ํ†ต์‹  ์ƒํƒœ์ผ ๊ฒฝ์šฐ์— ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์—ผ๋‘ํ•˜์„ธ์š”. ์ดˆ๊ธฐ HTML์ด ๋ Œ๋”๋œ ํ•œ์ฐธ ์ดํ›„์—์•ผ JavaScript ์ฝ”๋“œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ hydration ์ดํ›„์— ๋ฐ”๋กœ ๋‹ค๋ฅธ UI๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž์—๊ฒŒ UI๊ฐ€ ์‚๊ฑฑ๊ฑฐ๋ฆฌ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +์ด ๋ฐฉ๋ฒ•์€ ๋‘ ๋ฒˆ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Hydration์„ ๋А๋ฆฌ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋А๋ฆฐ ํ†ต์‹  ์ƒํƒœ์ผ ๊ฒฝ์šฐ์— ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์—ผ๋‘ํ•˜์„ธ์š”. ์ดˆ๊ธฐ HTML์ด ๋ Œ๋”๋ง๋œ ํ•œ์ฐธ ํ›„์—์•ผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Hydration ์ดํ›„์— ๋ฐ”๋กœ ๋‹ค๋ฅธ UI๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์šฉ์ž์—๊ฒŒ UI๊ฐ€ ์‚๊ฑฑ๊ฑฐ๋ฆฌ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --- -### hydrate๋œ root ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ {/*updating-a-hydrated-root-component*/} +### Hydration๋œ ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ {/*updating-a-hydrated-root-component*/} -root์˜ hydrating์ด ๋๋‚œ ์ดํ›„์—, [`root.render`](#root-render)๋ฅผ ํ˜ธ์ถœํ•ด React ์ปดํฌ๋„ŒํŠธ์˜ root๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **[`createRoot`](/reference/react-dom/client/createRoot)์™€๋Š” ๋‹ค๋ฅด๊ฒŒ HTML๋กœ ์ตœ์ดˆ์˜ ์ปจํ…์ธ ๊ฐ€ ์ด๋ฏธ ๋ Œ๋”๋ง ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž์ฃผ ์‚ฌ์šฉํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.** +๋ฃจํŠธ์˜ Hydration์ด ๋๋‚œ ํ›„์—, [`root.render`](#root-render)๋ฅผ ํ˜ธ์ถœํ•ด React ์ปดํฌ๋„ŒํŠธ์˜ ๋ฃจํŠธ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **[`createRoot`](/reference/react-dom/client/createRoot)์™€๋Š” ๋‹ค๋ฅด๊ฒŒ HTML๋กœ ์ตœ์ดˆ์˜ ์ปจํ…์ธ ๊ฐ€ ์ด๋ฏธ ๋ Œ๋”๋ง ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž์ฃผ ์‚ฌ์šฉํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.** -hydration ํ›„ ์–ด๋–ค ์‹œ์ ์— `root.render`๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๋ฉด, ๊ทธ๋ฆฌ๊ณ  ์ปดํฌ๋„ŒํŠธ์˜ ํŠธ๋ฆฌ ๊ตฌ์กฐ๊ฐ€ ์ด์ „์— ๋ Œ๋”๋งํ–ˆ๋˜ ๊ตฌ์กฐ์™€ ์ผ์น˜ํ•œ๋‹ค๋ฉด, React๋Š” [์ƒํƒœ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค.](/learn/preserving-and-resetting-state) input์— ์–ด๋–ป๊ฒŒ ํƒ€์ดํ•‘ํ•˜๋Š”์ง€์— ๋”ฐ๋ผ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ์ฒ˜๋Ÿผ ๋งค์ดˆ ๋งˆ๋‹ค ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐ˜๋ณต์ ์ธ `render`๋Š” ๋ฌธ์ œ ์—†์ด ๋ Œ๋”๋ง ๋œ๋‹ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: +Hydration ํ›„ ์–ด๋–ค ์‹œ์ ์— `root.render`๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๋ฉด, ๊ทธ๋ฆฌ๊ณ  ์ปดํฌ๋„ŒํŠธ์˜ ํŠธ๋ฆฌ ๊ตฌ์กฐ๊ฐ€ ์ด์ „์— ๋ Œ๋”๋งํ–ˆ๋˜ ๊ตฌ์กฐ์™€ ์ผ์น˜ํ•œ๋‹ค๋ฉด, React๋Š” [State๋ฅผ ๊ทธ๋Œ€๋กœ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค.](/learn/preserving-and-resetting-state) ์ž…๋ ฅ ์ฐฝInput์— ์–ด๋–ป๊ฒŒ ํƒ€์ดํ•‘ํ•˜๋“ ์ง€ ๊ฐ„์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ์ฒ˜๋Ÿผ ๋งค์ดˆ ๋งˆ๋‹ค ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐ˜๋ณต์ ์ธ `render`๋ฅผ ๋ฌธ์ œ ์—†์ด ๋ Œ๋”๋ง ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -371,21 +367,11 @@ export default function App({counter}) { -hydrate๋œ root์—์„œ [`root.render`](#root-render)๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ํ”ํ•œ ์ผ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ ์ค‘ ํ•œ ๊ณณ์—์„œ [useState](/reference/react/useState)๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. - -### ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ์—๋Ÿฌ์— ๋Œ€ํ•œ ๋Œ€ํ™” ์ƒ์ž ํ‘œ์‹œํ•˜๊ธฐ {/*show-a-dialog-for-uncaught-errors*/} - -<<<<<<< HEAD - +Hydration๋œ ๋ฃจํŠธ์—์„œ [`root.render`](#root-render)๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ํ”ํ•œ ์ผ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ ์ค‘ ํ•œ ๊ณณ์—์„œ [useState](/reference/react/useState)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. -`onUncaughtError`๋Š” ์ตœ์‹  React Canary ๋ฆด๋ฆฌ์Šค์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +### ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ๋Œ€ํ™” ์ƒ์ž ํ‘œ์‹œํ•˜๊ธฐ {/*show-a-dialog-for-uncaught-errors*/} - - -๊ธฐ๋ณธ์ ์œผ๋กœ React๋Š” ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๋ชจ๋“  ์—๋Ÿฌ๋ฅผ ์ฝ˜์†”์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์ž์ฒด์ ์ธ ์—๋Ÿฌ ๋ณด๊ณ  ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ์„ ํƒ์  root ์˜ต์…˜์ธ `onUncaughtError`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -======= -By default, React will log all uncaught errors to the console. To implement your own error reporting, you can provide the optional `onUncaughtError` root option: ->>>>>>> b1a249d597016c6584e4c186daa28b180cc9aafc +๊ธฐ๋ณธ์ ์œผ๋กœ React๋Š” ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ๋ชจ๋“  ์˜ค๋ฅ˜๋ฅผ ์ฝ˜์†”์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์ž์ฒด์ ์ธ ์˜ค๋ฅ˜ ๋ณด๊ณ  ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ์„ ํƒ์  ๋ฃจํŠธ ์˜ต์…˜์ธ `onUncaughtError`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ```js [[1, 7, "onUncaughtError"], [2, 7, "error", 1], [3, 7, "errorInfo"], [4, 11, "componentStack"]] import { hydrateRoot } from 'react-dom/client'; @@ -406,12 +392,12 @@ const root = hydrateRoot( root.render(); ``` -onUncaughtError ์˜ต์…˜์€ ๋‘ ๊ฐœ์˜ ์ธ์ž๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. +onUncaughtError ์˜ต์…˜์€ ๋‘ ๊ฐœ์˜ ์ธ์ˆ˜๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. -1. ๋ฐœ์ƒํ•œ ์—๋Ÿฌ. -2. ์—๋Ÿฌ์˜ componentStack์„ ํฌํ•จํ•˜๋Š” errorInfo ๊ฐ์ฒด. +1. ๋ฐœ์ƒํ•œ error. +2. ์˜ค๋ฅ˜์˜ componentStack์„ ํฌํ•จํ•˜๋Š” errorInfo ๊ฐ์ฒด. -`onUncaughtError` root ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด ์—๋Ÿฌ ๋Œ€ํ™” ์ƒ์ž๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +`onUncaughtError` ๋ฃจํŠธ ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด ์˜ค๋ฅ˜ ๋Œ€ํ™” ์ƒ์ž๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @@ -423,7 +409,7 @@ root.render();