diff --git a/README.md b/README.md
index 966131db5..182192cb5 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ This repo contains the source code and documentation powering [react.dev](https:
### Prerequisites
1. Git
-1. Node: any 12.x version starting with v12.0.0 or greater
+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
diff --git a/public/images/team/lauren.jpg b/public/images/team/lauren.jpg
index cb08b9725..26d46bd2f 100644
Binary files a/public/images/team/lauren.jpg and b/public/images/team/lauren.jpg differ
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 fd160e943..fbc4e378c 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
@@ -113,7 +113,7 @@ This will run the following codemods from `react-codemod`:
- [`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)
- [`replace-use-form-state`](https://github.com/reactjs/react-codemod?tab=readme-ov-file#replace-use-form-state)
-- [`prop-types-typescript`](TODO)
+- [`prop-types-typescript`](https://codemod.com/registry/react-prop-types-typescript)
This does not include the TypeScript changes. See [TypeScript changes](#typescript-changes) below.
diff --git a/src/content/blog/2024/12/05/react-19.md b/src/content/blog/2024/12/05/react-19.md
index 9f212209b..62a6ce464 100644
--- a/src/content/blog/2024/12/05/react-19.md
+++ b/src/content/blog/2024/12/05/react-19.md
@@ -17,7 +17,7 @@ Additions since this post was originally shared with the React 19 RC in April:
- **Pre-warming for suspended trees**: see [Improvements to Suspense](/blog/2024/04/25/react-19-upgrade-guide#improvements-to-suspense).
- **React DOM static APIs**: see [New React DOM Static APIs](#new-react-dom-static-apis).
-_The date for this post has been update to reflect the stable release date._
+_The date for this post has been updated to reflect the stable release date._
@@ -362,7 +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*/}
-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.
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.
@@ -807,4 +807,4 @@ Thanks to [Joey Arhar](https://github.com/josepharhar) for driving the design an
#### How to upgrade {/*how-to-upgrade*/}
See the [React 19 Upgrade Guide](/blog/2024/04/25/react-19-upgrade-guide) for step-by-step instructions and a full list of breaking and notable changes.
-_Note: this post was originally published 04/25/2024 and has been updated to 12/05/2024 with the stable release._
\ No newline at end of file
+_Note: this post was originally published 04/25/2024 and has been updated to 12/05/2024 with the stable release._
diff --git a/src/content/community/conferences.md b/src/content/community/conferences.md
index 8e492b1b1..d5df755bc 100644
--- a/src/content/community/conferences.md
+++ b/src/content/community/conferences.md
@@ -10,62 +10,73 @@ Do you know of a local React.js conference? Add it here! (Please keep the list c
## Upcoming Conferences {/*upcoming-conferences*/}
-### React Universe Conf 2024 {/*react-universe-conf-2024*/}
-September 5-6, 2024. Wrocław, Poland.
+### React Day Berlin 2024 {/*react-day-berlin-2024*/}
+December 13 & 16, 2024. In-person in Berlin, Germany + remote (hybrid event)
-[Website](https://www.reactuniverseconf.com/) - [Twitter](https://twitter.com/react_native_eu) - [LinkedIn](https://www.linkedin.com/events/reactuniverseconf7163919537074118657/)
+[Website](https://reactday.berlin/) - [Twitter](https://x.com/reactdayberlin)
-### React Alicante 2024 {/*react-alicante-2024*/}
-September 19-21, 2024. Alicante, Spain.
+### App.js Conf 2025 {/*appjs-conf-2025*/}
+May 28 - 30, 2025. In-person in Kraków, Poland + remote
-[Website](https://reactalicante.es/) - [Twitter](https://twitter.com/ReactAlicante) - [YouTube](https://www.youtube.com/channel/UCaSdUaITU1Cz6PvC97A7e0w)
+[Website](https://appjs.co) - [Twitter](https://twitter.com/appjsconf)
-### RenderCon Kenya 2024 {/*rendercon-kenya-2024*/}
-October 04 - 05, 2024. Nairobi, Kenya
+### React Summit 2025 {/*react-summit-2025*/}
+June 13 - 17, 2025. In-person in Amsterdam, Netherlands + remote (hybrid event)
-[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA)
+[Website](https://reactsummit.com/) - [Twitter](https://x.com/reactsummit)
-### React India 2024 {/*react-india-2024*/}
-October 17 - 19, 2024. In-person in Goa, India (hybrid event) + Oct 15 2024 - remote day
+## Past Conferences {/*past-conferences*/}
-[Website](https://www.reactindia.io) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w)
+### React Africa 2024 {/*react-africa-2024*/}
+November 29, 2024. In-person in Casablanca, Morocco (hybrid event)
-### React Brussels 2024 {/*react-brussels-2024*/}
-October 18, 2024. In-person in Brussels, Belgium (hybrid event)
+[Website](https://react-africa.com/) - [Twitter](https://x.com/BeJS_)
-[Website](https://www.react.brussels/) - [Twitter](https://x.com/BrusselsReact)
+### React Summit US 2024 {/*react-summit-us-2024*/}
+November 19 & 22, 2024. In-person in New York, USA + online (hybrid event)
-### reactjsday 2024 {/*reactjsday-2024*/}
-October 25, 2024. In-person in Verona, Italy + online (hybrid event)
+[Website](https://reactsummit.us/) - [Twitter](https://twitter.com/reactsummit) - [Videos](https://portal.gitnation.org/)
-[Website](https://2024.reactjsday.it/) - [Twitter](https://x.com/reactjsday) - [Facebook](https://www.facebook.com/GrUSP/) - [YouTube](https://www.youtube.com/c/grusp)
+### React Native London Conf 2024 {/*react-native-london-2024*/}
+November 14 & 15, 2024. In-person in London, UK
+
+[Website](https://reactnativelondon.co.uk/) - [Twitter](https://x.com/RNLConf)
### React Advanced London 2024 {/*react-advanced-london-2024*/}
October 25 & 28, 2024. In-person in London, UK + online (hybrid event)
[Website](https://reactadvanced.com/) - [Twitter](https://x.com/reactadvanced)
-### React Native London Conf 2024 {/*react-native-london-2024*/}
-November 14 & 15, 2024. In-person in London, UK
+### reactjsday 2024 {/*reactjsday-2024*/}
+October 25, 2024. In-person in Verona, Italy + online (hybrid event)
-[Website](https://reactnativelondon.co.uk/) - [Twitter](https://x.com/RNLConf)
+[Website](https://2024.reactjsday.it/) - [Twitter](https://x.com/reactjsday) - [Facebook](https://www.facebook.com/GrUSP/) - [YouTube](https://www.youtube.com/c/grusp)
-### React Summit US 2024 {/*react-summit-us-2024*/}
-November 19 & 22, 2024. In-person in New York, USA + online (hybrid event)
+### React Brussels 2024 {/*react-brussels-2024*/}
+October 18, 2024. In-person in Brussels, Belgium (hybrid event)
-[Website](https://reactsummit.us/) - [Twitter](https://twitter.com/reactsummit) - [Videos](https://portal.gitnation.org/)
+[Website](https://www.react.brussels/) - [Twitter](https://x.com/BrusselsReact)
-### React Africa 2024 {/*react-africa-2024*/}
-November 29, 2024. In-person in Casablanca, Morocco (hybrid event)
+### React India 2024 {/*react-india-2024*/}
+October 17 - 19, 2024. In-person in Goa, India (hybrid event) + Oct 15 2024 - remote day
-[Website](https://react-africa.com/) - [Twitter](https://x.com/BeJS_)
+[Website](https://www.reactindia.io) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w)
-### React Day Berlin 2024 {/*react-day-berlin-2024*/}
-December 13 & 16, 2024. In-person in Berlin, Germany + remote (hybrid event)
+### RenderCon Kenya 2024 {/*rendercon-kenya-2024*/}
+October 04 - 05, 2024. Nairobi, Kenya
-[Website](https://reactday.berlin/) - [Twitter](https://x.com/reactdayberlin)
+[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA)
+
+### React Alicante 2024 {/*react-alicante-2024*/}
+September 19-21, 2024. Alicante, Spain.
+
+[Website](https://reactalicante.es/) - [Twitter](https://twitter.com/ReactAlicante) - [YouTube](https://www.youtube.com/channel/UCaSdUaITU1Cz6PvC97A7e0w)
+
+### React Universe Conf 2024 {/*react-universe-conf-2024*/}
+September 5-6, 2024. Wrocław, Poland.
+
+[Website](https://www.reactuniverseconf.com/) - [Twitter](https://twitter.com/react_native_eu) - [LinkedIn](https://www.linkedin.com/events/reactuniverseconf7163919537074118657/)
-## Past Conferences {/*past-conferences*/}
### React Rally 2024 🐙 {/*react-rally-2024*/}
August 12-13, 2024. Park City, UT, USA
diff --git a/src/content/community/team.md b/src/content/community/team.md
index b11925407..94f31f09f 100644
--- a/src/content/community/team.md
+++ b/src/content/community/team.md
@@ -43,7 +43,7 @@ Current members of the React team are listed in alphabetical order below.
- Lauren's programming career peaked when she first discovered the `
diff --git a/src/content/learn/index.md b/src/content/learn/index.md
index a2dbf3167..72d2d0909 100644
--- a/src/content/learn/index.md
+++ b/src/content/learn/index.md
@@ -4,7 +4,7 @@ title: 快速開始
-歡迎來到 React 文件!本頁將為你介紹日常使用的 80% React 概念。
+歡迎來到 React 文件!本頁將向介紹 80% 日常使用的 React 概念。
diff --git a/src/content/learn/manipulating-the-dom-with-refs.md b/src/content/learn/manipulating-the-dom-with-refs.md
index 6d20232fb..e366ea7cc 100644
--- a/src/content/learn/manipulating-the-dom-with-refs.md
+++ b/src/content/learn/manipulating-the-dom-with-refs.md
@@ -343,75 +343,39 @@ Read more about [how this helps find bugs](/reference/react/StrictMode#fixing-bu
## Accessing another component's DOM nodes {/*accessing-another-components-dom-nodes*/}
-When you put a ref on a built-in component that outputs a browser element like ``, React will set that ref's `current` property to the corresponding DOM node (such as the actual `` in the browser).
+
+Refs are an escape hatch. Manually manipulating _another_ component's DOM nodes can make your code fragile.
+
-However, if you try to put a ref on **your own** component, like ``, by default you will get `null`. Here is an example demonstrating it. Notice how clicking the button **does not** focus the input:
+You can pass refs from parent component to child components [just like any other prop](/learn/passing-props-to-a-component).
-
-
-```js
+```js {3-4,9}
import { useRef } from 'react';
-function MyInput(props) {
- return ;
+function MyInput({ ref }) {
+ return ;
}
-export default function MyForm() {
+function MyForm() {
const inputRef = useRef(null);
-
- function handleClick() {
- inputRef.current.focus();
- }
-
- return (
- <>
-
-
- >
- );
+ return
}
```
-
-
-To help you notice the issue, React also prints an error to the console:
-
-
-
-Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
-
-
-
-This happens because by default React does not let a component access the DOM nodes of other components. Not even for its own children! This is intentional. Refs are an escape hatch that should be used sparingly. Manually manipulating _another_ component's DOM nodes makes your code even more fragile.
-
-Instead, components that _want_ to expose their DOM nodes have to **opt in** to that behavior. A component can specify that it "forwards" its ref to one of its children. Here's how `MyInput` can use the `forwardRef` API:
-
-```js
-const MyInput = forwardRef((props, ref) => {
- return ;
-});
-```
-
-This is how it works:
-
-1. `` tells React to put the corresponding DOM node into `inputRef.current`. However, it's up to the `MyInput` component to opt into that--by default, it doesn't.
-2. The `MyInput` component is declared using `forwardRef`. **This opts it into receiving the `inputRef` from above as the second `ref` argument** which is declared after `props`.
-3. `MyInput` itself passes the `ref` it received to the `` inside of it.
+In the above example, a ref is created in the parent component, `MyForm`, and is passed to the child component, `MyInput`. `MyInput` then passes the ref to ``. Because `` is a [built-in component](/reference/react-dom/components/common) React sets the `.current` property of the ref to the `` DOM element.
-Now clicking the button to focus the input works:
+The `inputRef` created in `MyForm` now points to the `` DOM element returned by `MyInput`. A click handler created in `MyForm` can access `inputRef` and call `focus()` to set the focus on ``.
```js
-import { forwardRef, useRef } from 'react';
+import { useRef } from 'react';
-const MyInput = forwardRef((props, ref) => {
- return ;
-});
+function MyInput({ ref }) {
+ return ;
+}
-export default function Form() {
+export default function MyForm() {
const inputRef = useRef(null);
function handleClick() {
@@ -431,24 +395,18 @@ export default function Form() {
-In design systems, it is a common pattern for low-level components like buttons, inputs, and so on, to forward their refs to their DOM nodes. On the other hand, high-level components like forms, lists, or page sections usually won't expose their DOM nodes to avoid accidental dependencies on the DOM structure.
-
#### Exposing a subset of the API with an imperative handle {/*exposing-a-subset-of-the-api-with-an-imperative-handle*/}
-In the above example, `MyInput` exposes the original DOM input element. This lets the parent component call `focus()` on it. However, this also lets the parent component do something else--for example, change its CSS styles. In uncommon cases, you may want to restrict the exposed functionality. You can do that with `useImperativeHandle`:
+In the above example, the ref passed to `MyInput` is passed on to the original DOM input element. This lets the parent component call `focus()` on it. However, this also lets the parent component do something else--for example, change its CSS styles. In uncommon cases, you may want to restrict the exposed functionality. You can do that with [`useImperativeHandle`](/reference/react/useImperativeHandle):
```js
-import {
- forwardRef,
- useRef,
- useImperativeHandle
-} from 'react';
+import { useRef, useImperativeHandle } from "react";
-const MyInput = forwardRef((props, ref) => {
+function MyInput({ ref }) {
const realInputRef = useRef(null);
useImperativeHandle(ref, () => ({
// Only expose focus and nothing else
@@ -456,8 +414,8 @@ const MyInput = forwardRef((props, ref) => {
realInputRef.current.focus();
},
}));
- return ;
-});
+ return ;
+};
export default function Form() {
const inputRef = useRef(null);
@@ -469,9 +427,7 @@ export default function Form() {
return (
<>
-
+
>
);
}
@@ -479,7 +435,7 @@ export default function Form() {
-Here, `realInputRef` inside `MyInput` holds the actual input DOM node. However, `useImperativeHandle` instructs React to provide your own special object as the value of a ref to the parent component. So `inputRef.current` inside the `Form` component will only have the `focus` method. In this case, the ref "handle" is not the DOM node, but the custom object you create inside `useImperativeHandle` call.
+Here, `realInputRef` inside `MyInput` holds the actual input DOM node. However, [`useImperativeHandle`](/reference/react/useImperativeHandle) instructs React to provide your own special object as the value of a ref to the parent component. So `inputRef.current` inside the `Form` component will only have the `focus` method. In this case, the ref "handle" is not the DOM node, but the custom object you create inside [`useImperativeHandle`](/reference/react/useImperativeHandle) call.
@@ -591,7 +547,7 @@ export default function TodoList() {
const newTodo = { id: nextId++, text: text };
flushSync(() => {
setText('');
- setTodos([ ...todos, newTodo]);
+ setTodos([ ...todos, newTodo]);
});
listRef.current.lastChild.scrollIntoView({
behavior: 'smooth',
diff --git a/src/content/learn/react-compiler.md b/src/content/learn/react-compiler.md
index 5362d69e1..0ae499472 100644
--- a/src/content/learn/react-compiler.md
+++ b/src/content/learn/react-compiler.md
@@ -347,7 +347,7 @@ React Compiler can verify many of the Rules of React statically, and will safely
### How do I know my components have been optimized? {/*how-do-i-know-my-components-have-been-optimized*/}
-[React Devtools](/learn/react-developer-tools) (v5.0+) has built-in support for React Compiler and will display a "Memo ✨" badge next to components that have been optimized by the compiler.
+[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.
### 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.
diff --git a/src/content/learn/react-developer-tools.md b/src/content/learn/react-developer-tools.md
index 7c5ec919e..4c247a12e 100644
--- a/src/content/learn/react-developer-tools.md
+++ b/src/content/learn/react-developer-tools.md
@@ -53,24 +53,9 @@ react-devtools
![React Developer Tools standalone](/images/docs/react-devtools-standalone.png)
## 行動裝置(React Native) {/*mobile-react-native*/}
-React 開發者工具也可以用來檢測由 [React Native](https://reactnative.dev/) 建構的應用程式。
-使用 React 開發者工具最簡單的方式就是全域安裝它:
-```bash
-# Yarn
-yarn global add react-devtools
-
-# Npm
-npm install -g react-devtools
-```
-
-接著從 terminal 打開開發者工具:
-```bash
-react-devtools
-```
-
-它應該連接到你任何在本機端執行的 React Native 應用程式。
+要檢查使用 [React Native](https://reactnative.dev/) 建立的應用程式,你可以使用 [React Native DevTools](https://reactnative.dev/docs/debugging/react-native-devtools), - 深度整合 React 開發工具的偵錯器。所有功能與瀏覽器擴充功能的工作方式相同,包括 native element 高亮顯示和選擇器。
-> 如果在幾秒鐘內沒有連接上開發者工具,請嘗試重新載入應用程式。
+[了解有關 React Native 中 debug 的更多資訊。](https://reactnative.dev/docs/debugging)
-[學習更多關於除錯 React Native 的方式。](https://reactnative.dev/docs/debugging)
+> 對於早於 0.76 的 React Native 版本,請按照上面的 [Safari 和其他瀏覽器](#safari-and-other-browsers) 指南使用獨立建置的 React DevTools。
diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md
index 047b65aa7..b3c849e72 100644
--- a/src/content/reference/react-dom/components/form.md
+++ b/src/content/reference/react-dom/components/form.md
@@ -50,7 +50,7 @@ To create interactive controls for submitting information, render the [built-in
### Handle form submission on the client {/*handle-form-submission-on-the-client*/}
-Pass a function to the `action` prop of form to run the function when the form is submitted. [`formData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) will be passed to the function as an argument so you can access the data submitted by the form. This differs from the conventional [HTML action](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action), which only accepts URLs.
+Pass a function to the `action` prop of form to run the function when the form is submitted. [`formData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) will be passed to the function as an argument so you can access the data submitted by the form. This differs from the conventional [HTML action](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action), which only accepts URLs. After the `action` function succeeds, all uncontrolled field elements in the form are reset.
@@ -117,7 +117,7 @@ function AddToCart({productId}) {
}
```
-When `
#### Providing an alternative value with `Promise.catch` {/*providing-an-alternative-value-with-promise-catch*/}
diff --git a/src/content/reference/react/useImperativeHandle.md b/src/content/reference/react/useImperativeHandle.md
index abd93cd4c..92f6e2cda 100644
--- a/src/content/reference/react/useImperativeHandle.md
+++ b/src/content/reference/react/useImperativeHandle.md
@@ -23,9 +23,9 @@ useImperativeHandle(ref, createHandle, dependencies?)
Call `useImperativeHandle` at the top level of your component to customize the ref handle it exposes:
```js
-import { forwardRef, useImperativeHandle } from 'react';
+import { useImperativeHandle } from 'react';
-const MyInput = forwardRef(function MyInput(props, ref) {
+function MyInput({ ref }) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
@@ -38,12 +38,18 @@ const MyInput = forwardRef(function MyInput(props, ref) {
#### Parameters {/*parameters*/}
-* `ref`: The `ref` you received as the second argument from the [`forwardRef` render function.](/reference/react/forwardRef#render-function)
+* `ref`: The `ref` you received as a prop to the `MyInput` component.
* `createHandle`: A function that takes no arguments and returns the ref handle you want to expose. That ref handle can have any type. Usually, you will return an object with the methods you want to expose.
* **optional** `dependencies`: The list of all reactive values referenced inside of the `createHandle` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. If a re-render resulted in a change to some dependency, or if you omitted this argument, your `createHandle` function will re-execute, and the newly created handle will be assigned to the ref.
+
+
+Starting with React 19, [`ref` is available a prop.](/blog/2024/12/05/react-19#ref-as-a-prop) In React 18 and earlier, it was necessary to get the `ref` from [`forwardRef`.](/reference/react/forwardRef)
+
+
+
#### Returns {/*returns*/}
`useImperativeHandle` returns `undefined`.
@@ -54,40 +60,38 @@ const MyInput = forwardRef(function MyInput(props, ref) {
### Exposing a custom ref handle to the parent component {/*exposing-a-custom-ref-handle-to-the-parent-component*/}
-By default, components don't expose their DOM nodes to parent components. For example, if you want the parent component of `MyInput` to [have access](/learn/manipulating-the-dom-with-refs) to the `` DOM node, you have to opt in with [`forwardRef`:](/reference/react/forwardRef)
-
-```js {4}
-import { forwardRef } from 'react';
+To expose a DOM node to the parent element, pass in the `ref` prop to the node.
-const MyInput = forwardRef(function MyInput(props, ref) {
- return ;
-});
+```js {2}
+function MyInput({ ref }) {
+ return ;
+};
```
-With the code above, [a ref to `MyInput` will receive the `` DOM node.](/reference/react/forwardRef#exposing-a-dom-node-to-the-parent-component) However, you can expose a custom value instead. To customize the exposed handle, call `useImperativeHandle` at the top level of your component:
+With the code above, [a ref to `MyInput` will receive the `` DOM node.](/learn/manipulating-the-dom-with-refs) However, you can expose a custom value instead. To customize the exposed handle, call `useImperativeHandle` at the top level of your component:
```js {4-8}
-import { forwardRef, useImperativeHandle } from 'react';
+import { useImperativeHandle } from 'react';
-const MyInput = forwardRef(function MyInput(props, ref) {
+function MyInput({ ref }) {
useImperativeHandle(ref, () => {
return {
// ... your methods ...
};
}, []);
- return ;
-});
+ return ;
+};
```
-Note that in the code above, the `ref` is no longer forwarded to the ``.
+Note that in the code above, the `ref` is no longer passed to the ``.
For example, suppose you don't want to expose the entire `` DOM node, but you want to expose two of its methods: `focus` and `scrollIntoView`. To do this, keep the real browser DOM in a separate ref. Then use `useImperativeHandle` to expose a handle with only the methods that you want the parent component to call:
```js {7-14}
-import { forwardRef, useRef, useImperativeHandle } from 'react';
+import { useRef, useImperativeHandle } from 'react';
-const MyInput = forwardRef(function MyInput(props, ref) {
+function MyInput({ ref }) {
const inputRef = useRef(null);
useImperativeHandle(ref, () => {
@@ -101,8 +105,8 @@ const MyInput = forwardRef(function MyInput(props, ref) {
};
}, []);
- return ;
-});
+ return ;
+};
```
Now, if the parent component gets a ref to `MyInput`, it will be able to call the `focus` and `scrollIntoView` methods on it. However, it will not have full access to the underlying `` DOM node.
@@ -134,9 +138,9 @@ export default function Form() {
```
```js src/MyInput.js
-import { forwardRef, useRef, useImperativeHandle } from 'react';
+import { useRef, useImperativeHandle } from 'react';
-const MyInput = forwardRef(function MyInput(props, ref) {
+function MyInput({ ref, ...props }) {
const inputRef = useRef(null);
useImperativeHandle(ref, () => {
@@ -151,7 +155,7 @@ const MyInput = forwardRef(function MyInput(props, ref) {
}, []);
return ;
-});
+};
export default MyInput;
```
@@ -195,11 +199,11 @@ export default function Page() {
```
```js src/Post.js
-import { forwardRef, useRef, useImperativeHandle } from 'react';
+import { useRef, useImperativeHandle } from 'react';
import CommentList from './CommentList.js';
import AddComment from './AddComment.js';
-const Post = forwardRef((props, ref) => {
+function Post({ ref }) {
const commentsRef = useRef(null);
const addCommentRef = useRef(null);
@@ -221,16 +225,16 @@ const Post = forwardRef((props, ref) => {
>
);
-});
+};
export default Post;
```
```js src/CommentList.js
-import { forwardRef, useRef, useImperativeHandle } from 'react';
+import { useRef, useImperativeHandle } from 'react';
-const CommentList = forwardRef(function CommentList(props, ref) {
+function CommentList({ ref }) {
const divRef = useRef(null);
useImperativeHandle(ref, () => {
@@ -252,17 +256,17 @@ const CommentList = forwardRef(function CommentList(props, ref) {
{comments}
);
-});
+}
export default CommentList;
```
```js src/AddComment.js
-import { forwardRef, useRef, useImperativeHandle } from 'react';
+import { useRef, useImperativeHandle } from 'react';
-const AddComment = forwardRef(function AddComment(props, ref) {
+function AddComment({ ref }) {
return ;
-});
+}
export default AddComment;
```
diff --git a/src/content/reference/react/useMemo.md b/src/content/reference/react/useMemo.md
index 33193ee3b..6bfaba8ee 100644
--- a/src/content/reference/react/useMemo.md
+++ b/src/content/reference/react/useMemo.md
@@ -1101,11 +1101,10 @@ function ChatRoom({ roomId }) {
}, [roomId]); // ✅ Only changes when roomId changes
useEffect(() => {
- const options = createOptions();
const connection = createConnection(options);
connection.connect();
return () => connection.disconnect();
- }, [options]); // ✅ Only changes when createOptions changes
+ }, [options]); // ✅ Only changes when options changes
// ...
```
diff --git a/src/content/reference/react/useRef.md b/src/content/reference/react/useRef.md
index 14cd9b2ec..8ab53aef3 100644
--- a/src/content/reference/react/useRef.md
+++ b/src/content/reference/react/useRef.md
@@ -448,16 +448,16 @@ button { display: block; margin-bottom: 20px; }
#### Exposing a ref to your own component {/*exposing-a-ref-to-your-own-component*/}
-Sometimes, you may want to let the parent component manipulate the DOM inside of your component. For example, maybe you're writing a `MyInput` component, but you want the parent to be able to focus the input (which the parent has no access to). You can use a combination of `useRef` to hold the input and [`forwardRef`](/reference/react/forwardRef) to expose it to the parent component. Read a [detailed walkthrough](/learn/manipulating-the-dom-with-refs#accessing-another-components-dom-nodes) here.
+Sometimes, you may want to let the parent component manipulate the DOM inside of your component. For example, maybe you're writing a `MyInput` component, but you want the parent to be able to focus the input (which the parent has no access to). You can create a `ref` in the parent and pass the `ref` as prop to the child component. Read a [detailed walkthrough](/learn/manipulating-the-dom-with-refs#accessing-another-components-dom-nodes) here.
```js
-import { forwardRef, useRef } from 'react';
+import { useRef } from 'react';
-const MyInput = forwardRef((props, ref) => {
- return ;
-});
+function MyInput({ ref }) {
+ return ;
+};
export default function Form() {
const inputRef = useRef(null);
@@ -554,7 +554,7 @@ You might get an error in the console:
-Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
+TypeError: Cannot read properties of null
@@ -573,12 +573,10 @@ export default function MyInput({ value, onChange }) {
}
```
-And then wrap it in [`forwardRef`](/reference/react/forwardRef) like this:
-
-```js {3,8}
-import { forwardRef } from 'react';
+And then add `ref` to the list of props your component accepts and pass `ref` as a prop to the relevent child [built-in component](/reference/react-dom/components/common) like this:
-const MyInput = forwardRef(({ value, onChange }, ref) => {
+```js {1,6}
+function MyInput({ value, onChange, ref }) {
return (
{
ref={ref}
/>
);
-});
+};
export default MyInput;
```
diff --git a/src/content/reference/react/useTransition.md b/src/content/reference/react/useTransition.md
index 7c019bc16..6b7c511e7 100644
--- a/src/content/reference/react/useTransition.md
+++ b/src/content/reference/react/useTransition.md
@@ -48,7 +48,7 @@ function TabContainer() {
### `startTransition(action)` {/*starttransition*/}
-The `startTransition` function returned by `useTransition` lets you mark a updates as a Transition.
+The `startTransition` function returned by `useTransition` lets you mark an update as a Transition.
```js {6,8}
function TabContainer() {
@@ -305,12 +305,12 @@ export async function updateQuantity(newQuantity) {
-This is a basic example to demonstrate how Actions work, but this example does not handle requests completing out of order. When updating the quantity multiple times, it's possible for the previous requests to finish after later requests causing the quantity to update out of order. This is a known limitation that we will fix in the future (see [Troubleshooting](#my-state-updates-in-async-transitions-are-out-of-order) below).
+This is a basic example to demonstrate how Actions work, but this example does not handle requests completing out of order. When updating the quantity multiple times, it's possible for the previous requests to finish after later requests causing the quantity to update out of order. This is a known limitation that we will fix in the future (see [Troubleshooting](#my-state-updates-in-transitions-are-out-of-order) below).
For common use cases, React provides built-in abstractions such as:
- [`useActionState`](/reference/react/useActionState)
- [`