Skip to content

Built-in React Components

Fresh

React provides several built-in components you can use in your JSX.

Fragment (<>...</>)

Lets you group elements without a wrapper DOM node:

jsx
function Post() {
  return (
    <>
      <PostTitle />
      <PostBody />
    </>
  );
}

Equivalent to <Fragment>...</Fragment>. Use the explicit <Fragment> form when you need a key:

jsx
function Blog({ posts }) {
  return posts.map(post => (
    <Fragment key={post.id}>
      <PostTitle title={post.title} />
      <PostBody body={post.body} />
    </Fragment>
  ));
}

StrictMode

Enables additional development-only checks for the component tree inside it:

jsx
import { StrictMode } from 'react';

function App() {
  return (
    <StrictMode>
      <Header />
      <Main />
      <Footer />
    </StrictMode>
  );
}

Strict Mode enables these checks in development:

  • Components re-render an extra time to find impure rendering bugs
  • Effects run an extra cleanup+setup cycle to find missing cleanup
  • Code is checked for usage of deprecated APIs

INFO

There is no way to opt out of Strict Mode inside a tree wrapped by it. This gives you confidence that all components inside are checked.

Suspense

Displays a fallback while child components are loading:

jsx
import { Suspense } from 'react';

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <Albums />
    </Suspense>
  );
}

Props:

  • children - The actual UI you intend to render. If children suspends while rendering, the Suspense boundary switches to fallback.
  • fallback - An alternate UI to render while the actual UI is loading.

Nested Suspense Boundaries

jsx
<Suspense fallback={<BigSpinner />}>
  <Biography />
  <Suspense fallback={<AlbumsGlimmer />}>
    <Panel>
      <Albums />
    </Panel>
  </Suspense>
</Suspense>

React will display the closest parent Suspense boundary's fallback. This lets you nest Suspense boundaries to create a loading sequence.

Suspense with Server Components

jsx
import { Suspense } from 'react';

async function ConferencePage({ slug }) {
  const conf = await db.Confs.find({ slug });
  return (
    <ConferenceLayout conf={conf}>
      <Suspense fallback={<TalksLoading />}>
        <Talks confId={conf.id} />
      </Suspense>
    </ConferenceLayout>
  );
}

async function Talks({ confId }) {
  const talks = await db.Talks.findAll({ confId });
  return <SearchableVideoList videos={talks.map(t => t.video)} />;
}

Profiler

Measures rendering performance of a React tree programmatically:

jsx
import { Profiler } from 'react';

function App() {
  return (
    <Profiler id="App" onRender={onRender}>
      <Navigation />
      <Main />
    </Profiler>
  );
}

function onRender(id, phase, actualDuration, baseDuration, startTime, commitTime) {
  console.log(`${id} ${phase} render took ${actualDuration}ms`);
}

onRender parameters:

  • id - The string id of the Profiler
  • phase - "mount", "update", or "nested-update"
  • actualDuration - Milliseconds spent rendering
  • baseDuration - Estimated render time without memoization
  • startTime / commitTime - Timestamps

WARNING

Profiling adds some overhead. It is disabled in production builds by default.

Activity (Experimental)

Lets you hide and show parts of the UI:

jsx
import { Activity } from 'react';

function TabContainer({ activeTab }) {
  return (
    <div>
      <Activity mode={activeTab === 'posts' ? 'visible' : 'hidden'}>
        <PostsTab />
      </Activity>
      <Activity mode={activeTab === 'photos' ? 'visible' : 'hidden'}>
        <PhotosTab />
      </Activity>
    </div>
  );
}

When mode is "hidden", the component is hidden from the DOM but its state is preserved. This is useful for tab containers where you want to keep state alive.