From 3ee3a60a1bcc687c0b87039a3a6582e3b1d6887c Mon Sep 17 00:00:00 2001 From: Soichiro Miki <smiki-tky@umin.ac.jp> Date: Mon, 26 May 2025 17:56:28 +0900 Subject: [PATCH 01/16] Fix wrong explanation in preserving-and-resetting-state (#6043) --- src/content/learn/preserving-and-resetting-state.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/preserving-and-resetting-state.md b/src/content/learn/preserving-and-resetting-state.md index bf5531f35f..11d398d23f 100644 --- a/src/content/learn/preserving-and-resetting-state.md +++ b/src/content/learn/preserving-and-resetting-state.md @@ -672,7 +672,7 @@ label { </Sandpack> -The counter state gets reset when you click the checkbox. Although you render a `Counter`, the first child of the `div` changes from a `div` to a `section`. When the child `div` was removed from the DOM, the whole tree below it (including the `Counter` and its state) was destroyed as well. +The counter state gets reset when you click the checkbox. Although you render a `Counter`, the first child of the `div` changes from a `section` to a `div`. When the child `section` was removed from the DOM, the whole tree below it (including the `Counter` and its state) was destroyed as well. <DiagramGroup> From 9db23d61294ab9aa74b81471bad51db6dfbcda6b Mon Sep 17 00:00:00 2001 From: Dmitry Titov <61434098+dimatitov@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:34:46 -0300 Subject: [PATCH 02/16] fix: correct broken WAI-ARIA modal dialog link in createPortal reference (#7833) * fix link from ARIA dialog-modal * chore: trigger CLA recheck --- src/content/reference/react-dom/createPortal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react-dom/createPortal.md b/src/content/reference/react-dom/createPortal.md index c04510f80d..5717460df6 100644 --- a/src/content/reference/react-dom/createPortal.md +++ b/src/content/reference/react-dom/createPortal.md @@ -240,7 +240,7 @@ export default function ModalContent({ onClose }) { It's important to make sure that your app is accessible when using portals. For instance, you may need to manage keyboard focus so that the user can move the focus in and out of the portal in a natural way. -Follow the [WAI-ARIA Modal Authoring Practices](https://www.w3.org/WAI/ARIA/apg/#dialog_modal) when creating modals. If you use a community package, ensure that it is accessible and follows these guidelines. +Follow the [WAI-ARIA Modal Authoring Practices](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal) when creating modals. If you use a community package, ensure that it is accessible and follows these guidelines. </Pitfall> From bbcb9af1c99e1fc148ff4f02982773c407b64e4c Mon Sep 17 00:00:00 2001 From: Shubham Gupta <50445450+shubhamui@users.noreply.github.com> Date: Mon, 2 Jun 2025 21:42:59 +0530 Subject: [PATCH 03/16] Update meetups.md adding React Rajasthan Community (#7831) Adding the React Community for Rajasthan India --- src/content/community/meetups.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/community/meetups.md b/src/content/community/meetups.md index 81fc5c2104..b4da5cdffb 100644 --- a/src/content/community/meetups.md +++ b/src/content/community/meetups.md @@ -88,6 +88,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet * [Delhi NCR](https://www.meetup.com/React-Delhi-NCR/) * [Mumbai](https://reactmumbai.dev) * [Pune](https://www.meetup.com/ReactJS-and-Friends/) +* [Rajasthan](https://reactrajasthan.com) ## Indonesia {/*indonesia*/} * [Indonesia](https://www.meetup.com/reactindonesia/) From a2d17d1218aa6559537b0aad9c4c12098b4197aa Mon Sep 17 00:00:00 2001 From: "G. van Dorland" <giodor13@gmail.com> Date: Mon, 2 Jun 2025 18:15:13 +0200 Subject: [PATCH 04/16] Update components-and-hooks-must-be-pure.md (#7830) Some grammar fixes, and language clarifications --- .../reference/rules/components-and-hooks-must-be-pure.md | 6 +++--- 1 file changed, 3 insertions(+), 3 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 d3d54560ef..6da6d49bb3 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 @@ -207,7 +207,7 @@ A component's props and state are immutable [snapshots](learn/state-as-a-snapsho You can think of the props and state values as snapshots that are updated after rendering. For this reason, you don't modify the props or state variables directly: instead you pass new props, or use the setter function provided to you to tell React that state needs to update the next time the component is rendered. ### Don't mutate Props {/*props*/} -Props are immutable because if you mutate them, the application will produce inconsistent output, which can be hard to debug since it may or may not work depending on the circumstance. +Props are immutable because if you mutate them, the application will produce inconsistent output, which can be hard to debug as it may or may not work depending on the circumstances. ```js {2} function Post({ item }) { @@ -307,7 +307,7 @@ function useIconStyle(icon) { } ``` -If you were to mutate the Hooks arguments, the custom hook's memoization will become incorrect, so it's important to avoid doing that. +If you were to mutate the Hook's arguments, the custom hook's memoization will become incorrect, so it's important to avoid doing that. ```js {4} style = useIconStyle(icon); // `style` is memoized based on `icon` @@ -327,7 +327,7 @@ Similarly, it's important to not modify the return values of Hooks, as they may ## Values are immutable after being passed to JSX {/*values-are-immutable-after-being-passed-to-jsx*/} -Don't mutate values after they've been used in JSX. Move the mutation before the JSX is created. +Don't mutate values after they've been used in JSX. Move the mutation to before the JSX is created. When you use JSX in an expression, React may eagerly evaluate the JSX before the component finishes rendering. This means that mutating values after they've been passed to JSX can lead to outdated UIs, as React won't know to update the component's output. From 94424aed87efca6616c1b21945a04b69e333202e Mon Sep 17 00:00:00 2001 From: Julius Lundang <cHaLkdusT@users.noreply.github.com> Date: Tue, 3 Jun 2025 00:18:57 +0800 Subject: [PATCH 05/16] Update referencing-values-with-refs.md (#7829) Fixed invalid URL --- src/content/learn/referencing-values-with-refs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/referencing-values-with-refs.md b/src/content/learn/referencing-values-with-refs.md index 4faf18786f..fab6599f26 100644 --- a/src/content/learn/referencing-values-with-refs.md +++ b/src/content/learn/referencing-values-with-refs.md @@ -464,7 +464,7 @@ export default function Toggle() { #### Fix debouncing {/*fix-debouncing*/} -In this example, all button click handlers are ["debounced".](https://redd.one/blog/debounce-vs-throttle) To see what this means, press one of the buttons. Notice how the message appears a second later. If you press the button while waiting for the message, the timer will reset. So if you keep clicking the same button fast many times, the message won't appear until a second *after* you stop clicking. Debouncing lets you delay some action until the user "stops doing things". +In this example, all button click handlers are ["debounced".](https://kettanaito.com/blog/debounce-vs-throttle) To see what this means, press one of the buttons. Notice how the message appears a second later. If you press the button while waiting for the message, the timer will reset. So if you keep clicking the same button fast many times, the message won't appear until a second *after* you stop clicking. Debouncing lets you delay some action until the user "stops doing things". This example works, but not quite as intended. The buttons are not independent. To see the problem, click one of the buttons, and then immediately click another button. You'd expect that after a delay, you would see both button's messages. But only the last button's message shows up. The first button's message gets lost. From 172f0b995857a7ac4c5c5e5ca7ea90e36cce9ca0 Mon Sep 17 00:00:00 2001 From: jinsoo <89149734+Jinsoo1004@users.noreply.github.com> Date: Tue, 3 Jun 2025 01:33:18 +0900 Subject: [PATCH 06/16] Add uwu click animation (#7822) --- src/components/Layout/TopNav/TopNav.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/Layout/TopNav/TopNav.tsx b/src/components/Layout/TopNav/TopNav.tsx index cc5c654e3d..a4b431189e 100644 --- a/src/components/Layout/TopNav/TopNav.tsx +++ b/src/components/Layout/TopNav/TopNav.tsx @@ -266,7 +266,9 @@ export default function TopNav({ <BrandMenu> <div className="flex items-center"> <div className="uwu-visible flex items-center justify-center h-full"> - <NextLink href="/"> + <NextLink + href="/" + className="active:scale-95 transition-transform"> <Image alt="logo by @sawaratsuki1004" title="logo by @sawaratsuki1004" From 3dcc4c4ac0e6b3d0b9db4a247c49f44d0ad8d1ab Mon Sep 17 00:00:00 2001 From: John Kapantzakis <kapantzak@gmail.com> Date: Mon, 2 Jun 2025 19:34:02 +0300 Subject: [PATCH 07/16] Fix typo and clarily that a server function reference is created only when that function is used by a Client Component (#7746) --- src/content/reference/rsc/server-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/rsc/server-functions.md b/src/content/reference/rsc/server-functions.md index 770f5a705e..2603c10992 100644 --- a/src/content/reference/rsc/server-functions.md +++ b/src/content/reference/rsc/server-functions.md @@ -28,7 +28,7 @@ To support Server Functions as a bundler or framework, we recommend pinning to a </Note> -When a Server Function 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. +When a Server Function 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. 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. From 06965de1d062a477f71f53c204051e770b65c822 Mon Sep 17 00:00:00 2001 From: Mike DiDomizio <mikedidomizio@gmail.com> Date: Mon, 2 Jun 2025 12:34:47 -0400 Subject: [PATCH 08/16] Add React Alicante 2025 to Conferences page (#7674) --- src/content/community/conferences.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/content/community/conferences.md b/src/content/community/conferences.md index a2bcd196e4..a97f3d5b42 100644 --- a/src/content/community/conferences.md +++ b/src/content/community/conferences.md @@ -45,6 +45,11 @@ September 2-4, 2025. Wrocław, Poland. [Website](https://www.reactuniverseconf.com/) - [Twitter](https://twitter.com/react_native_eu) - [LinkedIn](https://www.linkedin.com/events/reactuniverseconf7163919537074118657/) +### React Alicante 2025 {/*react-alicante-2025*/} +October 2-4, 2025. Alicante, Spain. + +[Website](https://reactalicante.es/) - [Twitter](https://x.com/ReactAlicante) - [Bluesky](https://bsky.app/profile/reactalicante.es) - [YouTube](https://www.youtube.com/channel/UCaSdUaITU1Cz6PvC97A7e0w) + ### React Conf 2025 {/*react-conf-2025*/} October 7-8, 2025. Henderson, Nevada, USA and free livestream From e90179047b1e7dd1ef19a37eed52765d8e04c484 Mon Sep 17 00:00:00 2001 From: Aakansha Doshi <aakansha1216@gmail.com> Date: Mon, 2 Jun 2025 22:06:20 +0530 Subject: [PATCH 09/16] fix: use const where applicable in examples for keeping components pure (#7819) --- src/content/learn/keeping-components-pure.md | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/content/learn/keeping-components-pure.md b/src/content/learn/keeping-components-pure.md index 6d4f55763f..70049e58e2 100644 --- a/src/content/learn/keeping-components-pure.md +++ b/src/content/learn/keeping-components-pure.md @@ -175,7 +175,7 @@ function Cup({ guest }) { } export default function TeaGathering() { - let cups = []; + const cups = []; for (let i = 1; i <= 12; i++) { cups.push(<Cup key={i} guest={i} />); } @@ -245,7 +245,7 @@ Rendering is a *calculation*, it shouldn't try to "do" things. Can you express t ```js src/Clock.js active export default function Clock({ time }) { - let hours = time.getHours(); + const hours = time.getHours(); if (hours >= 0 && hours <= 6) { document.getElementById('time').className = 'night'; } else { @@ -307,7 +307,7 @@ You can fix this component by calculating the `className` and including it in th ```js src/Clock.js active export default function Clock({ time }) { - let hours = time.getHours(); + const hours = time.getHours(); let className; if (hours >= 0 && hours <= 6) { className = 'night'; @@ -606,14 +606,14 @@ export default function StoryTray({ stories }) { import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; -let initialStories = [ +const initialStories = [ {id: 0, label: "Ankit's Story" }, {id: 1, label: "Taylor's Story" }, ]; export default function App() { - let [stories, setStories] = useState([...initialStories]) - let time = useTime(); + const [stories, setStories] = useState([...initialStories]) + const time = useTime(); // HACK: Prevent the memory from growing forever while you read docs. // We're breaking our own rules here. @@ -702,14 +702,14 @@ export default function StoryTray({ stories }) { import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; -let initialStories = [ +const initialStories = [ {id: 0, label: "Ankit's Story" }, {id: 1, label: "Taylor's Story" }, ]; export default function App() { - let [stories, setStories] = useState([...initialStories]) - let time = useTime(); + const [stories, setStories] = useState([...initialStories]) + const time = useTime(); // HACK: Prevent the memory from growing forever while you read docs. // We're breaking our own rules here. @@ -770,7 +770,7 @@ Alternatively, you could create a _new_ array (by copying the existing one) befo ```js src/StoryTray.js active export default function StoryTray({ stories }) { // Copy the array! - let storiesToDisplay = stories.slice(); + const storiesToDisplay = stories.slice(); // Does not affect the original array: storiesToDisplay.push({ @@ -794,14 +794,14 @@ export default function StoryTray({ stories }) { import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; -let initialStories = [ +const initialStories = [ {id: 0, label: "Ankit's Story" }, {id: 1, label: "Taylor's Story" }, ]; export default function App() { - let [stories, setStories] = useState([...initialStories]) - let time = useTime(); + const [stories, setStories] = useState([...initialStories]) + const time = useTime(); // HACK: Prevent the memory from growing forever while you read docs. // We're breaking our own rules here. From 87cef4a918be9873c9fed9115688de46e657ee71 Mon Sep 17 00:00:00 2001 From: Jan Kassens <jkassens@meta.com> Date: Tue, 3 Jun 2025 12:28:27 -0400 Subject: [PATCH 10/16] Remove `forwardRef` reference from API listing (#7837) This API is now under "Legacy APIs" and should probably no longer be listed as a "modern API". --- src/content/reference/react/apis.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/content/reference/react/apis.md b/src/content/reference/react/apis.md index cbab4a0e6f..6cb990908a 100644 --- a/src/content/reference/react/apis.md +++ b/src/content/reference/react/apis.md @@ -11,7 +11,6 @@ In addition to [Hooks](/reference/react) and [Components](/reference/react/compo --- * [`createContext`](/reference/react/createContext) lets you define and provide context to the child components. Used with [`useContext`.](/reference/react/useContext) -* [`forwardRef`](/reference/react/forwardRef) lets your component expose a DOM node as a ref to the parent. Used with [`useRef`.](/reference/react/useRef) * [`lazy`](/reference/react/lazy) lets you defer loading a component's code until it's rendered for the first time. * [`memo`](/reference/react/memo) lets your component skip re-renders with same props. Used with [`useMemo`](/reference/react/useMemo) and [`useCallback`.](/reference/react/useCallback) * [`startTransition`](/reference/react/startTransition) lets you mark a state update as non-urgent. Similar to [`useTransition`.](/reference/react/useTransition) From c60173f9a4be1021260327716fc4f3ba26295d4e Mon Sep 17 00:00:00 2001 From: minami yoshihiko <ymym1990ymym@gmail.com> Date: Wed, 4 Jun 2025 01:29:34 +0900 Subject: [PATCH 11/16] docs: Refactor context provider usage (#7793) * delete provider * Fix NavContext usage in Talks component * Fix TocContext and LanguagesContext usage in Page component * Fix IllustrationContext usage in IllustrationBlock component * Fix LevelContext and TasksContext usage in managing-state.md * Fix ThemeContext and Context usage in MyApp component * Fix HighlightContext usage in List component * Fix ThemeContext usage in MyApp component * Fix ErrorDecoderContext usage in ErrorDecoderPage component * Fix ThemeContext usage in MyPage and MyApp components * Fix ThemeContext usage in MyApp component * Fix useContext documentation to correct context provider references * Fix context provider references in createContext documentation * prettier * Update src/content/reference/react/createContext.md --------- Co-authored-by: Ricky <rickhanlonii@gmail.com> --- src/components/Layout/HomeContent.js | 4 +- src/components/Layout/Page.tsx | 8 +- src/components/MDX/MDXComponents.tsx | 4 +- src/content/learn/managing-state.md | 12 +-- .../scaling-up-with-reducer-and-context.md | 56 +++++------ src/content/learn/typescript.md | 8 +- src/content/reference/react/Component.md | 8 +- src/content/reference/react/cloneElement.md | 8 +- src/content/reference/react/createContext.md | 27 ++--- src/content/reference/react/memo.md | 4 +- src/content/reference/react/use.md | 8 +- src/content/reference/react/useContext.md | 98 +++++++++---------- src/pages/errors/[errorCode].tsx | 4 +- 13 files changed, 124 insertions(+), 125 deletions(-) diff --git a/src/components/Layout/HomeContent.js b/src/components/Layout/HomeContent.js index 83f5fa4f2e..22b75016b6 100644 --- a/src/components/Layout/HomeContent.js +++ b/src/components/Layout/HomeContent.js @@ -1172,7 +1172,7 @@ async function Talks({ confId }) { </CodeBlock> } right={ - <NavContext.Provider value={{slug, navigate}}> + <NavContext value={{slug, navigate}}> <BrowserChrome domain="example.com" path={'confs/' + slug} @@ -1192,7 +1192,7 @@ async function Talks({ confId }) { </Suspense> </ExamplePanel> </BrowserChrome> - </NavContext.Provider> + </NavContext> } /> ); diff --git a/src/components/Layout/Page.tsx b/src/components/Layout/Page.tsx index ec3a6eba0c..c3224e5174 100644 --- a/src/components/Layout/Page.tsx +++ b/src/components/Layout/Page.tsx @@ -82,11 +82,9 @@ export function Page({ 'max-w-7xl mx-auto', section === 'blog' && 'lg:flex lg:flex-col lg:items-center' )}> - <TocContext.Provider value={toc}> - <LanguagesContext.Provider value={languages}> - {children} - </LanguagesContext.Provider> - </TocContext.Provider> + <TocContext value={toc}> + <LanguagesContext value={languages}>{children}</LanguagesContext> + </TocContext> </div> {!isBlogIndex && ( <DocsPageFooter diff --git a/src/components/MDX/MDXComponents.tsx b/src/components/MDX/MDXComponents.tsx index 1da353f609..36774ad4b2 100644 --- a/src/components/MDX/MDXComponents.tsx +++ b/src/components/MDX/MDXComponents.tsx @@ -354,7 +354,7 @@ function IllustrationBlock({ </figure> )); return ( - <IllustrationContext.Provider value={isInBlockTrue}> + <IllustrationContext value={isInBlockTrue}> <div className="relative group before:absolute before:-inset-y-16 before:inset-x-0 my-16 mx-0 2xl:mx-auto max-w-4xl 2xl:max-w-6xl"> {sequential ? ( <ol className="mdx-illustration-block flex"> @@ -369,7 +369,7 @@ function IllustrationBlock({ )} <AuthorCredit author={author} authorLink={authorLink} /> </div> - </IllustrationContext.Provider> + </IllustrationContext> ); } diff --git a/src/content/learn/managing-state.md b/src/content/learn/managing-state.md index 93bcc10fd6..f2f02c64b9 100644 --- a/src/content/learn/managing-state.md +++ b/src/content/learn/managing-state.md @@ -741,9 +741,9 @@ export default function Section({ children }) { const level = useContext(LevelContext); return ( <section className="section"> - <LevelContext.Provider value={level + 1}> + <LevelContext value={level + 1}> {children} - </LevelContext.Provider> + </LevelContext> </section> ); } @@ -836,13 +836,13 @@ export function TasksProvider({ children }) { ); return ( - <TasksContext.Provider value={tasks}> - <TasksDispatchContext.Provider + <TasksContext value={tasks}> + <TasksDispatchContext value={dispatch} > {children} - </TasksDispatchContext.Provider> - </TasksContext.Provider> + </TasksDispatchContext> + </TasksContext> ); } diff --git a/src/content/learn/scaling-up-with-reducer-and-context.md b/src/content/learn/scaling-up-with-reducer-and-context.md index c3da0c6373..e193333b9b 100644 --- a/src/content/learn/scaling-up-with-reducer-and-context.md +++ b/src/content/learn/scaling-up-with-reducer-and-context.md @@ -461,11 +461,11 @@ export default function TaskApp() { const [tasks, dispatch] = useReducer(tasksReducer, initialTasks); // ... return ( - <TasksContext.Provider value={tasks}> - <TasksDispatchContext.Provider value={dispatch}> + <TasksContext value={tasks}> + <TasksDispatchContext value={dispatch}> ... - </TasksDispatchContext.Provider> - </TasksContext.Provider> + </TasksDispatchContext> + </TasksContext> ); } ``` @@ -509,8 +509,8 @@ export default function TaskApp() { } return ( - <TasksContext.Provider value={tasks}> - <TasksDispatchContext.Provider value={dispatch}> + <TasksContext value={tasks}> + <TasksDispatchContext value={dispatch}> <h1>Day off in Kyoto</h1> <AddTask onAddTask={handleAddTask} @@ -520,8 +520,8 @@ export default function TaskApp() { onChangeTask={handleChangeTask} onDeleteTask={handleDeleteTask} /> - </TasksDispatchContext.Provider> - </TasksContext.Provider> + </TasksDispatchContext> + </TasksContext> ); } @@ -676,13 +676,13 @@ In the next step, you will remove prop passing. Now you don't need to pass the list of tasks or the event handlers down the tree: ```js {4-5} -<TasksContext.Provider value={tasks}> - <TasksDispatchContext.Provider value={dispatch}> +<TasksContext value={tasks}> + <TasksDispatchContext value={dispatch}> <h1>Day off in Kyoto</h1> <AddTask /> <TaskList /> - </TasksDispatchContext.Provider> -</TasksContext.Provider> + </TasksDispatchContext> +</TasksContext> ``` Instead, any component that needs the task list can read it from the `TaskContext`: @@ -730,13 +730,13 @@ export default function TaskApp() { ); return ( - <TasksContext.Provider value={tasks}> - <TasksDispatchContext.Provider value={dispatch}> + <TasksContext value={tasks}> + <TasksDispatchContext value={dispatch}> <h1>Day off in Kyoto</h1> <AddTask /> <TaskList /> - </TasksDispatchContext.Provider> - </TasksContext.Provider> + </TasksDispatchContext> + </TasksContext> ); } @@ -921,11 +921,11 @@ export function TasksProvider({ children }) { const [tasks, dispatch] = useReducer(tasksReducer, initialTasks); return ( - <TasksContext.Provider value={tasks}> - <TasksDispatchContext.Provider value={dispatch}> + <TasksContext value={tasks}> + <TasksDispatchContext value={dispatch}> {children} - </TasksDispatchContext.Provider> - </TasksContext.Provider> + </TasksDispatchContext> + </TasksContext> ); } ``` @@ -963,11 +963,11 @@ export function TasksProvider({ children }) { ); return ( - <TasksContext.Provider value={tasks}> - <TasksDispatchContext.Provider value={dispatch}> + <TasksContext value={tasks}> + <TasksDispatchContext value={dispatch}> {children} - </TasksDispatchContext.Provider> - </TasksContext.Provider> + </TasksDispatchContext> + </TasksContext> ); } @@ -1174,11 +1174,11 @@ export function TasksProvider({ children }) { ); return ( - <TasksContext.Provider value={tasks}> - <TasksDispatchContext.Provider value={dispatch}> + <TasksContext value={tasks}> + <TasksDispatchContext value={dispatch}> {children} - </TasksDispatchContext.Provider> - </TasksContext.Provider> + </TasksDispatchContext> + </TasksContext> ); } diff --git a/src/content/learn/typescript.md b/src/content/learn/typescript.md index 7edf8eb6ed..bf7483d1cf 100644 --- a/src/content/learn/typescript.md +++ b/src/content/learn/typescript.md @@ -260,9 +260,9 @@ export default function MyApp() { const [theme, setTheme] = useState<Theme>('light'); return ( - <ThemeContext.Provider value={theme}> + <ThemeContext value={theme}> <MyComponent /> - </ThemeContext.Provider> + </ThemeContext> ) } @@ -310,9 +310,9 @@ export default function MyApp() { const object = useMemo(() => ({ kind: "complex" }), []); return ( - <Context.Provider value={object}> + <Context value={object}> <MyComponent /> - </Context.Provider> + </Context> ) } diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index 8e58af8ff6..09acbc7d69 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -1814,9 +1814,9 @@ function Form() { export default function MyApp() { return ( - <ThemeContext.Provider value="dark"> + <ThemeContext value="dark"> <Form /> - </ThemeContext.Provider> + </ThemeContext> ) } ``` @@ -1900,9 +1900,9 @@ function Form() { export default function MyApp() { return ( - <ThemeContext.Provider value="dark"> + <ThemeContext value="dark"> <Form /> - </ThemeContext.Provider> + </ThemeContext> ) } ``` diff --git a/src/content/reference/react/cloneElement.md b/src/content/reference/react/cloneElement.md index 6bcea51b05..4e29ff203b 100644 --- a/src/content/reference/react/cloneElement.md +++ b/src/content/reference/react/cloneElement.md @@ -414,9 +414,9 @@ export default function List({ items, renderItem }) { {items.map((item, index) => { const isHighlighted = index === selectedIndex; return ( - <HighlightContext.Provider key={item.id} value={isHighlighted}> + <HighlightContext key={item.id} value={isHighlighted}> {renderItem(item)} - </HighlightContext.Provider> + </HighlightContext> ); })} ``` @@ -472,12 +472,12 @@ export default function List({ items, renderItem }) { {items.map((item, index) => { const isHighlighted = index === selectedIndex; return ( - <HighlightContext.Provider + <HighlightContext key={item.id} value={isHighlighted} > {renderItem(item)} - </HighlightContext.Provider> + </HighlightContext> ); })} <hr /> diff --git a/src/content/reference/react/createContext.md b/src/content/reference/react/createContext.md index 03b09f8af9..5b2cc0eb22 100644 --- a/src/content/reference/react/createContext.md +++ b/src/content/reference/react/createContext.md @@ -38,14 +38,15 @@ const ThemeContext = createContext('light'); `createContext` returns a context object. -**The context object itself does not hold any information.** It represents _which_ context other components read or provide. Typically, you will use [`SomeContext.Provider`](#provider) in components above to specify the context value, and call [`useContext(SomeContext)`](/reference/react/useContext) in components below to read it. The context object has a few properties: +**The context object itself does not hold any information.** It represents _which_ context other components read or provide. Typically, you will use [`SomeContext`](#provider) in components above to specify the context value, and call [`useContext(SomeContext)`](/reference/react/useContext) in components below to read it. The context object has a few properties: -* `SomeContext.Provider` lets you provide the context value to components. +* `SomeContext` lets you provide the context value to components. * `SomeContext.Consumer` is an alternative and rarely used way to read the context value. +* `SomeContext.Provider` is a legacy way to provide the context value before React 19. --- -### `SomeContext.Provider` {/*provider*/} +### `SomeContext` {/*provider*/} Wrap your components into a context provider to specify the value of this context for all components inside: @@ -54,9 +55,9 @@ function App() { const [theme, setTheme] = useState('light'); // ... return ( - <ThemeContext.Provider value={theme}> + <ThemeContext value={theme}> <Page /> - </ThemeContext.Provider> + </ThemeContext> ); } ``` @@ -141,11 +142,11 @@ function App() { // ... return ( - <ThemeContext.Provider value={theme}> - <AuthContext.Provider value={currentUser}> + <ThemeContext value={theme}> + <AuthContext value={currentUser}> <Page /> - </AuthContext.Provider> - </ThemeContext.Provider> + </AuthContext> + </ThemeContext> ); } ``` @@ -187,11 +188,11 @@ import { ThemeContext, AuthContext } from './Contexts.js'; function App() { // ... return ( - <ThemeContext.Provider value={theme}> - <AuthContext.Provider value={currentUser}> + <ThemeContext value={theme}> + <AuthContext value={currentUser}> <Page /> - </AuthContext.Provider> - </ThemeContext.Provider> + </AuthContext> + </ThemeContext> ); } ``` diff --git a/src/content/reference/react/memo.md b/src/content/reference/react/memo.md index 26fa9ed9cc..01d6290f1a 100644 --- a/src/content/reference/react/memo.md +++ b/src/content/reference/react/memo.md @@ -226,12 +226,12 @@ export default function MyApp() { } return ( - <ThemeContext.Provider value={theme}> + <ThemeContext value={theme}> <button onClick={handleClick}> Switch theme </button> <Greeting name="Taylor" /> - </ThemeContext.Provider> + </ThemeContext> ); } diff --git a/src/content/reference/react/use.md b/src/content/reference/react/use.md index 557a71cad2..91e19c4b45 100644 --- a/src/content/reference/react/use.md +++ b/src/content/reference/react/use.md @@ -74,9 +74,9 @@ To pass context to a `Button`, wrap it or one of its parent components into the ```js [[1, 3, "ThemeContext"], [2, 3, "\\"dark\\""], [1, 5, "ThemeContext"]] function MyPage() { return ( - <ThemeContext.Provider value="dark"> + <ThemeContext value="dark"> <Form /> - </ThemeContext.Provider> + </ThemeContext> ); } @@ -116,9 +116,9 @@ const ThemeContext = createContext(null); export default function MyApp() { return ( - <ThemeContext.Provider value="dark"> + <ThemeContext value="dark"> <Form /> - </ThemeContext.Provider> + </ThemeContext> ) } diff --git a/src/content/reference/react/useContext.md b/src/content/reference/react/useContext.md index ce06e7035d..f69c49af98 100644 --- a/src/content/reference/react/useContext.md +++ b/src/content/reference/react/useContext.md @@ -38,11 +38,11 @@ function MyComponent() { #### Returns {/*returns*/} -`useContext` returns the context value for the calling component. It is determined as the `value` passed to the closest `SomeContext.Provider` above the calling component in the tree. If there is no such provider, then the returned value will be the `defaultValue` you have passed to [`createContext`](/reference/react/createContext) for that context. The returned value is always up-to-date. React automatically re-renders components that read some context if it changes. +`useContext` returns the context value for the calling component. It is determined as the `value` passed to the closest `SomeContext` above the calling component in the tree. If there is no such provider, then the returned value will be the `defaultValue` you have passed to [`createContext`](/reference/react/createContext) for that context. The returned value is always up-to-date. React automatically re-renders components that read some context if it changes. #### Caveats {/*caveats*/} -* `useContext()` call in a component is not affected by providers returned from the *same* component. The corresponding `<Context.Provider>` **needs to be *above*** the component doing the `useContext()` call. +* `useContext()` call in a component is not affected by providers returned from the *same* component. The corresponding `<Context>` **needs to be *above*** the component doing the `useContext()` call. * React **automatically re-renders** all the children that use a particular context starting from the provider that receives a different `value`. The previous and the next values are compared with the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. Skipping re-renders with [`memo`](/reference/react/memo) does not prevent the children receiving fresh context values. * If your build system produces duplicates modules in the output (which can happen with symlinks), this can break context. Passing something via context only works if `SomeContext` that you use to provide context and `SomeContext` that you use to read it are ***exactly* the same object**, as determined by a `===` comparison. @@ -70,9 +70,9 @@ To pass context to a `Button`, wrap it or one of its parent components into the ```js [[1, 3, "ThemeContext"], [2, 3, "\\"dark\\""], [1, 5, "ThemeContext"]] function MyPage() { return ( - <ThemeContext.Provider value="dark"> + <ThemeContext value="dark"> <Form /> - </ThemeContext.Provider> + </ThemeContext> ); } @@ -98,9 +98,9 @@ const ThemeContext = createContext(null); export default function MyApp() { return ( - <ThemeContext.Provider value="dark"> + <ThemeContext value="dark"> <Form /> - </ThemeContext.Provider> + </ThemeContext> ) } @@ -183,14 +183,14 @@ Often, you'll want the context to change over time. To update context, combine i function MyPage() { const [theme, setTheme] = useState('dark'); return ( - <ThemeContext.Provider value={theme}> + <ThemeContext value={theme}> <Form /> <Button onClick={() => { setTheme('light'); }}> Switch to light theme </Button> - </ThemeContext.Provider> + </ThemeContext> ); } ``` @@ -213,7 +213,7 @@ const ThemeContext = createContext(null); export default function MyApp() { const [theme, setTheme] = useState('light'); return ( - <ThemeContext.Provider value={theme}> + <ThemeContext value={theme}> <Form /> <label> <input @@ -225,7 +225,7 @@ export default function MyApp() { /> Use dark mode </label> - </ThemeContext.Provider> + </ThemeContext> ) } @@ -317,14 +317,14 @@ const CurrentUserContext = createContext(null); export default function MyApp() { const [currentUser, setCurrentUser] = useState(null); return ( - <CurrentUserContext.Provider + <CurrentUserContext value={{ currentUser, setCurrentUser }} > <Form /> - </CurrentUserContext.Provider> + </CurrentUserContext> ); } @@ -411,8 +411,8 @@ export default function MyApp() { const [theme, setTheme] = useState('light'); const [currentUser, setCurrentUser] = useState(null); return ( - <ThemeContext.Provider value={theme}> - <CurrentUserContext.Provider + <ThemeContext value={theme}> + <CurrentUserContext value={{ currentUser, setCurrentUser @@ -429,8 +429,8 @@ export default function MyApp() { /> Use dark mode </label> - </CurrentUserContext.Provider> - </ThemeContext.Provider> + </CurrentUserContext> + </ThemeContext> ) } @@ -596,16 +596,16 @@ export default function MyApp() { function MyProviders({ children, theme, setTheme }) { const [currentUser, setCurrentUser] = useState(null); return ( - <ThemeContext.Provider value={theme}> - <CurrentUserContext.Provider + <ThemeContext value={theme}> + <CurrentUserContext value={{ currentUser, setCurrentUser }} > {children} - </CurrentUserContext.Provider> - </ThemeContext.Provider> + </CurrentUserContext> + </ThemeContext> ); } @@ -775,11 +775,11 @@ export function TasksProvider({ children }) { ); return ( - <TasksContext.Provider value={tasks}> - <TasksDispatchContext.Provider value={dispatch}> + <TasksContext value={tasks}> + <TasksDispatchContext value={dispatch}> {children} - </TasksDispatchContext.Provider> - </TasksContext.Provider> + </TasksDispatchContext> + </TasksContext> ); } @@ -978,9 +978,9 @@ export default function MyApp() { const [theme, setTheme] = useState('light'); return ( <> - <ThemeContext.Provider value={theme}> + <ThemeContext value={theme}> <Form /> - </ThemeContext.Provider> + </ThemeContext> <Button onClick={() => { setTheme(theme === 'dark' ? 'light' : 'dark'); }}> @@ -1067,13 +1067,13 @@ function Button({ children, onClick }) { You can override the context for a part of the tree by wrapping that part in a provider with a different value. ```js {3,5} -<ThemeContext.Provider value="dark"> +<ThemeContext value="dark"> ... - <ThemeContext.Provider value="light"> + <ThemeContext value="light"> <Footer /> - </ThemeContext.Provider> + </ThemeContext> ... -</ThemeContext.Provider> +</ThemeContext> ``` You can nest and override providers as many times as you need. @@ -1093,9 +1093,9 @@ const ThemeContext = createContext(null); export default function MyApp() { return ( - <ThemeContext.Provider value="dark"> + <ThemeContext value="dark"> <Form /> - </ThemeContext.Provider> + </ThemeContext> ) } @@ -1104,9 +1104,9 @@ function Form() { <Panel title="Welcome"> <Button>Sign up</Button> <Button>Log in</Button> - <ThemeContext.Provider value="light"> + <ThemeContext value="light"> <Footer /> - </ThemeContext.Provider> + </ThemeContext> </Panel> ); } @@ -1230,9 +1230,9 @@ export default function Section({ children }) { const level = useContext(LevelContext); return ( <section className="section"> - <LevelContext.Provider value={level + 1}> + <LevelContext value={level + 1}> {children} - </LevelContext.Provider> + </LevelContext> </section> ); } @@ -1302,9 +1302,9 @@ function MyApp() { } return ( - <AuthContext.Provider value={{ currentUser, login }}> + <AuthContext value={{ currentUser, login }}> <Page /> - </AuthContext.Provider> + </AuthContext> ); } ``` @@ -1330,9 +1330,9 @@ function MyApp() { }), [currentUser, login]); return ( - <AuthContext.Provider value={contextValue}> + <AuthContext value={contextValue}> <Page /> - </AuthContext.Provider> + </AuthContext> ); } ``` @@ -1349,8 +1349,8 @@ Read more about [`useMemo`](/reference/react/useMemo#skipping-re-rendering-of-co There are a few common ways that this can happen: -1. You're rendering `<SomeContext.Provider>` in the same component (or below) as where you're calling `useContext()`. Move `<SomeContext.Provider>` *above and outside* the component calling `useContext()`. -2. You may have forgotten to wrap your component with `<SomeContext.Provider>`, or you might have put it in a different part of the tree than you thought. Check whether the hierarchy is right using [React DevTools.](/learn/react-developer-tools) +1. You're rendering `<SomeContext>` in the same component (or below) as where you're calling `useContext()`. Move `<SomeContext>` *above and outside* the component calling `useContext()`. +2. You may have forgotten to wrap your component with `<SomeContext>`, or you might have put it in a different part of the tree than you thought. Check whether the hierarchy is right using [React DevTools.](/learn/react-developer-tools) 3. You might be running into some build issue with your tooling that causes `SomeContext` as seen from the providing component and `SomeContext` as seen by the reading component to be two different objects. This can happen if you use symlinks, for example. You can verify this by assigning them to globals like `window.SomeContext1` and `window.SomeContext2` and then checking whether `window.SomeContext1 === window.SomeContext2` in the console. If they're not the same, fix that issue on the build tool level. ### I am always getting `undefined` from my context although the default value is different {/*i-am-always-getting-undefined-from-my-context-although-the-default-value-is-different*/} @@ -1359,9 +1359,9 @@ You might have a provider without a `value` in the tree: ```js {1,2} // 🚩 Doesn't work: no value prop -<ThemeContext.Provider> +<ThemeContext> <Button /> -</ThemeContext.Provider> +</ThemeContext> ``` If you forget to specify `value`, it's like passing `value={undefined}`. @@ -1370,18 +1370,18 @@ You may have also mistakingly used a different prop name by mistake: ```js {1,2} // 🚩 Doesn't work: prop should be called "value" -<ThemeContext.Provider theme={theme}> +<ThemeContext theme={theme}> <Button /> -</ThemeContext.Provider> +</ThemeContext> ``` In both of these cases you should see a warning from React in the console. To fix them, call the prop `value`: ```js {1,2} // ✅ Passing the value prop -<ThemeContext.Provider value={theme}> +<ThemeContext value={theme}> <Button /> -</ThemeContext.Provider> +</ThemeContext> ``` -Note that the [default value from your `createContext(defaultValue)` call](#specifying-a-fallback-default-value) is only used **if there is no matching provider above at all.** If there is a `<SomeContext.Provider value={undefined}>` component somewhere in the parent tree, the component calling `useContext(SomeContext)` *will* receive `undefined` as the context value. +Note that the [default value from your `createContext(defaultValue)` call](#specifying-a-fallback-default-value) is only used **if there is no matching provider above at all.** If there is a `<SomeContext value={undefined}>` component somewhere in the parent tree, the component calling `useContext(SomeContext)` *will* receive `undefined` as the context value. diff --git a/src/pages/errors/[errorCode].tsx b/src/pages/errors/[errorCode].tsx index a67c5742d7..c8cf28ad82 100644 --- a/src/pages/errors/[errorCode].tsx +++ b/src/pages/errors/[errorCode].tsx @@ -26,7 +26,7 @@ export default function ErrorDecoderPage({ ); return ( - <ErrorDecoderContext.Provider value={{errorMessage, errorCode}}> + <ErrorDecoderContext value={{errorMessage, errorCode}}> <Page toc={[]} meta={{ @@ -48,7 +48,7 @@ export default function ErrorDecoderPage({ <ErrorDecoder /> </MaxWidth> */} </Page> - </ErrorDecoderContext.Provider> + </ErrorDecoderContext> ); } From 37b09ea82c52c64d6fdeaf1cbca2db71765ed900 Mon Sep 17 00:00:00 2001 From: Kunall Banerjee <14703164+yeskunall@users.noreply.github.com> Date: Tue, 3 Jun 2025 13:03:40 -0400 Subject: [PATCH 12/16] fix: typo in docs on prerendering (#7823) --- src/content/reference/react-dom/static/prerender.md | 7 +++---- .../reference/react-dom/static/prerenderToNodeStream.md | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/content/reference/react-dom/static/prerender.md b/src/content/reference/react-dom/static/prerender.md index aac6d96b51..4bbf6c35da 100644 --- a/src/content/reference/react-dom/static/prerender.md +++ b/src/content/reference/react-dom/static/prerender.md @@ -68,7 +68,7 @@ On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to #### Caveats {/*caveats*/} -`nonce` is not an available option when prerendering. Nonces must be unique per request and if you use nonces to secure your application with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) it would be inappropriate and insecure to include the a nonce value in the prerender itself. +`nonce` is not an available option when prerendering. Nonces must be unique per request and if you use nonces to secure your application with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) it would be inappropriate and insecure to include the nonce value in the prerender itself. <Note> @@ -231,7 +231,7 @@ async function renderToString() { const {prelude} = await prerender(<App />, { bootstrapScripts: ['/main.js'] }); - + const reader = prelude.getReader(); let content = ''; while (true) { @@ -317,7 +317,6 @@ Any Suspense boundaries with incomplete children will be included in the prelude ### 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 diff --git a/src/content/reference/react-dom/static/prerenderToNodeStream.md b/src/content/reference/react-dom/static/prerenderToNodeStream.md index fb8073ef07..cc99c52d4e 100644 --- a/src/content/reference/react-dom/static/prerenderToNodeStream.md +++ b/src/content/reference/react-dom/static/prerenderToNodeStream.md @@ -69,7 +69,7 @@ On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to #### Caveats {/*caveats*/} -`nonce` is not an available option when prerendering. Nonces must be unique per request and if you use nonces to secure your application with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) it would be inappropriate and insecure to include the a nonce value in the prerender itself. +`nonce` is not an available option when prerendering. Nonces must be unique per request and if you use nonces to secure your application with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) it would be inappropriate and insecure to include the nonce value in the prerender itself. <Note> @@ -95,7 +95,7 @@ app.use('/', async (request, response) => { const { prelude } = await prerenderToNodeStream(<App />, { bootstrapScripts: ['/main.js'], }); - + response.setHeader('Content-Type', 'text/plain'); prelude.pipe(response); }); @@ -232,7 +232,7 @@ async function renderToString() { const {prelude} = await prerenderToNodeStream(<App />, { bootstrapScripts: ['/main.js'] }); - + return new Promise((resolve, reject) => { let data = ''; prelude.on('data', chunk => { @@ -320,4 +320,3 @@ Any Suspense boundaries with incomplete children will be included in the prelude 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). - From 5927c4e7d3fcb7ae84a09bc5c7717bfb3ac08c26 Mon Sep 17 00:00:00 2001 From: Jan Kassens <jkassens@meta.com> Date: Tue, 3 Jun 2025 15:08:53 -0400 Subject: [PATCH 13/16] Replace Context.Provider with Context (#7838) Update to be in line with the recommended way from React 19. Docs https://react.dev/blog/2024/12/05/react-19#context-as-a-provider --------- Co-authored-by: Ricky <rickhanlonii@gmail.com> --- src/content/learn/managing-state.md | 4 +--- .../learn/scaling-up-with-reducer-and-context.md | 1 - src/content/reference/react/createContext.md | 11 +++++++++-- src/content/reference/react/legacy.md | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/content/learn/managing-state.md b/src/content/learn/managing-state.md index f2f02c64b9..ef7b76e04c 100644 --- a/src/content/learn/managing-state.md +++ b/src/content/learn/managing-state.md @@ -837,9 +837,7 @@ export function TasksProvider({ children }) { return ( <TasksContext value={tasks}> - <TasksDispatchContext - value={dispatch} - > + <TasksDispatchContext value={dispatch}> {children} </TasksDispatchContext> </TasksContext> diff --git a/src/content/learn/scaling-up-with-reducer-and-context.md b/src/content/learn/scaling-up-with-reducer-and-context.md index e193333b9b..91fb6803fb 100644 --- a/src/content/learn/scaling-up-with-reducer-and-context.md +++ b/src/content/learn/scaling-up-with-reducer-and-context.md @@ -1363,4 +1363,3 @@ As your app grows, you may have many context-reducer pairs like this. This is a - You can have many context-reducer pairs like this in your app. </Recap> - diff --git a/src/content/reference/react/createContext.md b/src/content/reference/react/createContext.md index 5b2cc0eb22..2161fa63c6 100644 --- a/src/content/reference/react/createContext.md +++ b/src/content/reference/react/createContext.md @@ -46,7 +46,7 @@ const ThemeContext = createContext('light'); --- -### `SomeContext` {/*provider*/} +### `SomeContext` Provider {/*provider*/} Wrap your components into a context provider to specify the value of this context for all components inside: @@ -62,6 +62,14 @@ function App() { } ``` +<Note> + +Starting in React 19, you can render `<SomeContext>` as a provider. + +In older versions of React, use `<SomeContext.Provider>`. + +</Note> + #### Props {/*provider-props*/} * `value`: The value that you want to pass to all the components reading this context inside this provider, no matter how deep. The context value can be of any type. A component calling [`useContext(SomeContext)`](/reference/react/useContext) inside of the provider receives the `value` of the innermost corresponding context provider above it. @@ -215,4 +223,3 @@ const ThemeContext = createContext('light'); This value never changes. React only uses this value as a fallback if it can't find a matching provider above. To make context change over time, [add state and wrap components in a context provider.](/reference/react/useContext#updating-data-passed-via-context) - diff --git a/src/content/reference/react/legacy.md b/src/content/reference/react/legacy.md index b22a9c97ee..f4e3ebe289 100644 --- a/src/content/reference/react/legacy.md +++ b/src/content/reference/react/legacy.md @@ -30,6 +30,6 @@ These APIs were removed in React 19: * [`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 getChildContext`](https://18.react.dev//reference/react/Component#getchildcontext): use [`Context`](/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. From 5dca5201881bedcda8baaaac1c9376f796c1b23c Mon Sep 17 00:00:00 2001 From: Amirhossein Alibakhshi <amir78729@gmail.com> Date: Tue, 3 Jun 2025 22:39:55 +0330 Subject: [PATCH 14/16] =?UTF-8?q?fix(blog):=20resolve=20typo=20in=20React?= =?UTF-8?q?=2019=20blog=20post=20(`refs`=20=E2=86=92=20`ref`s)=20(#7828)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR corrects a small typo in the React documentation, changing "`refs`" to "`ref`s" for accuracy and consistency. --- src/content/blog/2024/12/05/react-19.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/blog/2024/12/05/react-19.md b/src/content/blog/2024/12/05/react-19.md index aac80a44fb..65bf42757a 100644 --- a/src/content/blog/2024/12/05/react-19.md +++ b/src/content/blog/2024/12/05/react-19.md @@ -410,7 +410,7 @@ New function components will no longer need `forwardRef`, and we will be publish <Note> -`refs` passed to classes are not passed as props since they reference the component instance. +`ref`s passed to classes are not passed as props since they reference the component instance. </Note> From 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 Mon Sep 17 00:00:00 2001 From: Jatin Singh <jadenrizz31@gmail.com> Date: Fri, 6 Jun 2025 21:16:39 +0530 Subject: [PATCH 15/16] Update analyze_comment.yml (#7840) --- .github/workflows/analyze_comment.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/analyze_comment.yml b/.github/workflows/analyze_comment.yml index 1e086b9b70..fcac377386 100644 --- a/.github/workflows/analyze_comment.yml +++ b/.github/workflows/analyze_comment.yml @@ -6,8 +6,11 @@ on: types: - completed -permissions: {} - +permissions: + contents: read + issues: write + pull-requests: write + jobs: comment: runs-on: ubuntu-latest From 981c9cf415b99f1b8a5abc2ee16f962f41ce520e Mon Sep 17 00:00:00 2001 From: Xleine <xleine@qq.com> Date: Wed, 11 Jun 2025 10:04:02 +0800 Subject: [PATCH 16/16] fix conflict --- .github/workflows/analyze_comment.yml | 3 -- src/content/blog/2024/12/05/react-19.md | 6 +-- .../learn/preserving-and-resetting-state.md | 6 +-- .../learn/referencing-values-with-refs.md | 6 +-- .../reference/react-dom/createPortal.md | 6 +-- .../reference/react-dom/static/prerender.md | 7 --- src/content/reference/react/apis.md | 9 ---- src/content/reference/react/createContext.md | 21 +++------ src/content/reference/react/legacy.md | 11 +---- src/content/reference/react/useContext.md | 45 +++---------------- .../components-and-hooks-must-be-pure.md | 14 ------ 11 files changed, 15 insertions(+), 119 deletions(-) diff --git a/.github/workflows/analyze_comment.yml b/.github/workflows/analyze_comment.yml index 7c5af46dcb..85e9d69181 100644 --- a/.github/workflows/analyze_comment.yml +++ b/.github/workflows/analyze_comment.yml @@ -6,14 +6,11 @@ on: types: - completed -<<<<<<< HEAD -======= permissions: contents: read issues: write pull-requests: write ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 jobs: comment: runs-on: ubuntu-latest diff --git a/src/content/blog/2024/12/05/react-19.md b/src/content/blog/2024/12/05/react-19.md index 47db8817d3..c6c5ba6d2b 100644 --- a/src/content/blog/2024/12/05/react-19.md +++ b/src/content/blog/2024/12/05/react-19.md @@ -410,11 +410,7 @@ function MyInput({placeholder, ref}) { <Note> -<<<<<<< HEAD -在类组件中,`ref` 不作为 props 传递,因为它们引用的是组件实例。这意味着,如果你在类组件中需要访问 `ref`,你需要使用 `React.forwardRef` 或者 `React.createRef`。 -======= -`ref`s passed to classes are not passed as props since they reference the component instance. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 +在类组件中,`ref` 不作为 props 传递,因为它们引用的是组件实例。 </Note> diff --git a/src/content/learn/preserving-and-resetting-state.md b/src/content/learn/preserving-and-resetting-state.md index fda51635aa..c89b640337 100644 --- a/src/content/learn/preserving-and-resetting-state.md +++ b/src/content/learn/preserving-and-resetting-state.md @@ -676,11 +676,7 @@ label { </Sandpack> -<<<<<<< HEAD -当你勾选复选框后计数器的 state 被重置了。虽然你渲染了一个 `Counter`,但是 `div` 的第一个子组件从 `div` 变成了 `section`。当子组件 `div` 从 DOM 中被移除的时候,它底下的整棵树(包含 `Counter` 以及它的 state)也都被销毁了。 -======= -The counter state gets reset when you click the checkbox. Although you render a `Counter`, the first child of the `div` changes from a `section` to a `div`. When the child `section` was removed from the DOM, the whole tree below it (including the `Counter` and its state) was destroyed as well. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 +当你勾选复选框后计数器的 state 被重置了。虽然你渲染了一个 `Counter`,但是 `div` 的第一个子组件从 `section` 变成了 `div`。当子组件 `section` 从 DOM 中被移除的时候,它底下的整棵树(包含 `Counter` 以及它的 state)也都被销毁了。 <DiagramGroup> diff --git a/src/content/learn/referencing-values-with-refs.md b/src/content/learn/referencing-values-with-refs.md index 1af0e342d7..409431a386 100644 --- a/src/content/learn/referencing-values-with-refs.md +++ b/src/content/learn/referencing-values-with-refs.md @@ -467,11 +467,7 @@ export default function Toggle() { #### 修复防抖 {/*fix-debouncing*/} -<<<<<<< HEAD -在这个例子中,所有按钮点击处理器都是 ["防抖的"](https://redd.one/blog/debounce-vs-throttle)。 要了解这意味着什么,请按下其中一个按钮。注意消息在一秒后显示。如果你在等待消息时按下按钮,计时器将重置。因此如果你多次快速单击同一个按钮,则直到你停止单击 **之后** 1 秒钟,该消息才会显示。防抖可以让你将一些动作推迟到用户“停止动作”之后。 -======= -In this example, all button click handlers are ["debounced".](https://kettanaito.com/blog/debounce-vs-throttle) To see what this means, press one of the buttons. Notice how the message appears a second later. If you press the button while waiting for the message, the timer will reset. So if you keep clicking the same button fast many times, the message won't appear until a second *after* you stop clicking. Debouncing lets you delay some action until the user "stops doing things". ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 +在这个例子中,所有按钮点击处理器都是 ["防抖的"](https://kettanaito.com/blog/debounce-vs-throttle)。 要了解这意味着什么,请按下其中一个按钮。注意消息在一秒后显示。如果你在等待消息时按下按钮,计时器将重置。因此如果你多次快速单击同一个按钮,则直到你停止单击 **之后** 1 秒钟,该消息才会显示。防抖可以让你将一些动作推迟到用户“停止动作”之后。 这个例子可以正常运行,但并不完全符合预期。按钮不是独立的。要查看问题,请单击其中一个按钮,然后立即单击另一个按钮。你本来期望在延迟之后,你会看到两个按钮的消息。但只有最后一个按钮的消息出现了。第一个按钮的消息丢失了。 diff --git a/src/content/reference/react-dom/createPortal.md b/src/content/reference/react-dom/createPortal.md index b57dc17d8c..4fa5b54785 100644 --- a/src/content/reference/react-dom/createPortal.md +++ b/src/content/reference/react-dom/createPortal.md @@ -240,11 +240,7 @@ export default function ModalContent({ onClose }) { 使用 portal 时,确保应用程序的无障碍性非常重要。例如,你可能需要管理键盘焦点,以便用户可以自然进出 portal。 -<<<<<<< HEAD -创建模态对话框时,请遵循 [WAI-ARIA 模态实践指南](https://www.w3.org/WAI/ARIA/apg/#dialog_modal)。如果你使用了社区包,请确保它具有无障碍性,并遵循这些指南。 -======= -Follow the [WAI-ARIA Modal Authoring Practices](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal) when creating modals. If you use a community package, ensure that it is accessible and follows these guidelines. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 +创建模态对话框时,请遵循 [WAI-ARIA 模态实践指南](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal)。如果你使用了社区包,请确保它具有无障碍性,并遵循这些指南。 </Pitfall> diff --git a/src/content/reference/react-dom/static/prerender.md b/src/content/reference/react-dom/static/prerender.md index 1c3b98a57a..5880259653 100644 --- a/src/content/reference/react-dom/static/prerender.md +++ b/src/content/reference/react-dom/static/prerender.md @@ -318,13 +318,6 @@ async function renderToString() { ### 我的流要等到整个应用渲染完成后才会启动。 {/*my-stream-doesnt-start-until-the-entire-app-is-rendered*/} -<<<<<<< HEAD `prerender` 的响应会等待整个应用渲染完成,包括所有 Suspense 边界的内容加载完成后,才会解析。这种设计适用于静态站点生成(SSG),并不支持在内容加载时进行流式加载。 如果需要在内容加载时进行流式加载,可以使用类似 [renderToReadableStream](/reference/react-dom/server/renderToReadableStream) 的流式服务器渲染 API。 - -======= -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). ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 diff --git a/src/content/reference/react/apis.md b/src/content/reference/react/apis.md index d279cc966c..31276bde71 100644 --- a/src/content/reference/react/apis.md +++ b/src/content/reference/react/apis.md @@ -13,20 +13,11 @@ translators: --- -<<<<<<< HEAD * [`createContext`](/reference/react/createContext) API 可以创建一个 context,你可以将其提供给子组件,通常会与 [`useContext`](/reference/react/useContext) 一起配合使用。 -* [`forwardRef`](/reference/react/forwardRef) 允许组件将 DOM 节点作为 ref 暴露给父组件。 * [`lazy`](/reference/react/lazy) 允许你延迟加载组件,直到该组件需要第一次被渲染。 * [`memo`](/reference/react/memo) 允许你在 props 没有变化的情况下跳过组件的重渲染。通常 [`useMemo`](/reference/react/useMemo) 与 [`useCallback`](/reference/react/useCallback) 会一起配合使用。 * [`startTransition`](/reference/react/startTransition) 允许你可以标记一个状态更新是不紧急的。类似于 [`useTransition`](/reference/react/useTransition)。 * [`act`](/reference/react/act) 允许你在测试中包装渲染和交互,以确保在断言之前已完成更新。 -======= -* [`createContext`](/reference/react/createContext) lets you define and provide context to the child components. Used with [`useContext`.](/reference/react/useContext) -* [`lazy`](/reference/react/lazy) lets you defer loading a component's code until it's rendered for the first time. -* [`memo`](/reference/react/memo) lets your component skip re-renders with same props. Used with [`useMemo`](/reference/react/useMemo) and [`useCallback`.](/reference/react/useCallback) -* [`startTransition`](/reference/react/startTransition) lets you mark a state update as non-urgent. Similar to [`useTransition`.](/reference/react/useTransition) -* [`act`](/reference/react/act) lets you wrap renders and interactions in tests to ensure updates have processed before making assertions. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 --- diff --git a/src/content/reference/react/createContext.md b/src/content/reference/react/createContext.md index df84ab0c47..ad8f9249bb 100644 --- a/src/content/reference/react/createContext.md +++ b/src/content/reference/react/createContext.md @@ -38,18 +38,11 @@ const ThemeContext = createContext('light'); `createContext` 返回一个上下文对象。 -<<<<<<< HEAD -**该上下文对象本身不包含任何信息**。它只表示其他组件读取或提供的那个上下文。一般来说,在组件上方使用 [`SomeContext.Provider`](#provider) 指定上下文的值,并在被包裹的下方组件内调用 [`useContext(SomeContext)`](/reference/react/useContext) 读取它。上下文对象有一些属性: +**该上下文对象本身不包含任何信息**。它只表示其他组件读取或提供的那个上下文。一般来说,在组件上方使用 [`SomeContext`](#provider) 指定上下文的值,并在被包裹的下方组件内调用 [`useContext(SomeContext)`](/reference/react/useContext) 读取它。上下文对象有一些属性: -* `SomeContext.Provider` 让你为被它包裹的组件提供上下文的值。 +* `SomeContext` 为组件提供上下文的值。 * `SomeContext.Consumer` 是一个很少会用到的备选方案,它用于读取上下文的值。 -======= -**The context object itself does not hold any information.** It represents _which_ context other components read or provide. Typically, you will use [`SomeContext`](#provider) in components above to specify the context value, and call [`useContext(SomeContext)`](/reference/react/useContext) in components below to read it. The context object has a few properties: - -* `SomeContext` lets you provide the context value to components. -* `SomeContext.Consumer` is an alternative and rarely used way to read the context value. -* `SomeContext.Provider` is a legacy way to provide the context value before React 19. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 +* `SomeContext.Provider` 是在 React 19 之前提供上下文值的遗留方法。 --- @@ -71,9 +64,9 @@ function App() { <Note> -Starting in React 19, you can render `<SomeContext>` as a provider. +从 React 19 开始,你可以将 `<SomeContext>` 作为渲染的上下文 provider。 -In older versions of React, use `<SomeContext.Provider>`. +较旧版本的 React 需要使用 `<SomeContext.Provider>`。 </Note> @@ -229,9 +222,5 @@ const ThemeContext = createContext('light'); 该值永远不会发生改变。当 React 无法找到匹配的 provider 时,该值会被作为后备方案。 -<<<<<<< HEAD 要想使上下文的值随时间变化,[添加状态并使用一个上下文 provider 包裹组件](/reference/react/useContext#updating-data-passed-via-context)。 -======= -To make context change over time, [add state and wrap components in a context provider.](/reference/react/useContext#updating-data-passed-via-context) ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 diff --git a/src/content/reference/react/legacy.md b/src/content/reference/react/legacy.md index 62cca6a70a..3892ae5e4e 100644 --- a/src/content/reference/react/legacy.md +++ b/src/content/reference/react/legacy.md @@ -27,18 +27,9 @@ title: "过时的 React API" 这些 API 在 React 19 中被移除。 -<<<<<<< HEAD * [`createFactory`](https://18.react.dev/reference/react/createFactory):使用 JSX 来替代。 * 类组件:[`static contextTypes`](https://18.react.dev//reference/react/Component#static-contexttypes): 使用 [`static contextType`](#static-contexttype) 来替代。 * 类组件:[`static childContextTypes`](https://18.react.dev//reference/react/Component#static-childcontexttypes): 使用 [`static contextType`](#static-contexttype) 来替代。 -* 类组件:[`static getChildContext`](https://18.react.dev//reference/react/Component#getchildcontext): 使用 [`Context.Provider`](/reference/react/createContext#provider) 来替代。 +* 类组件:[`static getChildContext`](https://18.react.dev//reference/react/Component#getchildcontext): 使用 [`Context`](/reference/react/createContext#provider) 来替代。 * 类组件:[`static propTypes`](https://18.react.dev//reference/react/Component#static-proptypes): 使用 [TypeScript](https://www.typescriptlang.org/) 等类型系统来替代。 * 类组件:[`this.refs`](https://18.react.dev//reference/react/Component#refs): 使用 [`createRef`](/reference/react/createRef) 来替代。 -======= -* [`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`](/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. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 diff --git a/src/content/reference/react/useContext.md b/src/content/reference/react/useContext.md index 5d93d37777..b9e1e0de4d 100644 --- a/src/content/reference/react/useContext.md +++ b/src/content/reference/react/useContext.md @@ -38,23 +38,13 @@ function MyComponent() { #### 返回值 {/*returns*/} -<<<<<<< HEAD -`useContext` 为调用组件返回 context 的值。它被确定为传递给树中调用组件上方最近的 `SomeContext.Provider` 的 `value`。如果没有这样的 provider,那么返回值将会是为创建该 context 传递给 [`createContext`](/reference/react/createContext) 的 `defaultValue`。返回的值始终是最新的。如果 context 发生变化,React 会自动重新渲染读取 context 的组件。 -======= -`useContext` returns the context value for the calling component. It is determined as the `value` passed to the closest `SomeContext` above the calling component in the tree. If there is no such provider, then the returned value will be the `defaultValue` you have passed to [`createContext`](/reference/react/createContext) for that context. The returned value is always up-to-date. React automatically re-renders components that read some context if it changes. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 +`useContext` 为调用组件返回 context 的值。它被确定为传递给树中调用组件上方最近的 `SomeContext` 的 `value`。如果没有这样的 provider,那么返回值将会是为创建该 context 传递给 [`createContext`](/reference/react/createContext) 的 `defaultValue`。返回的值始终是最新的。如果 context 发生变化,React 会自动重新渲染读取 context 的组件。 #### 注意事项 {/*caveats*/} -<<<<<<< HEAD -* 组件中的 `useContext()` 调用不受 **同一** 组件返回的 provider 的影响。相应的 `<Context.Provider>` 需要位于调用 `useContext()` 的组件 **之上**。 +* 组件中的 `useContext()` 调用不受 **同一** 组件返回的 provider 的影响。相应的 `<Context>` 需要位于调用 `useContext()` 的组件 **之上**。 * 从 provider 接收到不同的 `value` 开始,React 自动重新渲染使用了该特定 context 的所有子级。先前的值和新的值会使用 [`Object.is`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/is) 来做比较。使用 [`memo`](/reference/react/memo) 来跳过重新渲染并不妨碍子级接收到新的 context 值。 * 如果你的构建系统在输出中产生重复的模块(可能发生在符号链接中),这可能会破坏 context。通过 context 传递数据只有在用于传递 context 的 `SomeContext` 和用于读取数据的 `SomeContext` 是完全相同的对象时才有效,这是由 `===` 比较决定的。 -======= -* `useContext()` call in a component is not affected by providers returned from the *same* component. The corresponding `<Context>` **needs to be *above*** the component doing the `useContext()` call. -* React **automatically re-renders** all the children that use a particular context starting from the provider that receives a different `value`. The previous and the next values are compared with the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison. Skipping re-renders with [`memo`](/reference/react/memo) does not prevent the children receiving fresh context values. -* If your build system produces duplicates modules in the output (which can happen with symlinks), this can break context. Passing something via context only works if `SomeContext` that you use to provide context and `SomeContext` that you use to read it are ***exactly* the same object**, as determined by a `===` comparison. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 --- @@ -1359,28 +1349,17 @@ function MyApp() { 这里有几种常见的情况会引起这个问题: -<<<<<<< HEAD -1. 你在调用 `useContext()` 的同一组件(或下层)渲染 `<SomeContext.Provider>`。把 `<SomeContext.Provider>` 向调用 `useContext()` 组件 **之上和之外** 移动。 -2. 你可能忘记了使用 `<SomeContext.Provider>` 包装组件,或者你可能将组件放在树的不同部分。使用 [React DevTools](/learn/react-developer-tools) 检查组件树的层级是否正确。 +1. 你在调用 `useContext()` 的同一组件(或下层)渲染 `<SomeContext>`。把 `<SomeContext>` 向调用 `useContext()` 组件 **之上和之外** 移动。 +2. 你可能忘记了使用 `<SomeContext>` 包装组件,或者你可能将组件放在树的不同部分。使用 [React DevTools](/learn/react-developer-tools) 检查组件树的层级是否正确。 3. 你的工具可能会遇到一些构建问题,导致你在传值组件中的所看到的 `SomeContext` 和读值组件中所看到的 `SomeContext` 是两个不同的对象。例如,如果使用符号链接,就会发生这种情况。你可以通过将它们赋值给全局对象如 `window.SomeContext1` 和 `window.SomeContext2` 来验证这种情况。然后在控制台检查 `window.SomeContext1 === window.SomeContext2` 是否相等。如果它们是不相等的,就在构建工具层面修复这个问题。 -======= -1. You're rendering `<SomeContext>` in the same component (or below) as where you're calling `useContext()`. Move `<SomeContext>` *above and outside* the component calling `useContext()`. -2. You may have forgotten to wrap your component with `<SomeContext>`, or you might have put it in a different part of the tree than you thought. Check whether the hierarchy is right using [React DevTools.](/learn/react-developer-tools) -3. You might be running into some build issue with your tooling that causes `SomeContext` as seen from the providing component and `SomeContext` as seen by the reading component to be two different objects. This can happen if you use symlinks, for example. You can verify this by assigning them to globals like `window.SomeContext1` and `window.SomeContext2` and then checking whether `window.SomeContext1 === window.SomeContext2` in the console. If they're not the same, fix that issue on the build tool level. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 ### 尽管设置了不一样的默认值,但是我总是从 context 中得到 `undefined` {/*i-am-always-getting-undefined-from-my-context-although-the-default-value-is-different*/} 你可能在组件树中有一个没有设置 `value` 的 provider: ```js {1,2} -<<<<<<< HEAD // 🚩 不起作用:没有 value 作为 prop -<ThemeContext.Provider> -======= -// 🚩 Doesn't work: no value prop <ThemeContext> ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 <Button /> </ThemeContext> ``` @@ -1390,13 +1369,8 @@ function MyApp() { 你可能还错误地使用了一个不同的 prop 名: ```js {1,2} -<<<<<<< HEAD // 🚩 不起作用:prop 应该是“value” -<ThemeContext.Provider theme={theme}> -======= -// 🚩 Doesn't work: prop should be called "value" <ThemeContext theme={theme}> ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 <Button /> </ThemeContext> ``` @@ -1404,19 +1378,10 @@ function MyApp() { 在这两种情况下,你都应该在控制台中看到 React 发出的警告。要解决这些问题,使用 `value` 作为 prop: ```js {1,2} -<<<<<<< HEAD // ✅ 传递 value 作为 prop -<ThemeContext.Provider value={theme}> -======= -// ✅ Passing the value prop <ThemeContext value={theme}> ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 <Button /> </ThemeContext> ``` -<<<<<<< HEAD -注意,只有在 **上层根本没有匹配的 provider** 时才使用 [`createContext(defaultValue)`调用的默认值](#specifying-a-fallback-default-value)。如果存在 `<SomeContext.Provider value={undefined}>` 组件在父树的某个位置,调用 `useContext(SomeContext)` 的组件 **将会** 接收到 `undefined` 作为 context 的值。 -======= -Note that the [default value from your `createContext(defaultValue)` call](#specifying-a-fallback-default-value) is only used **if there is no matching provider above at all.** If there is a `<SomeContext value={undefined}>` component somewhere in the parent tree, the component calling `useContext(SomeContext)` *will* receive `undefined` as the context value. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 +注意,只有在 **上层根本没有匹配的 provider** 时才使用 [`createContext(defaultValue)`调用的默认值](#specifying-a-fallback-default-value)。如果存在 `<SomeContext value={undefined}>` 组件在父树的某个位置,调用 `useContext(SomeContext)` 的组件 **将会** 接收到 `undefined` 作为 context 的值。 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 4a7d74359e..fcd56c5928 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 @@ -206,13 +206,8 @@ function ProductDetailPage({ product }) { 你可以将 props 和 state 视为在渲染后更新的快照。因此,你不会直接修改 props 或 state,相反,你传递新的 props,或者使用提供给你的 setter 函数来告诉 React,state 需要在下一次组件渲染时更新。 -<<<<<<< HEAD ### 不要修改 props {/*props*/} props 是不可变的,因为如果你改变了它们,应用程序可能会产生不一致的结果,这会让调试变得困难,因为程序可能会在某些情况下工作,而在另一些情况下不工作。 -======= -### Don't mutate Props {/*props*/} -Props are immutable because if you mutate them, the application will produce inconsistent output, which can be hard to debug as it may or may not work depending on the circumstances. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 ```js {2} function Post({ item }) { @@ -311,12 +306,7 @@ function useIconStyle(icon) { }, [icon, theme]); } ``` -<<<<<<< HEAD 如果你改变了 Hook 的参数,那么自定义 Hook 的缓存(memoization)就会变得不正确,因此避免这样做非常重要。 -======= - -If you were to mutate the Hook's arguments, the custom hook's memoization will become incorrect, so it's important to avoid doing that. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 ```js {4} style = useIconStyle(icon); // `style` 是基于 `icon` 进行记忆化的 @@ -336,11 +326,7 @@ style = useIconStyle(icon); // 计算 `style` 的新值 ## 不要改变传递给 JSX 后的值 {/*values-are-immutable-after-being-passed-to-jsx*/} -<<<<<<< HEAD 不要在 JSX 使用过值之后改变它们。应该在创建 JSX 之前完成值的更改。 -======= -Don't mutate values after they've been used in JSX. Move the mutation to before the JSX is created. ->>>>>>> 50d6991ca6652f4bc4c985cf0c0e593864f2cc91 当你在表达式中使用 JSX 时,React 可能会在组件完成渲染之前就急于计算 JSX。这意味着,如果在将值传递给 JSX 之后对它们进行更改,可能会导致 UI 过时,因为 React 不会知道需要更新组件的输出。