Browse Source

[Beta] Revamp navigation (#5287)

* [Beta] Split API reference

* Learn | Hooks | APIs

* tsc

* nav changes

* redirects and url changes

* twk

* alt take

* fix;

* wip

* nav?

* tsc

* twk

* tweaks

* index pages

* cleanup

* undo changes

* edits

* edits
main
dan 2 years ago
committed by GitHub
parent
commit
1a641bb88e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      beta/src/components/Layout/MarkdownPage.tsx
  2. 23
      beta/src/components/Layout/Nav/Nav.tsx
  3. 10
      beta/src/components/Layout/Page.tsx
  4. 121
      beta/src/components/Layout/Sidebar/SidebarRouteTree.tsx
  5. 2
      beta/src/components/Layout/useRouteMeta.tsx
  6. 58
      beta/src/content/apis/react-dom/client/index.md
  7. 111
      beta/src/content/apis/react-dom/index.md
  8. 9
      beta/src/content/apis/react-dom/legacy.md
  9. 99
      beta/src/content/apis/react-dom/server/index.md
  10. 421
      beta/src/content/apis/react/index.md
  11. 36
      beta/src/content/apis/react/legacy.md
  12. 31
      beta/src/content/apis/react/other.md
  13. 2
      beta/src/content/index.md
  14. 0
      beta/src/content/learn/acknowledgements.md
  15. 0
      beta/src/content/learn/community.md
  16. 0
      beta/src/content/learn/meet-the-team.md
  17. 6
      beta/src/hooks/useActiveSection.ts
  18. 162
      beta/src/sidebarAPIs.json
  19. 32
      beta/src/sidebarHome.json
  20. 16
      beta/src/sidebarLearn.json

9
beta/src/components/Layout/MarkdownPage.tsx

@ -3,10 +3,12 @@
*/
import * as React from 'react';
import {useRouter} from 'next/router';
import {DocsPageFooter} from 'components/DocsFooter';
import {Seo} from 'components/Seo';
import PageHeading from 'components/PageHeading';
import {useRouteMeta} from './useRouteMeta';
import {useActiveSection} from '../../hooks/useActiveSection';
import {TocContext} from '../MDX/TocContext';
import(/* webpackPrefetch: true */ '../MDX/CodeBlock/CodeBlock');
@ -25,13 +27,10 @@ export function MarkdownPage<
T extends {title: string; status?: string} = {title: string; status?: string}
>({children, meta, toc}: MarkdownProps<T>) {
const {route, nextRoute, prevRoute} = useRouteMeta();
const section = useActiveSection();
const title = meta.title || route?.title || '';
const description = meta.description || route?.description || '';
if (!route) {
console.error('This page was not added to one of the sidebar JSON files.');
}
const isHomePage = route?.path === '/';
const isHomePage = section === 'home';
return (
<>
<div className="pl-0">

23
beta/src/components/Layout/Nav/Nav.tsx

@ -19,9 +19,8 @@ import NavLink from './NavLink';
import {SidebarContext} from 'components/Layout/useRouteMeta';
import {SidebarRouteTree} from '../Sidebar/SidebarRouteTree';
import type {RouteItem} from '../useRouteMeta';
import sidebarHome from '../../../sidebarHome.json';
import sidebarLearn from '../../../sidebarLearn.json';
import sidebarReference from '../../../sidebarReference.json';
import sidebarAPIs from '../../../sidebarAPIs.json';
declare global {
interface Window {
@ -115,13 +114,11 @@ export default function Nav() {
if (isOpen) {
switch (tab) {
case 'home':
routeTree = sidebarHome as RouteItem;
break;
case 'learn':
routeTree = sidebarLearn as RouteItem;
break;
case 'apis':
routeTree = sidebarReference as RouteItem;
routeTree = sidebarAPIs as RouteItem;
break;
}
}
@ -188,7 +185,7 @@ export default function Nav() {
});
}, [showFeedback]);
function selectTab(nextTab: 'learn' | 'apis' | 'home') {
function selectTab(nextTab: 'learn' | 'apis') {
setTab(nextTab);
scrollParentRef.current!.scrollTop = 0;
}
@ -245,10 +242,9 @@ export default function Nav() {
</div>
</div>
<div className="px-0 pt-2 w-full 2xl:max-w-xs hidden lg:flex items-center self-center border-b-0 lg:border-b border-border dark:border-border-dark">
<NavLink href="/" isActive={section === 'home'}>
Home
</NavLink>
<NavLink href="/learn" isActive={section === 'learn'}>
<NavLink
href="/learn"
isActive={section === 'learn' || section === 'home'}>
Learn
</NavLink>
<NavLink href="/apis/react" isActive={section === 'apis'}>
@ -312,12 +308,7 @@ export default function Nav() {
{isOpen && (
<div className="bg-wash dark:bg-wash-dark px-5 flex justify-end border-b border-border dark:border-border-dark items-center self-center w-full z-10">
<TabButton
isActive={tab === 'home'}
onClick={() => selectTab('home')}>
Home
</TabButton>
<TabButton
isActive={tab === 'learn'}
isActive={tab === 'learn' || tab === 'home'}
onClick={() => selectTab('learn')}>
Learn
</TabButton>

10
beta/src/components/Layout/Page.tsx

@ -11,9 +11,8 @@ import {useActiveSection} from 'hooks/useActiveSection';
import {Footer} from './Footer';
import {Toc} from './Toc';
import SocialBanner from '../SocialBanner';
import sidebarHome from '../../sidebarHome.json';
import sidebarLearn from '../../sidebarLearn.json';
import sidebarReference from '../../sidebarReference.json';
import sidebarAPIs from '../../sidebarAPIs.json';
import type {TocItem} from 'components/MDX/TocContext';
interface PageProps {
@ -24,13 +23,10 @@ interface PageProps {
export function Page({children, toc}: PageProps) {
const {asPath} = useRouter();
const section = useActiveSection();
let routeTree = sidebarHome as RouteItem;
let routeTree = sidebarLearn as RouteItem;
switch (section) {
case 'apis':
routeTree = sidebarReference as RouteItem;
break;
case 'learn':
routeTree = sidebarLearn as RouteItem;
routeTree = sidebarAPIs as RouteItem;
break;
}
return (

121
beta/src/components/Layout/Sidebar/SidebarRouteTree.tsx

@ -99,63 +99,78 @@ export function SidebarRouteTree({
const expanded = expandedPath;
return (
<ul>
{currentRoutes.map(({path, title, routes, wip, heading}) => {
const pagePath = path && removeFromLast(path, '.');
const selected = slug === pagePath;
{currentRoutes.map(
({path, title, routes, wip, heading, hasSeparator}) => {
const pagePath = path && removeFromLast(path, '.');
const selected = slug === pagePath;
// if current route item has no path and children treat it as an API sidebar heading
if (!path || !pagePath || heading) {
return (
<SidebarRouteTree
level={level + 1}
isForceExpanded={isForceExpanded}
routeTree={{title, routes}}
/>
);
}
// if route has a path and child routes, treat it as an expandable sidebar item
if (routes) {
const isExpanded = isForceExpanded || expanded === path;
return (
<li key={`${title}-${path}-${level}-heading`}>
<SidebarLink
key={`${title}-${path}-${level}-link`}
href={pagePath}
isPending={pendingRoute === pagePath}
selected={selected}
level={level}
title={title}
wip={wip}
isExpanded={isExpanded}
isBreadcrumb={expandedPath === path}
hideArrow={isForceExpanded}
let listItem = null;
if (!path || !pagePath || heading) {
// if current route item has no path and children treat it as an API sidebar heading
listItem = (
<SidebarRouteTree
level={level + 1}
isForceExpanded={isForceExpanded}
routeTree={{title, routes}}
/>
<CollapseWrapper duration={250} isExpanded={isExpanded}>
<SidebarRouteTree
isForceExpanded={isForceExpanded}
routeTree={{title, routes}}
level={level + 1}
);
} else if (routes) {
// if route has a path and child routes, treat it as an expandable sidebar item
const isExpanded = isForceExpanded || expanded === path;
listItem = (
<li key={`${title}-${path}-${level}-heading`}>
<SidebarLink
key={`${title}-${path}-${level}-link`}
href={pagePath}
isPending={pendingRoute === pagePath}
selected={selected}
level={level}
title={title}
wip={wip}
isExpanded={isExpanded}
isBreadcrumb={expandedPath === path}
hideArrow={isForceExpanded}
/>
</CollapseWrapper>
</li>
);
}
<CollapseWrapper duration={250} isExpanded={isExpanded}>
<SidebarRouteTree
isForceExpanded={isForceExpanded}
routeTree={{title, routes}}
level={level + 1}
/>
</CollapseWrapper>
</li>
);
} else {
// if route has a path and no child routes, treat it as a sidebar link
listItem = (
<li key={`${title}-${path}-${level}-link`}>
<SidebarLink
isPending={pendingRoute === pagePath}
href={path.startsWith('https://') ? path : pagePath}
selected={selected}
level={level}
title={title}
wip={wip}
/>
</li>
);
}
// if route has a path and no child routes, treat it as a sidebar link
return (
<li key={`${title}-${path}-${level}-link`}>
<SidebarLink
isPending={pendingRoute === pagePath}
href={path.startsWith('https://') ? path : pagePath}
selected={selected}
level={level}
title={title}
wip={wip}
/>
</li>
);
})}
if (hasSeparator) {
return (
<>
<li
role="separator"
className="my-2 ml-5 border-b border-border dark:border-border-dark"
/>
{listItem}
</>
);
} else {
return listItem;
}
}
)}
</ul>
);
}

2
beta/src/components/Layout/useRouteMeta.tsx

@ -34,6 +34,8 @@ export interface RouteItem {
wip?: boolean;
/** List of sub-routes */
routes?: RouteItem[];
/** Adds a separator above the route item */
hasSeparator?: boolean;
}
export interface Routes {

58
beta/src/content/apis/react-dom/client/index.md

@ -1,62 +1,24 @@
---
title: ReactDOMClient APIs
title: react-dom/client
---
<Intro>
The ReactDOMClient APIs let you render React components in the browser.
The `react-dom/client` APIs let you render React components on the client (in the browser). These APIs are typically used at the top level of your app to initialize your React tree. A [framework](/learn/start-a-new-react-project#building-with-a-full-featured-framework) may call them for you. Most of your components don't need to import or use them.
</Intro>
Typically, you will use ReactDOM at the top level of your app to display your components. You will either use it directly or a [framework](/learn/start-a-new-react-project#building-with-react-and-a-framework) may do it for you. Most of your components should *not* need to import this module.
<InlineToc />
## Installation {/*installation*/}
<PackageImport>
<TerminalBlock>
npm install react-dom
</TerminalBlock>
```js
// Importing a specific API:
import { createRoot } from 'react-dom/client';
// Importing all APIs together:
import * as ReactDOMClient from 'react-dom/client';
```
</PackageImport>
You'll also need to install the same version of [React.](/apis/react)
## Browser Support {/*browser-support*/}
ReactDOM supports all popular browsers, including Internet Explorer 9 and above. [Some polyfills are required](TODO:/link-to-js-environment-requirements) for older browsers such as IE 9 and IE 10.
## Exports {/*exports*/}
<YouWillLearnCard title="createRoot" path="/apis/react-dom/client/createRoot">
Create and render a React root.
```js
const root = createRoot(domNode);
root.render(<App />);
```
</YouWillLearnCard>
---
<YouWillLearnCard title="hydrateRoot" path="/apis/react-dom/client/hydrateRoot">
## React DOM Client APIs {/*react-dom-client-apis*/}
Hydrate server-rendered HTML.
* [`createRoot`](/apis/react-dom/client/createRoot) lets you create a root to display React components inside a browser DOM node.
* [`hydrateRoot`](/apis/react-dom/client/hydrateRoot) lets you display React components inside a browser DOM node whose HTML content was previously generated by [`react-dom/server`.](/apis/react-dom/server)
```js
hydrateRoot(domNode, <App />);
```
---
</YouWillLearnCard>
## Browser support {/*browser-support*/}
React supports all popular browsers, including Internet Explorer 9 and above. Some polyfills are required for older browsers such as IE 9 and IE 10.

111
beta/src/content/apis/react-dom/index.md

@ -1,112 +1,45 @@
---
title: ReactDOM APIs
title: react-dom
---
<Wip>
This section is incomplete, please see the old docs for [ReactDOM.](https://reactjs.org/docs/react-dom.html)
</Wip>
<Intro>
The ReactDOM package provides DOM-specific methods that your components can import.
The `react-dom` package contains methods that are only supported for the web applications (which run in the browser DOM environment). They are not supported for React Native.
</Intro>
Most of your components should *not* need to import this module.
## Installation {/*installation*/}
<PackageImport>
<TerminalBlock>
npm install react-dom
</TerminalBlock>
```js
// Importing a specific API:
import { createPortal } from 'react-dom';
// Importing all APIs together:
import * as ReactDOM from 'react-dom';
```
</PackageImport>
You'll also need to install the same version of [React.](/apis/react)
## Exports {/*exports*/}
### Portals {/*portals*/}
<InlineToc />
<YouWillLearnCard title="createPortal" path="/apis/react-dom/createPortal">
Create a portal.
```js
createPortal(child, container);
```
</YouWillLearnCard>
### Flushing {/*flushing*/}
<YouWillLearnCard title="flushSync" path="/apis/react-dom/flushSync">
Flush in progress updates.
```js
flushSync(() => {
// ...
});
```
</YouWillLearnCard>
### Deprecated {/*deprecated*/}
<YouWillLearnCard title="render" path="/apis/react-dom/render">
Displays a React component inside a browser DOM node (deprecated).
```js
render(<App />, document.getElementById('root'));
```
---
</YouWillLearnCard>
## React DOM APIs {/*react-dom-apis*/}
<YouWillLearnCard title="hydrate" path="/apis/react-dom/hydrate">
These APIs can be imported from your components. They are rarely used:
Hydrate server-rendered HTMl (deprecated).
* [`createPortal`](/apis/react-dom/createPortal) lets you render child components in a different part of the DOM tree.
* [`flushSync`](/apis/react-dom/flushSync) lets you force React to flush a state update and update the DOM synchronously.
```js
hydrate(<App />, document.getElementById('root'));
```
---
</YouWillLearnCard>
## React DOM entry points {/*react-dom-entry-points*/}
## Entry points {/*entry-points*/}
The `react-dom` package provides two additional entry points:
<YouWillLearnCard title="ReactDOMClient APIs" path="/apis/react-dom/client">
* [`react-dom/client`](/apis/react-dom/client) contains APIs to render React components on the client (in the browser).
* [`react-dom/server`](/apis/react-dom/server) contains APIs to render React components on the server.
The ReactDOMClient APIs let you render React components in the browser.
---
```js
import * as ReactDOMClient from 'react-dom/client';
```
## Deprecated React DOM APIs {/*deprecated-react-dom-apis*/}
</YouWillLearnCard>
<Deprecated>
<YouWillLearnCard title="ReactDOMServer APIs" path="/apis/react-dom/server">
This API will be removed in a future major version of React.
The ReactDOMServer APIs let you render React components to HTML.
</Deprecated>
```js
import * as ReactDOMServer from 'react-dom/server';
```
* [`findDOMNode`](/apis/react-dom/findDOMNode) finds the closest DOM node corresponding to a class component instance.
* [`hydrate`](/apis/react-dom/hydrate) mounts a tree into the DOM created from server HTML. Deprecated in favor of [`hydrateRoot`](/apis/react-dom/client/hydrateRoot).
* [`render`](/apis/react-dom/render) mounts a tree into the DOM. Deprecated in favor of [`createRoot`](/apis/react-dom/client/createRoot).
* [`unmountComponentAtNode`](/apis/react-dom/unmountComponentAtNode) unmounts a tree from the DOM. Deprecated in favor of [`root.unmount()`.](/apis/react-dom/client/createRoot#root-unmount)
</YouWillLearnCard>

9
beta/src/content/apis/react-dom/legacy.md

@ -0,0 +1,9 @@
---
title: React APIs
---
<Wip>
This section is incomplete, please see the old docs for [React.](https://reactjs.org/docs/react-api.html)
</Wip>

99
beta/src/content/apis/react-dom/server/index.md

@ -1,102 +1,51 @@
---
title: ReactDOMServer APIs
title: react-dom/server
---
<Wip>
This section is incomplete, please see the old docs for [ReactDOM.](https://reactjs.org/docs/react-dom.html)
</Wip>
<Intro>
The ReactDOMServer APIs let you render React components to HTML.
The `react-dom/server` APIs let you render React components to HTML on the server. These APIs are only used on the server at the top level of your app to generate the initial HTML. A [framework](/learn/start-a-new-react-project#building-with-a-full-featured-framework) may call them for you. Most of your components don't need to import or use them.
</Intro>
Typically, you will run ReactDOMServer on the server to generate your app's initial HTML. You will either use it directly or a [framework](/learn/start-a-new-react-project#building-with-react-and-a-framework) may do it for you. Most of your components should *not* need to import this module.
## Installation {/*installation*/}
<PackageImport>
<TerminalBlock>
npm install react-dom
</TerminalBlock>
```js
// Importing a specific API:
import { renderToPipeableStream } from 'react-dom/server';
// Importing all APIs together:
import * as ReactDOMServer from 'react-dom/server';
```
</PackageImport>
<InlineToc />
You'll also need to install the same version of [React.](/apis/react)
## Exports {/*exports*/}
<YouWillLearnCard title="renderToPipeableStream" path="/apis/react-dom/server/renderToPipeableStream">
Render a React element to a pipeable stream.
```js
renderToPipeableStream(element, options)
```
</YouWillLearnCard>
<YouWillLearnCard title="renderToReadableStream" path="/apis/react-dom/server/renderToReadableStream">
Render a React element to a Readable stream.
---
```js
renderToReadableStream(element, options)
```
## React DOM Server APIs for Node.js Streams {/*react-dom-server-apis-for-nodejs-streams*/}
</YouWillLearnCard>
These methods are only available in the environments with [Node.js Streams:](https://nodejs.org/api/stream.html)
<YouWillLearnCard title="renderToNodeStream" path="/apis/react-dom/server/renderToNodeStream">
* [`renderToPipeableStream`](/apis/react-dom/server/renderToPipeableStream) renders a React tree to a pipeable [Node.js Stream.](https://nodejs.org/api/stream.html)
* [`renderToStaticNodeStream`](/apis/react-dom/server/renderToStaticNodeStream) renders a non-interactive React tree to a [Node.js Readable Stream.](https://nodejs.org/api/stream.html#readable-streams)
Render a React element to a Node stream.
---
```js
renderToNodeStream(element)
```
## React DOM Server APIs for Web Streams {/*react-dom-server-apis-for-web-streams*/}
</YouWillLearnCard>
These methods are only available in the environments with [Web Streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), which includes browsers, Deno, and some modern edge runtimes:
<YouWillLearnCard title="renderToStaticNodeStream" path="/apis/react-dom/server/renderToStaticNodeStream">
* [`renderToReadableStream`](/apis/react-dom/server/renderToReadableStream) renders a React tree to a [Readable](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) Web Stream.
Render a React element to a static Node stream.
---
```js
renderToStaticNodeStream(element)
```
## React DOM Server APIs for non-streaming environments {/*react-dom-server-apis-for-non-streaming-environments*/}
</YouWillLearnCard>
These methods can be used in the environments that don't support streams:
<YouWillLearnCard title="renderToString" path="/apis/react-dom/server/renderToString">
* [`renderToString`](/apis/react-dom/server/renderToString) renders a React tree to a string.
* [`renderToStaticMarkup`](/apis/react-dom/server/renderToStaticMarkup) renders a non-interactive React tree to a string.
Render a React element to a string.
They have limited functionality compared to the streaming APIs.
```js
renderToString(element)
```
---
</YouWillLearnCard>
## Deprecated React DOM Server APIs {/*deprecated-react-dom-server-apis*/}
<YouWillLearnCard title="renderToStaticMarkup" path="/apis/react-dom/server/renderToStaticMarkup">
<Deprecated>
Render a React element to static markup.
This API will be removed in a future major version of React.
```js
renderToStaticMarkup(element)
```
</Deprecated>
</YouWillLearnCard>
* [`renderToNodeStream`](/apis/react-dom/server/renderToNodeStream) renders a React tree to a [Node.js Readable stream.](https://nodejs.org/api/stream.html#readable-streams) (Deprecated.)

421
beta/src/content/apis/react/index.md

@ -1,428 +1,129 @@
---
title: React APIs
title: "react: Hooks"
---
<Wip>
This section is incomplete, please see the old docs for [React.](https://reactjs.org/docs/react-api.html)
</Wip>
<Intro>
The React package contains all the APIs necessary to define and use [components.](/learn/your-first-component)
*Hooks* let you use different React features from your components. You can either use the built-in Hooks or combine them to build your own. This page lists all the built-in Hooks in React.
</Intro>
## Installation {/*installation*/}
It is available as [`react`](https://www.npmjs.com/package/react) on npm. You can also [add React to the page as a `<script>` tag.](/learn/add-react-to-a-website)
<PackageImport>
<TerminalBlock>
npm install react
</TerminalBlock>
```js
// Importing a specific API:
import { useState } from 'react';
// Importing all APIs together:
import * as React from 'react';
```
<InlineToc />
</PackageImport>
If you use React on the web, you'll also need the same version of [ReactDOM.](/apis/react-dom)
---
## Exports {/*exports*/}
## State Hooks {/*state-hooks*/}
### State {/*state*/}
[State](/learn/state-a-components-memory) lets a component "remember" information like user input. For example, a form component can use state to store the input value, while an image gallery component can use state to store the selected image index.
<YouWillLearnCard title="useState" path="/apis/react/useState">
To add state to a component, use one of these Hooks:
Declares a state variable.
* [`useState`](/apis/react/useState) declares a state variable that you can update directly.
* [`useReducer`](/apis/react/useReducer) declares a state variable with the update logic inside a [reducer function.](/learn/extracting-state-logic-into-a-reducer)
```js
function MyComponent() {
const [age, setAge] = useState(42);
function ImageGallery() {
const [index, setIndex] = useState(0);
// ...
```
</YouWillLearnCard>
<YouWillLearnCard title="useReducer" path="/apis/react/useReducer">
[See the `useState` page for more examples.](/apis/react/useState)
Declares a state variable managed with a reducer.
```js
function MyComponent() {
const [state, dispatch] = useReducer(reducer, { age: 42 });
// ...
```
</YouWillLearnCard>
---
### Context {/*context*/}
## Context Hooks {/*context-hooks*/}
<YouWillLearnCard title="useContext" path="/apis/react/useContext">
[Context](/learn/passing-data-deeply-with-context) lets a component receive information from distant parents without [passing it as props.](/learn/passing-props-to-a-component) For example, your app's top-level component can pass the current UI theme to all components below, no matter how deep.
Reads and subscribes to a context.
* [`useContext`](/apis/react/useContext) reads and subscribes to a context.
```js
function MyComponent() {
function Button() {
const theme = useContext(ThemeContext);
// ...
```
</YouWillLearnCard>
<YouWillLearnCard title="createContext" path="/apis/react/createContext">
Creates a context that components can provide or read.
[See the `useContext` page for more examples.](/apis/react/useContext)
```js
const ThemeContext = createContext('light');
```
</YouWillLearnCard>
### Refs {/*refs*/}
---
## Ref Hooks {/*ref-hooks*/}
<YouWillLearnCard title="useRef" path="/apis/react/useRef">
[Refs](/learn/referencing-values-with-refs) let a component hold some information that isn't used for rendering, like a DOM node or a timeout ID. Unlike with state, updating a ref does not re-render your component. Refs are an "escape hatch" from the React paradigm. They are useful when you need to work with non-React systems, such as the built-in browser APIs.
Declares a ref.
* [`useRef`](/apis/react/useRef) declares a ref. You can hold any value in it, but most often it's used to hold a DOM node.
* [`useImperativeHandle`](/apis/react/useImperativeHandle) lets you customize the ref exposed by your component. This is rarely used.
```js
function MyComponent() {
function Form() {
const inputRef = useRef(null);
// ...
```
</YouWillLearnCard>
<YouWillLearnCard title="forwardRef" path="/apis/react/forwardRef">
Create a component that forwards the ref attribute:
```js
const Component = forwardRef((props, ref) => {
// ...
});
```
</YouWillLearnCard>
<YouWillLearnCard title="useImperativeHandle" path="/apis/react/useImperativeHandle">
Customize instance value exposed to parent refs:
```js
useImperativeHandle(ref, () => {
// ...
});
```
</YouWillLearnCard>
<YouWillLearnCard title="createRef" path="/apis/react/createRef">
Create a ref (typically for class components):
```js
this.ref = createRef();
```
</YouWillLearnCard>
### Components {/*components*/}
[See the `useRef` page for more examples.](/apis/react/useRef)
<YouWillLearnCard title="React.Component" path="/apis/react/Component">
Define a components as a class:
```js
class MyComponent extends React.Component {
// ...
}
```
---
</YouWillLearnCard>
## Effect Hooks {/*effect-hooks*/}
<YouWillLearnCard title="React.PureComponent" path="/apis/react/PureComponent">
[Effects](/learn/synchronizing-with-effects) let a component connect to and synchronize with external systems. This includes dealing with network, browser DOM, animations, widgets written using a different UI library, and in general any non-React code.
Define a pure component as a class:
* [`useEffect`](/apis/react/useEffect) connects a component to an external system.
```js
class MyComponent extends React.PureComponent {
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);
// ...
}
```
</YouWillLearnCard>
### Elements {/*elements*/}
<YouWillLearnCard title="Fragment" path="/apis/react/Fragment">
Return multiple elements:
```js
function MyComponent() {
return (
<>
<h1>Title</h1>
<h2>Subtitle</h2>
</>
);
}
```
</YouWillLearnCard>
<YouWillLearnCard title="Children" path="/apis/react/Children">
Utilities for dealing with `props.children`:
```js
React.Children.map(children, () => ([]));
[See the `useEffect` page for more examples.](/apis/react/useEffect)
React.Children.forEach(children, () => {});
React.Children.count(children);
React.Children.only(children);
React.Children.toArray(children);
```
</YouWillLearnCard>
<YouWillLearnCard title="createElement" path="/apis/react/createElement">
Create a React element:
```js
React.createElement('div', { title: 'Element'});
```
</YouWillLearnCard>
<YouWillLearnCard title="createFactory" path="/apis/react/createFactory">
Create a factory for React elements of a given type:
```js
React.createFactory('div');
```
</YouWillLearnCard>
<YouWillLearnCard title="cloneElement" path="/apis/react/cloneElement">
Clone a React element:
```js
React.cloneElement(element, props);
```
Effects are an "escape hatch" from the React paradigm. Don't use Effects to orchestrate the data flow of your application. If you're not interacting with an external system, [you might not need an Effect.](/learn/you-might-not-need-an-effect)
</YouWillLearnCard>
There are two variations of `useEffect` with differences in timing:
<YouWillLearnCard title="isValidElement" path="/apis/react/isValidElement">
* [`useLayoutEffect`](/apis/react/useLayoutEffect) fires before the browser repaints the screen. You can measure layout here.
* [`useInsertionEffect`](/apis/react/useInsertionEffect) fires before React makes changes to the DOM. Libraries can insert dynamic CSS here.
Verifies the object is a React element:
They are rarely used.
```js
React.isValidElement(object);
```
</YouWillLearnCard>
### Suspense {/*suspense*/}
<YouWillLearnCard title="React.lazy" path="/apis/react/lazy">
Define a component that is loaded dynamically:
```js
const SomeComponent = React.lazy(() => import('./SomeComponent'));
```
</YouWillLearnCard>
<YouWillLearnCard title="Suspense" path="/apis/react/Suspense">
Define Suspense boundaries:
```js
<React.Suspense fallback={<Spinner />}>
//...
</React.Suspense>
```
</YouWillLearnCard>
### Transitions {/*transitions*/}
<YouWillLearnCard title="startTransition" path="/apis/react/startTransition">
Mark updates as transitions:
```js
startTransition(() => {
setState(c => c + 1);
});
```
</YouWillLearnCard>
<YouWillLearnCard title="useTransition" path="/apis/react/startTransition">
Mark updates as transitions with pending flags:
```js
const [isPending, startTransition] = useTransition();
```
</YouWillLearnCard>
<YouWillLearnCard title="useDeferredValue" path="/apis/react/useDeferredValue">
Defer to more urgent updates:
```js
const deferredValue = useDeferredValue(value);
```
</YouWillLearnCard>
### Effects {/*effects*/}
<YouWillLearnCard title="useEffect" path="/apis/react/useEffect">
Synchronize external state:
```js
useEffect(() => {
const unsubscribe = socket.connect(props.userId);
return () => {
unsubscribe();
}
}, [props.userId]);
```
</YouWillLearnCard>
<YouWillLearnCard title="useLayoutEffect" path="/apis/react/useLayoutEffect">
Read layout DOM state:
```js
useLayoutEffect(() => {
// Read DOM layout
});
```
</YouWillLearnCard>
<YouWillLearnCard title="useInsertionEffect" path="/apis/react/useInsertionEffect">
Insert styles into the DOM.
```js
useInsertionEffect(() => {
// Insert styles
});
```
</YouWillLearnCard>
### Memoization {/*memoization*/}
<YouWillLearnCard title="useCallback" path="/apis/react/useCallback">
Return a memoized callback.
```js
const handleClick = useCallback(() => {
doSomething(a, b);
}, [a, b]);
```
</YouWillLearnCard>
<YouWillLearnCard title="useMemo" path="/apis/react/useMemo">
---
Return a memoized value.
## Performance Hooks {/*performance-hooks*/}
```js
const value = useMemo(() => {
return calculateValue(a, b);
}, [a, b]);
```
A common way to optimize re-rendering performance is to skip unnecessary work. For example, you can tell React to reuse a cached calculation or to skip a re-render if the data has not changed since the previous render.
</YouWillLearnCard>
To skip calculations and unnecessary re-rendering, use one of these Hooks:
<YouWillLearnCard title="memo" path="/apis/react/memo">
Return a memoized component.
- [`useMemo`](/apis/react/useMemo) lets you cache the result of an expensive calculation.
- [`useCallback`](/apis/react/useCallback) lets you cache a function definition before passing it down to an optimized component.
```js
const MyComponent = React.memo(function MyComponent(props) {
function TodoList({ todos, tab, theme }) {
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
// ...
});
```
</YouWillLearnCard>
### Subscribing {/*subscribing*/}
<YouWillLearnCard title="useSyncExternalStore" path="/apis/react/useSyncExternalStore">
Subscribe to external state.
```js
const state = useSyncExternalStore(subscribe, getSnapshot);
```
</YouWillLearnCard>
### Accessibility {/*accessibility*/}
<YouWillLearnCard title="useId" path="/apis/react/useId">
Generate unique IDs across the server and client:
```js
const id = useId();
}
```
</YouWillLearnCard>
[See the `useMemo` page for more examples.](/apis/react/useMemo)
### Debugging {/*devtools*/}
Sometimes, you can't skip re-rendering because the screen actually needs to update. In that case, you can improve performance by separating urgent updates that must be synchronous (like typing into an input) from non-urgent updates which don't need to block the user interface (like updating a chart).
<YouWillLearnCard title="StrictMode" path="/apis/react/StrictMode">
To prioritize rendering, use one of these Hooks:
Eagerly highlight potential problems.
```js
<StrictMode>{...}</StrictMode>
```
- [`useTransition`](/apis/react/useTransition) lets you mark a state transition as non-urgent and allow other updates to interrupt it.
- [`useDeferredValue`](/apis/react/useDeferredValue) lets you defer updating a non-critical part of the UI and let other parts update first.
</YouWillLearnCard>
<YouWillLearnCard title="useDebugValue" path="/apis/react/useDebugValue">
Display a label for custom hooks.
---
```js
useDebugValue('Custom Label');
```
## Other Hooks {/*other-hooks*/}
</YouWillLearnCard>
These Hooks are mostly useful to library authors and aren't commonly used in the application code.
- [`useDebugValue`](/apis/react/useDebugValue) lets you customize the label React DevTools displays for your custom Hook.
- [`useId`](/apis/react/useId) lets a component associate a unique ID with itself. Typically used with accessibility APIs.
- [`useSyncExternalStore`](/apis/react/useSyncExternalStore) lets a component subscribe to an external store.

36
beta/src/content/apis/react/legacy.md

@ -0,0 +1,36 @@
---
title: "react: Legacy APIs"
---
<Intro>
These APIs are exported from the `react` package, but they are not recommended for use in the newly written code. See the linked individual API pages for the suggested alternatives.
</Intro>
<InlineToc />
---
## Legacy React APIs {/*legacy-react-apis*/}
* [`Children`](/apis/react/Children) lets you manipulate and transform the JSX received as the `children` prop. [See alternatives.](/apis/react/Children#alternatives)
* [`cloneElement`](/apis/react/cloneElement) lets you create a React element using another element as a starting point. [See alternatives.](/apis/react/cloneElement#alternatives)
* [`Component`](/apis/react/Component) lets you define a React component as a JavaScript class. [See alternatives.](/apis/react/Component#alternatives)
* [`createElement`](/apis/react/createElement) lets you create a React element. Typically, you'll use JSX instead.
* [`createRef`](/apis/react/createRef) creates a ref object which can contain arbitrary value. [See alternatives.](/apis/react/createRef#alternatives)
* [`isValidElement`](/apis/react/isValidElement) checks whether a value is a React element. Typically used with [`cloneElement`.](/apis/react/cloneElement)
* [`PureComponent`](/apis/react/PureComponent) is similar to [`Component`,](/apis/react/Component) but it skip re-renders with same props. [See alternatives.](/apis/react/PureComponent#alternatives)
---
## Deprecated React APIs {/*deprecated-react-apis*/}
<Deprecated>
This API will be removed in a future major version of React.
</Deprecated>
* [`createFactory`](/apis/react/createFactory) lets you create a function that produces React elements of a certain type.

31
beta/src/content/apis/react/other.md

@ -0,0 +1,31 @@
---
title: "react: Other APIs"
---
<Intro>
In addition to [Hooks,](/apis/react) the `react` package exports a few components and other APIs that are useful for defining components. This page lists all the modern React APIs that are not Hooks.
</Intro>
<InlineToc />
---
## Built-in React components {/*built-in-react-components*/}
React exposes a few built-in components that you can use in your JSX.
* [`<Fragment>`](/apis/react/Fragment), alternatively written as `<>...</>`, lets you group multiple JSX nodes together.
* [`<Suspense>`](/apis/react/Suspense) lets you display a fallback while the child components are loading.
* [`<StrictMode>`](/apis/react/StrictMode) enables extra development-only checks that help you find bugs early.
---
## Other React APIs {/*other-react-apis*/}
* [`createContext`](/apis/react/createContext) lets you define and provide context to the child components. Used with [`useContext`.](/apis/react/useContext)
* [`forwardRef`](/apis/react/forwardRef) lets your component expose a DOM node as a ref to the parent. Used with [`useRef`.](/apis/react/useRef)
* [`lazy`](/apis/react/lazy) lets you defer loading a component's code until it's rendered for the first time.
* [`memo`](/apis/react/memo) lets your component skip re-renders with same props. Used with [`useMemo`](/apis/react/useMemo) and [`useCallback`.](/apis/react/useCallback)
* [`startTransition`](/apis/react/startTransition) lets you mark a state update as non-urgent. Similar to [`useTransition`.](/apis/react/useTransition)

2
beta/src/content/index.md

@ -19,7 +19,7 @@ This beta website contains the current draft of the new docs.
## How much content is ready? {/*how-much-content-is-ready*/}
* [Learn React](/learn): ~95% finished.
* [API Reference](/apis): ~70% finished.
* [API Reference](/apis): ~85% finished.
You can track our progress [on GitHub.](https://github.com/reactjs/reactjs.org/issues/3308)

0
beta/src/content/community/acknowledgements.md → beta/src/content/learn/acknowledgements.md

0
beta/src/content/community/index.md → beta/src/content/learn/community.md

0
beta/src/content/community/meet-the-team.md → beta/src/content/learn/meet-the-team.md

6
beta/src/hooks/useActiveSection.ts

@ -6,10 +6,10 @@ import {useRouter} from 'next/router';
export function useActiveSection(): 'learn' | 'apis' | 'home' {
const {asPath} = useRouter();
if (asPath.startsWith('/learn')) {
return 'learn';
} else if (asPath.startsWith('/apis')) {
if (asPath.startsWith('/apis')) {
return 'apis';
} else if (asPath.startsWith('/learn')) {
return 'learn';
} else {
return 'home';
}

162
beta/src/sidebarReference.json → beta/src/sidebarAPIs.json

@ -1,5 +1,5 @@
{
"title": "API Reference",
"title": "APIs",
"heading": true,
"path": "/apis",
"routes": [
@ -8,75 +8,9 @@
"path": "",
"routes": [
{
"title": "React APIs",
"title": "react: Hooks",
"path": "/apis/react",
"routes": [
{
"title": "Children",
"path": "/apis/react/Children"
},
{
"title": "cloneElement",
"path": "/apis/react/cloneElement"
},
{
"title": "Component",
"path": "/apis/react/Component"
},
{
"title": "createContext",
"path": "/apis/react/createContext"
},
{
"title": "createElement",
"path": "/apis/react/createElement"
},
{
"title": "createFactory",
"path": "/apis/react/createFactory"
},
{
"title": "createRef",
"path": "/apis/react/createRef"
},
{
"title": "forwardRef",
"path": "/apis/react/forwardRef"
},
{
"title": "Fragment (<>...</>)",
"path": "/apis/react/Fragment"
},
{
"title": "isValidElement",
"path": "/apis/react/isValidElement"
},
{
"title": "lazy",
"path": "/apis/react/lazy"
},
{
"title": "memo",
"path": "/apis/react/memo"
},
{
"title": "PureComponent",
"path": "/apis/react/PureComponent"
},
{
"title": "startTransition",
"path": "/apis/react/startTransition",
"wip": true
},
{
"title": "StrictMode",
"path": "/apis/react/StrictMode",
"wip": true
},
{
"title": "Suspense",
"path": "/apis/react/Suspense"
},
{
"title": "useCallback",
"path": "/apis/react/useCallback"
@ -150,7 +84,46 @@
]
},
{
"title": "ReactDOM APIs",
"title": "react: Other APIs",
"path": "/apis/react/other",
"routes": [
{
"title": "<Fragment> (<>)",
"path": "/apis/react/Fragment"
},
{
"title": "<StrictMode>",
"path": "/apis/react/StrictMode"
},
{
"title": "<Suspense>",
"path": "/apis/react/Suspense"
},
{
"title": "createContext",
"path": "/apis/react/createContext"
},
{
"title": "forwardRef",
"path": "/apis/react/forwardRef"
},
{
"title": "lazy",
"path": "/apis/react/lazy"
},
{
"title": "memo",
"path": "/apis/react/memo"
},
{
"title": "startTransition",
"path": "/apis/react/startTransition",
"wip": true
}
]
},
{
"title": "react-dom",
"path": "/apis/react-dom",
"routes": [
{
@ -158,15 +131,15 @@
"path": "/apis/react-dom/createPortal",
"wip": true
},
{
"title": "flushSync",
"path": "/apis/react-dom/flushSync"
},
{
"title": "findDOMNode",
"path": "/apis/react-dom/findDOMNode",
"wip": true
},
{
"title": "flushSync",
"path": "/apis/react-dom/flushSync"
},
{
"title": "hydrate",
"path": "/apis/react-dom/hydrate"
@ -183,7 +156,7 @@
]
},
{
"title": "ReactDOMClient APIs",
"title": "react-dom\/client",
"path": "/apis/react-dom/client",
"routes": [
{
@ -197,7 +170,7 @@
]
},
{
"title": "ReactDOMServer APIs",
"title": "react-dom\/server",
"path": "/apis/react-dom/server",
"routes": [
{
@ -231,6 +204,45 @@
"wip": true
}
]
},
{
"title": "react: Legacy APIs",
"path": "/apis/react/legacy",
"hasSeparator": true,
"routes": [
{
"title": "Children",
"path": "/apis/react/Children"
},
{
"title": "cloneElement",
"path": "/apis/react/cloneElement"
},
{
"title": "Component",
"path": "/apis/react/Component"
},
{
"title": "createElement",
"path": "/apis/react/createElement"
},
{
"title": "createFactory",
"path": "/apis/react/createFactory"
},
{
"title": "createRef",
"path": "/apis/react/createRef"
},
{
"title": "isValidElement",
"path": "/apis/react/isValidElement"
},
{
"title": "PureComponent",
"path": "/apis/react/PureComponent"
}
]
}
]
}

32
beta/src/sidebarHome.json

@ -1,32 +0,0 @@
{
"title": "Home",
"heading": true,
"path": "/",
"routes": [
{
"heading": true,
"path": "",
"routes": [
{
"title": "Overview",
"path": "/"
},
{
"title": "Community",
"path": "/community",
"routes": [{
"title": "Acknowledgements",
"path": "/community/acknowledgements"
}, {
"title": "Meet the Team",
"path": "/community/meet-the-team"
}]
},
{
"title": "Blog",
"path": "https://reactjs.org/blog"
}
]
}
]
}

16
beta/src/sidebarLearn.json

@ -188,6 +188,22 @@
"path": "/learn/reusing-logic-with-custom-hooks"
}
]
},
{
"title": "Community",
"hasSeparator": true,
"path": "/learn/community",
"routes": [{
"title": "Acknowledgements",
"path": "/learn/acknowledgements"
}, {
"title": "Meet the Team",
"path": "/learn/meet-the-team"
}]
},
{
"title": "Blog",
"path": "https://reactjs.org/blog"
}
]
}

Loading…
Cancel
Save