Skip to content

Commit 098f0a4

Browse files
Merge branch 'main' of https://github.com/reactjs/react.dev into sync-d34c6a2c
2 parents 84ac2e5 + d34c6a2 commit 098f0a4

21 files changed

+240
-148
lines changed
16.3 KB
Loading

src/components/DocsFooter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ function FooterLink({
8080
/>
8181
<div className="flex flex-col overflow-hidden">
8282
<span className="text-sm font-bold tracking-wide no-underline uppercase text-secondary dark:text-secondary-dark group-focus:text-link dark:group-focus:text-link-dark group-focus:text-opacity-100">
83-
{type}
83+
{type === 'Previous' ? 'Previous' : 'Next'}
8484
</span>
8585
<span className="text-lg break-words group-hover:underline">
8686
{title}

src/components/Icon/IconArrowSmall.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const IconArrowSmall = memo<
1919
const classes = cn(className, {
2020
'rotate-180': displayDirection === 'left',
2121
'rotate-180 rtl:rotate-0': displayDirection === 'start',
22+
'rtl:rotate-180': displayDirection === 'end',
2223
'rotate-90': displayDirection === 'down',
2324
});
2425
return (

src/components/MDX/Challenges/Navigation.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export function Navigation({
108108
onClick={handleScrollLeft}
109109
aria-label="Scroll left"
110110
className={cn(
111-
'bg-secondary-button dark:bg-secondary-button-dark h-8 px-2 rounded-l border-gray-20 border-r rtl:rotate-180',
111+
'bg-secondary-button dark:bg-secondary-button-dark h-8 px-2 rounded-l rtl:rounded-r rtl:rounded-l-none border-gray-20 border-r rtl:border-l rtl:border-r-0',
112112
{
113113
'text-primary dark:text-primary-dark': canScrollLeft,
114114
'text-gray-30': !canScrollLeft,
@@ -120,7 +120,7 @@ export function Navigation({
120120
onClick={handleScrollRight}
121121
aria-label="Scroll right"
122122
className={cn(
123-
'bg-secondary-button dark:bg-secondary-button-dark h-8 px-2 rounded-e rtl:rotate-180',
123+
'bg-secondary-button dark:bg-secondary-button-dark h-8 px-2 rounded-e',
124124
{
125125
'text-primary dark:text-primary-dark': canScrollRight,
126126
'text-gray-30': !canScrollRight,

src/content/blog/2025/04/23/react-labs-view-transitions-activity-and-more.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2521,7 +2521,7 @@ export default function App() {
25212521
const { url } = useRouter();
25222522

25232523
// Define a default animation of .slow-fade.
2524-
// See animations.css for the animation definiton.
2524+
// See animations.css for the animation definition.
25252525
return (
25262526
<ViewTransition default="slow-fade">
25272527
{url === '/' ? <Home /> : <Details />}

src/content/community/conferences.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ October 2-4, 2025. Alicante, Spain.
2020

2121
[Website](https://reactalicante.es/) - [Twitter](https://x.com/ReactAlicante) - [Bluesky](https://bsky.app/profile/reactalicante.es) - [YouTube](https://www.youtube.com/channel/UCaSdUaITU1Cz6PvC97A7e0w)
2222

23+
### RenderCon Kenya 2025 {/*rendercon-kenya-2025*/}
24+
October 04, 2025. Nairobi, Kenya
25+
26+
[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA)
27+
2328
### React Conf 2025 {/*react-conf-2025*/}
2429
October 7-8, 2025. Henderson, Nevada, USA and free livestream
2530

src/content/community/meetups.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet
5858
* [Manchester](https://www.meetup.com/Manchester-React-User-Group/)
5959
* [React.JS Girls London](https://www.meetup.com/ReactJS-Girls-London/)
6060
* [React Advanced London](https://guild.host/react-advanced-london)
61+
* [React Native Liverpool](https://www.meetup.com/react-native-liverpool/)
6162
* [React Native London](https://guild.host/RNLDN)
6263

6364
## Finland {/*finland*/}
@@ -137,6 +138,9 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet
137138
## Portugal {/*portugal*/}
138139
* [Lisbon](https://www.meetup.com/JavaScript-Lisbon/)
139140

141+
## Scotland (UK) {/*scotland-uk*/}
142+
* [Edinburgh](https://www.meetup.com/react-edinburgh/)
143+
140144
## Spain {/*spain*/}
141145
* [Barcelona](https://www.meetup.com/ReactJS-Barcelona/)
142146

src/content/learn/build-a-react-app-from-scratch.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ For code-splitting instructions, see your build tool docs:
122122

123123
### Improving Application Performance {/*improving-application-performance*/}
124124

125-
Since the build tool you select only support single page apps (SPAs) you'll need to implement other [rendering patterns](https://www.patterns.dev/vanilla/rendering-patterns) like server-side rendering (SSR), static site generation (SSG), and/or React Server Components (RSC). Even if you don't need these features at first, in the future there may be some routes that would benefit SSR, SSG or RSC.
125+
Since the build tool you select only supports single page apps (SPAs), you'll need to implement other [rendering patterns](https://www.patterns.dev/vanilla/rendering-patterns) like server-side rendering (SSR), static site generation (SSG), and/or React Server Components (RSC). Even if you don't need these features at first, in the future there may be some routes that would benefit SSR, SSG or RSC.
126126

127127
* **Single-page apps (SPA)** load a single HTML page and dynamically updates the page as the user interacts with the app. SPAs are easier to get started with, but they can have slower initial load times. SPAs are the default architecture for most build tools.
128128

src/content/learn/manipulating-the-dom-with-refs.md

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ This is because **Hooks must only be called at the top-level of your component.*
211211

212212
One possible way around this is to get a single ref to their parent element, and then use DOM manipulation methods like [`querySelectorAll`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) to "find" the individual child nodes from it. However, this is brittle and can break if your DOM structure changes.
213213

214-
Another solution is to **pass a function to the `ref` attribute.** This is called a [`ref` callback.](/reference/react-dom/components/common#ref-callback) React will call your ref callback with the DOM node when it's time to set the ref, and with `null` when it's time to clear it. This lets you maintain your own array or a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), and access any ref by its index or some kind of ID.
214+
Another solution is to **pass a function to the `ref` attribute.** This is called a [`ref` callback.](/reference/react-dom/components/common#ref-callback) React will call your ref callback with the DOM node when it's time to set the ref, and call the cleanup function returned from the callback when it's time to clear it. This lets you maintain your own array or a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), and access any ref by its index or some kind of ID.
215215

216216
This example shows how you can use this approach to scroll to an arbitrary node in a long list:
217217

@@ -247,13 +247,13 @@ export default function CatFriends() {
247247
<nav>
248248
<button onClick={() => scrollToCat(catList[0])}>Neo</button>
249249
<button onClick={() => scrollToCat(catList[5])}>Millie</button>
250-
<button onClick={() => scrollToCat(catList[9])}>Bella</button>
250+
<button onClick={() => scrollToCat(catList[8])}>Bella</button>
251251
</nav>
252252
<div>
253253
<ul>
254254
{catList.map((cat) => (
255255
<li
256-
key={cat}
256+
key={cat.id}
257257
ref={(node) => {
258258
const map = getMap();
259259
map.set(cat, node);
@@ -263,7 +263,7 @@ export default function CatFriends() {
263263
};
264264
}}
265265
>
266-
<img src={cat} />
266+
<img src={cat.imageUrl} />
267267
</li>
268268
))}
269269
</ul>
@@ -273,11 +273,22 @@ export default function CatFriends() {
273273
}
274274

275275
function setupCatList() {
276-
const catList = [];
277-
for (let i = 0; i < 10; i++) {
278-
catList.push("https://loremflickr.com/320/240/cat?lock=" + i);
276+
const catCount = 10;
277+
const catList = new Array(catCount)
278+
for (let i = 0; i < catCount; i++) {
279+
let imageUrl = '';
280+
if (i < 5) {
281+
imageUrl = "https://placecats.com/neo/320/240";
282+
} else if (i < 8) {
283+
imageUrl = "https://placecats.com/millie/320/240";
284+
} else {
285+
imageUrl = "https://placecats.com/bella/320/240";
286+
}
287+
catList[i] = {
288+
id: i,
289+
imageUrl,
290+
};
279291
}
280-
281292
return catList;
282293
}
283294

@@ -876,12 +887,30 @@ export default function CatFriends() {
876887
);
877888
}
878889

879-
const catList = [];
880-
for (let i = 0; i < 10; i++) {
881-
catList.push({
890+
const catCount = 10;
891+
const catList = new Array(catCount);
892+
for (let i = 0; i < catCount; i++) {
893+
const bucket = Math.floor(Math.random() * catCount) % 2;
894+
let imageUrl = '';
895+
switch (bucket) {
896+
case 0: {
897+
imageUrl = "https://placecats.com/neo/250/200";
898+
break;
899+
}
900+
case 1: {
901+
imageUrl = "https://placecats.com/millie/250/200";
902+
break;
903+
}
904+
case 2:
905+
default: {
906+
imageUrl = "https://placecats.com/bella/250/200";
907+
break;
908+
}
909+
}
910+
catList[i] = {
882911
id: i,
883-
imageUrl: 'https://loremflickr.com/250/200/cat?lock=' + i
884-
});
912+
imageUrl,
913+
};
885914
}
886915

887916
```
@@ -961,7 +990,7 @@ export default function CatFriends() {
961990
behavior: 'smooth',
962991
block: 'nearest',
963992
inline: 'center'
964-
});
993+
});
965994
}}>
966995
Next
967996
</button>
@@ -993,12 +1022,30 @@ export default function CatFriends() {
9931022
);
9941023
}
9951024

996-
const catList = [];
997-
for (let i = 0; i < 10; i++) {
998-
catList.push({
1025+
const catCount = 10;
1026+
const catList = new Array(catCount);
1027+
for (let i = 0; i < catCount; i++) {
1028+
const bucket = Math.floor(Math.random() * catCount) % 2;
1029+
let imageUrl = '';
1030+
switch (bucket) {
1031+
case 0: {
1032+
imageUrl = "https://placecats.com/neo/250/200";
1033+
break;
1034+
}
1035+
case 1: {
1036+
imageUrl = "https://placecats.com/millie/250/200";
1037+
break;
1038+
}
1039+
case 2:
1040+
default: {
1041+
imageUrl = "https://placecats.com/bella/250/200";
1042+
break;
1043+
}
1044+
}
1045+
catList[i] = {
9991046
id: i,
1000-
imageUrl: 'https://loremflickr.com/250/200/cat?lock=' + i
1001-
});
1047+
imageUrl,
1048+
};
10021049
}
10031050

10041051
```

src/content/learn/react-compiler/introduction.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ const ExpensiveComponent = memo(function ExpensiveComponent({ data, onClick }) {
5050
});
5151
```
5252

53+
54+
<Note>
55+
56+
This manual memoization has a subtle bug that breaks memoization:
57+
58+
```js [[2, 1, "() => handleClick(item)"]]
59+
<Item key={item.id} onClick={() => handleClick(item)} />
60+
```
61+
62+
Even though `handleClick` is wrapped in `useCallback`, the arrow function `() => handleClick(item)` creates a new function every time the component renders. This means that `Item` will always receive a new `onClick` prop, breaking memoization.
63+
64+
React Compiler is able to optimize this correctly with or without the arrow function, ensuring that `Item` only re-renders when `props.onClick` changes.
65+
66+
</Note>
67+
5368
### After React Compiler {/*after-react-compiler*/}
5469

5570
With React Compiler, you write the same code without manual memoization:
@@ -74,7 +89,7 @@ function ExpensiveComponent({ data, onClick }) {
7489

7590
_[See this example in the React Compiler Playground](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEAogB4AOCmYeAbggMIQC2Fh1OAFMEQCYBDHAIA0RQowA2eOAGsiAXwCURYAB1iROITA4iFGBERgwCPgBEhAogF4iCStVoMACoeO1MAcy6DhSgG4NDSItHT0ACwFMPkkmaTlbIi48HAQWFRsAPlUQ0PFMKRlZFLSWADo8PkC8hSDMPJgEHFhiLjzQgB4+eiyO-OADIwQTM0thcpYBClL02xz2zXz8zoBJMqJZBABPG2BU9Mq+BQKiuT2uTJyomLizkoOMk4B6PqX8pSUFfs7nnro3qEapgFCAFEA)_
7691

77-
React Compiler automatically applies the equivalent optimizations, ensuring your app only re-renders when necessary.
92+
React Compiler automatically applies the optimal memoization, ensuring your app only re-renders when necessary.
7893

7994
<DeepDive>
8095
#### What kind of memoization does React Compiler add? {/*what-kind-of-memoization-does-react-compiler-add*/}

0 commit comments

Comments
 (0)