Permalink
Find file Copy path
268 lines (203 sloc) 7.91 KB

Components

React-Static is packed with awesome components to help you be productive. Some are required for React-Static to work properly, others are available merely for your convenience:

Root

For React Static to work, you must place the Root component at the top of your app. In addition to providing context for React Static components, it also:

  • Automatically smooth-scrolls to hash links
  • Automatically scrolls to the top of the page on route changes
  • Adds a top level @reach/router Router component so Link components work correctly without any configuration
  • Provides render props to support other routers like react-router.

Props

Prop type Default description
disableScroller bool false Toggles all scrolling behavior
autoScrollToTop bool true Toggles scroll-to-top behavior
autoScrollToHash bool true Toggles scroll-to-hash behavior
scrollToTopDuration integer 0 The duration in ms for the scroll-to-top animation
scrollToHashDuration integer 800 The duration in ms for the scroll-to-hash animation
scrollToHashOffset integer 0 The vertical offset of the top of the window from the hash target

Example

// App.js
import { Root, Routes } from 'react-static'

export default () => (
  <Root disableScroller>
    <Routes />
  </Root>
)

Custom Router

Out of the box, React Static ships with a very unopinionated configuation of @reach/router, but you can also use your own router if you'd like. To do this, you'll need to utilize the browser plugin API An example of this can be found in the react-static-plugin-react-router plugin.

Routes

React Static handles all of your routing for you using react-router under the hood. All you need to do is import Routes and specify where you want to render them:

// App.js
import { Root, Routes } from 'react-static'

export default () => (
  <Root>
    <Routes />
  </Root>
)

The routes that will be rendered are the routes returned by the getRoutes function of this config.

Custom Routes Rendering

Occasionally, you may need to render the automatic <Routes> component in a custom way. The most common use-case is illustrated in the animated-routes example transitions. To do this, utilize a render prop:

import { Root, Routes } from 'react-static'

// This is the default renderer for `<Routes>`
const RenderRoutes =

export default () => (
  <Root>
    <Routes>
      {({ getComponentForPath }) => {
        // The pathname is used to retrieve the component for that path
        let Comp = getComponentForPath(window.location.href)
        // The component is rendered!
        return <Comp />
      }}
    </Routes>
  </Root>
)

Render Props - These special props are sent to your rendered component or render function

  • getComponentForPath(pathname) => Component - Takes a pathname and returns the component (if it exists) to render that path. Returns false if no component is found.

RouteData

RouteData and its companion HOC withRouteData are what provide a component with the results of the currently matched route's getData function as defined in your static.config.js.

Props

  • component: ReactComponent
  • render: Function
  • children: Function

Render Props

  • Any props that you passed in its corresponding route's getData method.
  • is404: boolean - Will be set to true if the page requests results in a 404. This is useful for runtime 404s where the url of the page may remain what the user requested, but the route is not found.

Here is a an example show all of the different syntaxes you can use:

static.config.js

module.exports = {
  getRoutes: () => [
    {
      path: '/top-100-songs',
      getData: async () => ({
        songs: await SpotifyAPI.getTopSongs(100),
      }),
    },
  ],
}

TopSongs.js

import { RouteData } from 'react-static'

export default () => (
  <RouteData>
    {({ songs }) => (
      <div>
        <h1>Top 100 Spotify Songs</h1>
        <ul>
          {songs.map(song => (
            <li key={song.id}>{song.title}</li>
          ))}
        </ul>
      </div>
    )}
  </RouteData>
)
import { RouteData, withRouteData } from 'react-static'

export default withRouteData(({ songs }) => (
  <div>
    <h1>Top 100 Spotify Songs</h1>
    <ul>
      {songs.map(song => (
        <li key={song.id}>{song.title}</li>
      ))}
    </ul>
  </div>
))

SiteData

SiteData and its companion HOC withSiteData are what provide a component with the results of the getSiteData function as defined in your static.config.js.

static.config.js

module.exports = {
  getSiteData: () => ({
    siteTitle: 'React Static',
    metaDescription: 'A progressive static-site framework for React',
  }),
}

Home.js

import { SiteData } from 'react-static'

export default () => (
  <SiteData>
    {({ siteTitle, metaDescription }) => (
      <div>
        Welcome to {siteTitle}! {metaDescription}
      </div>
    )}
  </SiteData>
)
import { SiteData, withSiteData } from 'react-static'

export default withSiteData(({ siteTitle, metaDescription }) => (
  <div>
    Welcome to {siteTitle}! {metaDescription}
  </div>
))

Head

Head is a react component for managing tags in the document's head. Use it to update meta tags, title tags, etc.

  • It can be used anywhere in your app.
  • It can be used in multiple places at the same time.
  • For more information, see the React-Helmet library that React Static uses to accomplish this.

Example:

import { Head } from 'react-static'

export () => (
  <div>
    <Head>
      <meta charSet="UTF-8" />
      <title>This is my page title!</title>
    </Head>
    <div>
      My page content...
    </div>
  </div>
)

Prefetch

Prefetch is a react component that can prefetch the assets for a given route when visibly rendered in the viewport. When its content or element are visible in the viewport, the template and data required to render the path in the path prop will be prefetched. This increases the chance that if the user then navigates to that route, they will not have to wait for the required data to load. You can also force the prefetch to happen even if the element is outside the viewport via the force prop.

Props:

  • path: String Required - The path you want to prefetch.
  • force: Boolean - Force the prefetch even if the element is not visible in the viewport

Notes:

  • If the path doesn't match a valid static route, nothing will happen.
  • If the route has already been loaded in the session, nothing will happen.
  • If multiple instances of the same path are prefetched at the same time, only a single request will be made for all instances.
  • If abused, this component could result in fetching a lot of unused data. Be smart about what you prefetch.

Example:

import { Prefetch } from 'react-static'
import { Link } from '@reach/router'

// Standalone
<Prefetch path='/blog' />

// With children
<Prefetch path='/blog'>
  <Link to='/blog'>
    Go to blog
  </Link>
</Prefetch>

// With a custom refHandler
<Prefetch path='/blog'>
  {({ handleRef }) => (
    <MyComponent ref={handleRef}/>
  )}
</Prefetch>