npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@chrissnyder/react-router-relay

v0.9.0

Published

Nested react-router routes for Relay

Downloads

8

Readme

react-router-relay Travis npm

Relay integration for React Router.

Discord

Usage

Use <RelayRouter> or <RelayRouterContext> instead of <Router> or <RouterContext> respectively, then define Relay queries and render callbacks for each of your routes:

import { RelayRouter } from 'react-router-relay';

/* ... */

const ViewerQueries = {
  viewer: () => Relay.QL`query { viewer }`
};

const WidgetQueries = {
  widget: () => Relay.QL`query { widget(widgetId: $widgetId) }`
}

ReactDOM.render((
  <RelayRouter history={history}>
    <Route
      path="/" component={Application}
      queries={ViewerQueries}
    >
      <Route
        path="widgets" component={WidgetList}
        queries={ViewerQueries}
        queryParams={['color']} stateParams={['limit']}
        prepareParams={prepareWidgetListParams}
        renderLoading={() => <Loading />}
      />
      <Route
        path="widgets/:widgetId" component={Widget}
        queries={WidgetQueries}
      />
    </Route>
  </RelayRouter>
), container);

react-router-relay will automatically generate a combined Relay route with all queries and parameters from the active React Router routes, then pass down the query results to each of the route components. As the queries are all gathered onto a single route, they'll all be fetched at the same time, and the data for your entire page will load and then render in one go.

You can find an example implementation of TodoMVC with routing using react-router-relay at https://github.com/taion/relay-todomvc.

Guide

Installation

Note: Releases from v0.9.0 onward only support React Router v2.x. For React Router 1.x support, use v0.8.0 or earlier.

$ npm install react react-dom react-relay react-router
$ npm install react-router-relay

Routes and queries

For each of your routes that requires data from Relay, define a queries prop on the <Route>. These should be just like the queries on a Relay route:

const ViewerQueries = {
  viewer: () => Relay.QL`query { viewer }`
};

const applicationRoute = (
  <Route
    path="/" component={Application}
    queries={ViewerQueries}
  />
);

Just like with Relay.RootContainer, the component will receive the query results as props, in addition to the other injected props from React Router.

If your route doesn't have any dependencies on Relay data, just don't declare queries. The only requirement is that any route that does define queries must have a Relay container as its component.

Any URL parameters for routes with queries and their ancestors will be used as parameters on the Relay route:

const WidgetQueries = {
  widget: () => Relay.QL`
    query {
      widget(widgetId: $widgetId) # `widgetId` receives a value from the route
    }
  `
}

class Widget extends React.Component { /* ... */ }

Widget = Relay.createContainer(Widget, {
  fragments: {
    widget: () => Relay.QL`
      fragment on Widget {
        name
      }
    `
  }
});

// This handles e.g. /widgets/3.
const widgetRoute = (
  <Route
    path="widgets/:widgetId" component={Widget}
    queries={WidgetQueries}
  />
);

If your route requires parameters from the location query or state, you can specify them respectively on the queryParams or stateParams props on the <Route>. URL and query parameters will be strings, while missing query and state parameters will be null.

If you need to convert or initialize these parameters, you can do so with prepareParams, which has the same signature and behavior as prepareVariables on a Relay container, except that it also receives the React Router route object as an argument.

Additionally, you can use route parameters as variables on your containers:

class WidgetList extends React.Component { /* ... */ }

WidgetList = Relay.createContainer(WidgetList, {
  initialVariables: {
    color: null,
    size: null,
    limit: null
  },

  fragments: {
    viewer: () => Relay.QL`
      fragment on User {
        widgets(color: $color, size: $size, first: $limit) {
          edges {
            node {
              name
            }
          }
        }
      }
    `
  }
});

function prepareWidgetListParams(params, route) {
  return {
    ...params,
    size: params.size ? parseInt(params.size, 10) : null,
    limit: params.limit || route.defaultLimit
  };
};

// This handles e.g. /widgets?color=blue&size=3.
const widgetListRoute = (
  <Route
    path="widgets" component={WidgetList}
    queries={ViewerQueries}
    queryParams={['color', 'size']} stateParams={['limit']}
    prepareParams={prepareWidgetListParams}
    defaultLimit={10}
  />
);

Render callbacks

You can pass in custom renderLoading, renderFetched, and renderFailure callbacks to your routes:

<Route /* ... */ renderLoading={() => <Loading />} />

These have the same signature and behavior as they do on Relay.RootContainer, except that the argument to renderFetched also includes the injected props from React Router. As on Relay.RootContainer, the renderLoading callback can simulate the default behavior of rendering the previous view by returning undefined.

Additional Relay.RootContainer configuration

We pass through additional props on <RelayRouter> or <RelayRouterContext> are to the underlying Relay.RootContainer. You can use this to control props like forceFetch on the Relay.RootContainer:

<RelayRouter
  history={history} routes={routes}
  forceFetch={true}
/>

Notes

  • react-router-relay currently does not support named components.
  • react-router-relay only updates the Relay route on actual location changes. Specifically, it will not update the Relay route after changes to location state, so ensure that you update your container variables appropriately when updating location state.
  • react-router-relay uses referential equality on route objects to generate unique names for queries. If your route objects do not maintain referential equality, then you can specify a globally unique name property on the route to identify it.
  • Relay's re-rendering optimizations only work when all non-Relay props are scalar. As the props injected by React Router are objects, they disable these re-rendering optimizations. To take maximum advantage of these optimizations, you should make the render methods on your route components as lightweight as possible, and do as much rendering work as possible in child components that only receive scalar and Relay props.

Authors