Declarative routing for React

Last update: Jun 22, 2022

Welcome to React Router 路 build

React Router is a lightweight, fully-featured routing library for the React JavaScript library. React Router runs everywhere that React runs; on the web, on the server (using node.js), and on React Native.

If you're new to React Router, we recommend you start with the getting started guide.

If you're migrating to v6 from v5 (or v4, which is the same as v5), check out the migration guide. If you're migrating from Reach Router, check out the migration guide for Reach Router. If you need to find the code for v5, it is on the v5 branch.

When v6 is stable we will publish the docs on our website.

Contributing

There are many different ways to contribute to React Router's development. If you're interested, check out our contributing guidelines to learn how you can get involved.

Packages

This repository is a monorepo containing the following packages:

Changes

Detailed release notes for a given version can be found on our releases page.

Funding

You may provide financial support for this project by donating via Open Collective. Thank you for your support!

About

React Router is developed and maintained by Remix Software and many amazing contributors.

GitHub

https://github.com/ReactTraining/react-router
Comments
  • 1. Server rendering

    Route.spec.js contains a commented out test for server rendering but it seems, server rendering would at least require exposing findMatches in the main module.

    Any plans for reintroducing server rendering support?

    Reviewed by simenbrekken at 2014-06-29 18:57
  • 2. Rewrite, version 1.0

    NOTE: DO NOT MERGE YET

    This PR is a complete rewrite of the router with the following goals in mind:

    • simpler top-level API with less boilerplate
    • async route config and/or component loading (better support for code splitting in large apps)
    • simpler API for server-side rendering
    • more React-like <RouteHandler> API
    • easier data fetching API

    ... and a bunch of other stuff that we've learned from various issues over the past year.

    Here's a summary of the various things you can do:

    Top-level API

    var { createRouter, Route } = require('react-router');
    
    var Router = createRouter(
      <Route component={App}>
        <Route name="home" component={Home}/>
      </Route>
    );
    
    // The minimal client-side API requires you to pass a history object to your router.
    var BrowserHistory = require('react-router/lib/BrowserHistory');
    React.render(<Router history={BrowserHistory}/>, document.body);
    
    // On the server, you need to run the request path through the router
    // first to figure out what props it needs. This also works well in testing.
    Router.match('/the/path', function (error, props) {
      React.renderToString(<Router {...props}/>);
    });
    

    The props arg here contains 4 properties:

    • location: the current Location (see below)
    • branch: an array of the routes that are currently active
    • params: the URL params
    • components: an array of components (classes) that are going to be rendered to the page (see below for component loading)

    The branch and components are particularly useful for fetching data, so you could do something like this:

    BrowserHistory.listen(function (location) {
      Router.match(location, function (error, props) {
        // Fetch data based on what route you're in.
        fetchData(props.branch, function (data) {
          // Use higher-order components to wrap the ones that we're gonna render to the page.
          wrapComponentsWithData(props.components, data);
          React.render(<Router {...props}/>, document.body);
        });
      });
    });
    

    Inside your App component (or any component in the hierarchy) you use this.props.children instead of <RouteHandler> to render your child route handler. This eliminates the need for <RouteHandler>, context hacks, and <DefaultRoute> since you can now choose to render something else by just checking this.props.children for truthiness.

    <NotFoundRoute> has also been removed in favor of just using <Route path="*">, which does the exact same thing.

    Non-JSX Config

    You can provide your route configuration using plain JavaScript objects; no JSX required. In fact, all we do is just strip the props from your JSX elements under the hood to get plain objects from them. So JSX is purely sugar API.

    var Router = createRouter(
      {
        component: App,
        childRoutes: [{
          name: 'home',
          component: Home
        }]
      }
    );
    

    Note the use of childRoutes instead of children above. If you need to load more route config asynchronously, you can provide a getChildRoutes(callback) method. For example, if you were using webpack's code splitting feature you could do:

    var Router = createRouter(
      {
        component: App,
        getChildRoutes(callback) {
          require.ensure([ './HomeRoute' ], function (require) {
            callback(null, [ require('./HomeRoute') ]); // args are error, childRoutes
          }
        }
      }
    );
    

    Which brings me to my next point ...

    Gradual Path Matching

    Since we want to be able to load route config on-demand, we can no longer match the deepest route first. Instead, we start at the top of the route hierarchy and traverse downwards until the entire path is consumed by a branch of routes. This works fine in most cases, but it makes it difficult for us to nest absolute paths, obviously.

    One solution that @ryanflorence proposed was to let parent routes essentially specify a function that would return true or false depending on whether or not that route thought it could match the path in some grandchild. So, e.g. you would have something like:

    var Router = createRouter(
      {
        path: '/home',
        component: Home,
        childRouteCanMatch(path) {
          return (/^\/users\/\d+$/).test(path);
        },
    
        // keep in mind, these may be loaded asynchronously
        childRoutes: [{
          path: '/users/:userID',
          component: UserProfile
        }]
      }
    );
    

    Now, if the path were something like /users/5 the router would know that it should load the child routes of Home because one of them probably matches the path. This hasn't been implemented yet, but I thought I'd mention it here for discussion's sake.

    Async Component Loading

    Along with on-demand loading of route config, you can also easily load components when they are needed.

    var Router = createRouter(
      {
        path: '/home',
        getComponents(callback) {
          require.ensure([ './Home' ], function (require) {
            callback(null, require('./Home')); // args are error, component(s)
          }
        }
      }
    );
    

    Rendering Multiple Components

    Routes may render a single component (most common) or multiple. Similar to ReactChildren, if components is a single component, this.props.children will be a single element. In order to render multiple components, components should be an object that is keyed with the name of a prop to use for that element.

    var App = React.createClass({
      render() {
        var { header, sidebar } = this.props;
        // ...
      }
    });
    
    var Router = createRouter(
      {
        path: '/home',
        component: App,
        childRoutes: [{
          path: 'news',
          components: { header: Header, sidebar: Sidebar }
        }]
      }
    );
    

    Note: When rendering multiple child components, this.props.children is null. Also, arrays as children are not allowed.

    Props

    Aside from children, route components also get a few other props:

    • location: the current Location (see below)
    • params: the URL params
    • route: the route object that is rendering that component

    Error/Update Handling

    The router also accepts onError and onUpdate callbacks that are called when there are errors or when the DOM is updated.

    History/Location API

    Everything that used to be named *Location is now called *History. A history object is a thing that emits Location objects as the user navigates around the page. A Location object is just a container for the path and the navigationType (i.e. push, replace, or pop).

    History objects are also much more powerful now. All have a go(n) implementation, and HTML5History and History (used mainly for testing) have reliable canGo(n) implementations.

    There is also a NativeHistory implementation that should work on React Native, tho it's a little tricky to get it working ATM.

    Transition Hooks

    The willTransitionTo and willTransitionFrom transition hooks have been removed in favor of more fine-grained hooks at both the route and component level. The transition hook signatures are now:

    • route.onLeave(router, nextState)
    • route.onEnter(router, nextState)

    Transition hooks still run from the leaf of the branch we're leaving, up to the common parent route, and back down to the leaf of the branch we're entering, in that order. Additionally, component instances may register hook functions that can be used to observe and/or prevent transitions when they need to using the new Transition mixin. Component instance-level hooks run before route hooks.

    var { Transition } = require('react-router');
    
    var MyComponent = React.createClass({
      mixins: [ Transition ],
      transitionHook(router) {
        if (this.refs.textInput.getValue() !== '' && prompt('Are you sure?'))
          router.cancelTransition();
      },
      componentDidMount() {
        this.addTransitionHook(this.transitionHook);
      },
      componentWillUnmount() {
        this.removeTransitionHook(this.transitionHook);
      },
      render() {
        return (
          <div>
            <input ref="textInput" type="text"/>
          </div>
        );
      }
    });
    

    Anyway, apologies for the long-winded PR, but there's a lot of stuff here! Please keep comments small and scoped to what we're doing here. I'd hate for this to turn into a huge thread :P

    Edit: Added data-loading example. Edit: Added transition hooks. Edit: Added props for named children, disallow arrays. Edit: Added addTransitionHook/removeTransitionHook API. Edit: Renamed Router.run => Router.match Edit: Removed static transition hooks

    Stuff we still need:

    Ok. Stuff we still need here:

    • [ ] Support absolute paths inside nested UI somehow in new path matching algorithm
    • [x] ~~Move routerWillLeave hook to instance lifecycle method instead of static~~ Add component-level API for observing/preventing transitions
    • [x] Add back scroll history support (@gaearon can you help w/ this?)
    • [ ] Maybe remove canGo(n) support (@taurose can you help determine if the current impl. is legit or not? if not, let's just remove it)

    COME ON! LET'S GET THIS MERGED AND SHIP 1.0!!!!

    Reviewed by mjackson at 2015-05-06 06:54
  • 3. RFC: Relative Links and Routes

    We intend to ship Relative Routes and Relative Links soon. I'd like to hear people's comments on something I'm not totally sure about yet.

    What are Relative Links and Routes?

    Instead of <Route path={match.path + '/more/stuff'}/> you could simply do <Route path="more/stuff"/> and Router will use the lack of / at the start of your path as a hint that you want to just use whatever path is above you. Relative!

    Same with links. Instead of <Link to={match.url + '/more/stuff'}/> you can just do <Link to="more/stuff"/>.

    The Problem

    Going "down" as shown in the quick example up there is easy. But we're not sure what ".." should mean. There are two options for what it means: go up a URL segment, or go up a matched route.

    Go up a URL segment

    With plain anchors tags, .. means "up a URL segment". Given the following URL, an anchor tag with the following HREFs results in the following URLs:

    /clients/invoice/123
    

    href | url -----|----- payments | /clients/invoice/123/payments | /clients/invoice/123 . | /clients/invoice/123 .. | /clients/invoice ../ | /clients/invoice ../.. | /clients ../../ | /clients

    (As far as I can tell, feel free to double check!)

    So I think everybody's intuition around this is to just do exactly that and be done with it. Ship it.

    However, I have this gut instinct that our intuition right now might be keeping us from a better meaning of ".." in a React Router app?

    Go up a matched Route

    Maybe your app is something like this:

      <Switch>
        <Route exact path="/" component={Home}/>
        <Route path="/clients" render={() => (
          <Clients>
            <Switch>
              <Route exact path="." component={ClientList}/>
              <Route path="invoice/:invoiceId" component={Invoice}/>
            </Switch>
          </Clients>
        )}/>
      </Switch>
    

    Maybe we want ".." to mean "go up a matched route" rather than "go up some url segments".

    So now the "relative" portion of the Link's to prop is the parent Route's path, not the current location.

    to prop | link's url -----|----- .. | /clients ../.. | /

    Notice .. doesn't go to "invoice" because that's not a route that will ever match.

    Pros

    • When you change a parent Route's path prop, the relative links below don't need to be updated
    • You can't link to something that doesn't have UI (probably, see cons*)

    Cons

    • *Since any ol' route can match a location w/o a relationship with other Route's that match, a Link in one place can potentially have a completely different href than a link somewhere else--even though they have the same to prop 馃槵. It all depends on the Route's path the Link is rendered within.
    • It's against most people's intuition

    What do you think?

    Reviewed by ryanflorence at 2017-05-16 23:33
  • 4. [added] Router.renderRoutesToString

    This PR allows the path to be given to as a prop.

    <Routes initialPath="/some/path"> ... </Routes>
    

    This only works server side. This patch also stops the URLStore and RoutesStore being started as componentWillMount is called but componentWillUnmount isn't call on server side. This would lead to a memory leak and potential async issue when multiple pages are being rendered at once.

    When rendering on server side you should always make a new instance of <Routes> so if multiple pages are being rendered they don't change the routes in another page.

    var App = React.createClass({
      render: function(){
        return <Routes initialPath={this.props.initialPath} location="history"> ... </Routes>
      }
    });
    
    //server side
    React.renderComponentToString(<App initialPath="/some/path" />);
    
    //client side
    React.renderCompoent(<App />, domelement);
    
    Reviewed by karlmikko at 2014-08-07 23:21
  • 5. Proposal: Replace AsyncState with getAsyncProps

    Edit: Please read my updated proposal as well

    I'd like to propose adding two new transition hooks, didTransitionTo and didTransitionFrom that are designed to replace the AsyncState mixin. Currently, AsyncState has the following quirks/limitations:

    • It keeps data in this.state, but data is passed passed to children through props in render
    • It's a mixin but it was only ever intended to be used in route handler components, so users may be inclined to use it in other components (which we don't support). Also, it means that users need to declare the mixin

    The goals for these two new transition hooks are:

    • Keep data in props, where it belongs. this.state should be used for UI state
    • Keep the ability for components to subscribe to changes in data, but also have a way to let components know that data only needs to be fetched once (for server rendering)
    • Keep the ability for components to fetch data in parallel
    • More clearly indicate that data fetching behavior belongs in route handlers, and not other components and eliminate the need for users to declare a mixin in order to use it

    I believe the following API satisfies all of the above requirements. Feedback is welcome.

    var User = React.createClass({
    
      statics: {
    
        // This hook is called after the transition has been validated by all
        // willTransition* hooks. The setProps argument is a function that
        // can be used to set props ad hoc (like AsyncState's setState).
        didTransitionTo: function (params, query, singleRun, setProps) {
          // If you have an immediate value, use it.
          setProps({ user: UserStore.getUserByID(params.userID) });
    
          // If we're not on the server, subscribe to changes in the data.
          if (!singleRun) {
            this.userListener = function () {
              setProps({ user: UserStore.getUserByID(params.userID) });
            };
    
            UserStore.addChangeListener(this.userListener);
          }
    
          // Or, ignore setProps entirely and return a hash of values that should
          // be used as props. Values may be immediate or promises. As they
          // resolve, props are updated.
          return {
            user: fetchUser(params.userID)
          };
        },
    
        // This hook is called after the transition has been validated by all
        // willTransition* hooks.
        didTransitionFrom: function () {
          UserStore.removeChangeListener(this.userListener);
        }
    
      },
    
      // The render method needs to be resilient to the fact that props
      // may not yet be loaded.
      render: function () {
        var user = this.props.user;
        var name = user == null ? 'anonymous' : user.name;
    
        return <div className="user-component">Hello {name}!</div>;
      }
    
    });
    

    Note that, although this API looks similar to the willTransition* API, it has two key differences:

    • handlers are run in parallel, not in sequence, so all data can be fetched at the same time
    • the resolution of these handlers does not block the transition from happening

    Thanks to @rpflorence for giving me feedback and helping me think through this API earlier today!

    Edit: Updated example code to make setProps the last (optional) argument to didTransitionTo.

    Reviewed by mjackson at 2014-09-03 21:44
  • 6. v2 Roadmap

    This might not be the best way to manage this (one gigantic issue), but @mjackson and I are a solid 50% done with all of this anyway, so I'm not too concerned.

    @taion you'll likely have some questions since this affects a lot of what you're trying to do, please chat me up on discord before we clog up this issue with back-and-forth conversation :)

    Router 2.0 Roadmap

    TOC

    Motivations for the following API changes are all about cleaning up and clarifying the coupling between React Router and History; this generally translates to "You won't need to know anything about History anymore."

    • Learning the router is complicated by History, you have to learn both APIs and the line between them is unclear. This affects end users trying to use the libraries together as well as contributors (for example duplication of docs is also a problem).
    • We have some rough edges around ingration with libraries like React native, Redux, Relay, and our own AsyncProps.
    • React 15 is only going to allow components to export only one object to "context" (we only want one anyway)

    The following issues should help address these concerns.

    Note about upgrading

    All v1.0.0 APIs will continue to work in v2.0.0. An app using only public API should be able to drop in v2.0.0 and just get warnings. Old API will be removed in 3.0.0. If you update your code and no longer get warnings, you should be able to upgrade to 3.0 w/o trouble.

    Ship History 2.0

    It's really just removing deprecated API. The rest of these items all kind of depend on it though.

    Refactor route matching out of useRoutes and into match

    Background

    Currently we wrap a history with useRoutes so it is now aware of routes and performs the match against them. This changes the signature and timing of listen (making it async) causing difficulty when integrating or using alongside libraries like redux and react native.

    Additionally, navigating outside of components (like in flux and redux) is complicated by Router wrapping the history provided as a prop.

    Goals

    • Remove need for listenRoutes to integrate with other libs
    • Make navigating outside of components simpler for redux/flux etc.
    • Not require apps to wrap their singleton history in things like useQueries in order to navigate outside of components
    • apps can still learn about History and add behavior if they choose, (custom queryString parsing, etc.) and Router should not touch the history provided

    Upgrading

    ////////////////////////////////////////////////////////////////////////////////
    // Rendering
    // v1.0.0
    import createBrowserHistory from 'history/lib/createBrowserHistory'
    render(<Router history={createBrowserHistory()}/>, el)
    
    // v2.0.0
    import { browserHistory } from 'react-router'
    render(<Router history={browserHistory}/>, el)
    
    ////////////////////////////////////////////////////////////////////////////////
    // Navigating outside of components
    
    // v1.0.0
    // probably exported from a module somehwere like this
    import createBrowserHistory from 'history/lib/createBrowserHistory'
    import useQueries from 'history/lib/useQueries'
    const createHistory = useQueries(createBrowserHistory)
    export default createHistory()
    // and then used in an action or somehwere
    import appHistory from './appHistory'
    appHistory.push(...)
    
    // v2.0.0
    // React Router exports a singleton
    import { browserHistory } from 'react-router'
    browserHistory.push(...)
    

    Tasks

    While the nitty gritty won't be this simple, this is what will probably need to happen:

    • remove useRoutes and move all route matching to match
    • use match inside of Router instead of wrapping the history provided in anything (don't alter history)
    • create hashHistory and browserHistory singletons, exported from index.js
    • remove default to hashHistory and require devs to provide one, should help with people not understanding that there's a better option, and allow devs to decrease the bundle size of their app

    Export only router to context

    Background

    Right now we put history, location, and route (sometimes) on context, we also pass a bag of props to route components. Turns out there's some overlap between them. We're tempted to add more to context, and add more to props because the line and purpose between them isn't clear.

    React Router continues to strive to be just one library in a wonderful ecosystem of other libraries, prescribing strategies for data flow in an app is not our goal. We will put only what we absolutely need in context (which can be summed up with "what does Link need?). Everything else will go to route components as props. The opinions of the app can take over from there.

    Context was recently documented, so we no longer need the mixins to hide the context API. It's up to the app to decide if it wants to use context directly or continue to hide it with mixins or higher order components.

    Also, react 15 or 16 will only allow one contextType. We've been talking about only have one context type for a while. Now is the time.

    Finally, in the global effort to make History an implementation detail, we need to provide something else to navigate around in components.

    Goals

    • Make separation between what is on context v. route props clear, and remove overlap
    • Let apps decide how to get props the router gives them down the render tree
    • Remove need to learn History API

    Tasks

    • Deprecate all items on context: history, location, route

    • Add context.router that looks like this:

      router: shape({
        push: func,
        replace: func,
        isActive: func,
        addRouteLeaveHook: func
      })
      
    • Pass router as a prop to route components

    • Deprecate all mixins

    • Deprecate passing history to route components

    • proxy push/replace/isActive/addRouteLeaveHook to underlying history (so integration with a custom history will work)

    • automatically remove route leave hooks since we should know everything we need to know, so devs don't have to and there's no reason to leave them hanging around.

    Upgrading

    History methods

    In all cases where you once had a history for navigation, you now have a router with different methods.

    // v1.0.0
    history.pushState(state, path, query)
    history.replaceState(state, path, query)
    
    // v2.0.0
    router.push(path)
    router.push({ path, query, state }) // new "location descriptor"
    
    router.replace(path)
    router.replace({ path, query, state }) // new "location descriptor"
    

    Navigating in route components

    // v1.0.0
    class RouteComponent extends React.Component {
      someHandler() {
        this.props.history.pushState(...)
      }
    }
    
    // v2.0.0
    class RouteComponent extends React.Component {
      someHandler() {
        this.props.router.push(...)
      }
    }
    

    Navigating inside deeply nested components

    // v1.0.0
    const DeepComponent = React.createClass({
      mixins: [ History ],
    
      someHandler() {
        this.history.pushState(...)
      }
    }
    
    // v2.0.0
    // You have a couple options:
    // Use context directly (recommended)
    const DeepComponent = React.createClass({
      contextTypes: {
        router: object.isRequired
      },
    
      someHandler() {
        this.context.router.push(...)
      }
    }
    
    // create your own mixin:
    const RouterMixin = {
      contextTypes: {
        router: object.isRequired
      },
      componentWillMount() {
        this.router = this.context.router
      }
    }
    
    const DeepComponent = React.createClass({
      mixins: [ RouterMixin ],
      someHandler() {
        this.history.pushState(...)
      }
    }
    
    // use the singleton history you are using when the router was rendered,
    import { browserHistory } from 'react-router'
    
    const DeepComponent = React.createClass({
      someHandler() {
        browserHistory.push(...)
      }
    }
    

    Lifecycle Mixin with route components

    // v1.0.0
    const RouteComponent = React.createClass({
      mixins: [ Lifecycle ],
      routerWillLeave() {
        // ...
      }
    })
    
    // v2.0.0
    const RouteComponent = React.createClass({
      componentDidMount() {
        const { router, route } = this.props
        router.addRouteLeaveHook(route, this.routerWillLeave)
      }
    })
    
    // or make your own mixin, check it out in the next section
    

    Lifecycle Mixin with deep, non-route components

    // v1.0.0
    const DeepComponent = React.createClass({
      mixins: [ Lifecycle ],
      routerWillLeave() {
        // do stuff
      }
    })
    
    // v2.0.0
    // you have a couple of options
    // first you can put the route on context in the route component
    const RouteComponent = React.createClass({
      childContextTypes: {
        route: object
      },
    
      getChildContext() {
        return { route: this.props.route }
      }
    })
    
    // and then access it on your deep component
    const DeepComponent = React.createClass({
      contextTypes: {
        route: object.isRequired,
        router: objec.isRequired
      },
    
      componentDidMount() {
        const { router, route } = this.context
        router.addRouteLeaveHook(route, this.routerWillLeave)
      }
    })
    
    // or make your own mixin that will work for both route components and
    // deep components alike (as long as your route component puts `route`
    // on context
    const Lifecycle = {
      contextTypes: {
        route: object.isRequired,
        router: objec.isRequired
      },
    
      componentDidMount() {
        const router = this.context.router
        const route = this.props.route || this.context.route
        router.addRouteLeaveHook(route, this.routerWillLeave)
      }
    }
    

    Add render prop to Router, remove RoutingContext prop

    Background

    The functional composition of history is awesome, but we also need this kind of composition for React Router when it's time to render. While we can add some behavior into history we lack the necessary lifecycle hooks that components give us. Integrations also need all of the routing information in aggregate (like all the components and routes).

    Our current workaround is the RoutingContext prop, but that only lets us add one level of behavior. Consider an app that was built with Async Props, but now wants to iterate to using Relay, as well as add a new scroll restoring behavior. If each of these components used the RoutingContext prop API, they would all render a RoutingContext and therefore can't be used together.

    Goals

    • Allow integration for middleware components that need lifecycle hooks and the aggregate routing information
    • Allow multiple levels of behavior, not just one

    Upgrading

    // v1.0.0
    render(<Router RoutingContext={AsyncProps}/>, el)
    
    // v2.0.0
    render((
      <Router render={(props) => (
        <AsyncProps {...props} render={(props) => (
          <RoutingContext {...props} />
        )}/>
      )}/>
    ), el)
    
    // While that's more code, now we can do this:
    render((
      <Router render={(props) => (
        <AsyncProps {...props} render={(props) => (
          <RelayRoutes {...props} render={(props) => (
            <ScrollRestorer {...props} render={(props) => (
              <RoutingContext {...props} />
            )}/>
          )}/>
        )}/>
      )}/>
    ), el)
    

    Tasks

    • Remove RoutingContext prop, no need for deprecation warnings, it's undocumented and everybody we've told to try it got an earful of "we aren't sure about this thing yet"
    • Add render prop to Router
    • Add a default prop that just renders a RoutingContext
    • Write a document about how to write a middleware component (should continue to send down the props in a method called render

    Holy smokes that looks like a lot, it's really not too much, and we're feeling really good about it all.

    Reviewed by ryanflorence at 2015-12-05 15:54
  • 7. Allow transition hooks access to a context object you can specify when you create the router.

    I've been trying to make an authentication mixin that can access the state in one of my flux stores but am not using singletons that I can make available to the static methods. Would it be alright to pass a context object through to the static willTransition hook methods to allow them access to arbitrary services you might need?

        var context = {...}
        Router.create({routes: routes, transitionContext: context})
    
        statics: {
          willTransitionTo: function(transition) {
             var loginState = transition.context.getStore(LoginStore).getState();
          }
        }
    
    Reviewed by bobpace at 2014-12-11 06:49
  • 8. Server rendering dynamic routes

    I use server side rendering with some code splitting routes. It looks like OK on my server side with shim require.ensure. But I get the following warning on my client side:

    Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
     (client) ctid=".bqth22sav4"><noscript data-reacti
     (server) ctid=".bqth22sav4"><div data-reactid=
    

    Here is the main part of my client side codes:

    
    const store = createStore(getInitialState());
    const history = createHistory();
    const { pathname, search } = window.location;
    const location = createLocation(pathname + search);
    
    match({ routes, location }, (err, redirectLocation, renderProps) => {
        render(
            <Provider store={store}>
                <Router
                    {...renderProps}
                    history={history}
                />
            </Provider>,
            document.getElementById('mount')
        );
    });
    

    Regards.

    Reviewed by Cap32 at 2015-09-21 16:58
  • 9. React Native

    Just tracking react native thoughts here. My assumptions are probably all wrong since 1) I don't know much about native dev and 2) I've spent 5 minutes with react native but:

    1. Looks like a component is mounted as the "top level" thing, the router listens to a location and then renders an app, so the basic usage is probably going to be slightly different, your top level component has route definitions and gets a url passed in as a prop or something.
    2. We need some sort of iOS Location and eventually an Android location, it'll probably be stored in memory and persisted to some sort of localStorage equivalent. When the app boots we look at the URI requesting the launch first, and then the localStorage (whatever it really is) second.

    Again, I have no idea what I'm talking about yet. 炉(潞_o)/炉

    Reviewed by ryanflorence at 2015-01-31 03:24
  • 10. this.context.router is undefined

    I just upgraded to react-router (and react) 0.13, and got rid of all the deprecated State mixins. Using this.context.router doesn't seem to work. I just see this everywhere:

    Uncaught TypeError: Cannot read property 'getParams' of undefined
    

    Is there anything additional I need to do?


    Edit by Ryan Florence to get people to the answer right here at the top of the issue :dancer:

    Check out the upgrade guide: https://github.com/rackt/react-router/blob/master/UPGRADE_GUIDE.md#012x---013x

    Sorry it wasn't done w/ the release, it's been an abnormally busy month for us since we quit our jobs and started a new business :P

    Reviewed by tjwebb at 2015-03-21 06:00
  • 11. ActiveState changes don't propagate if any single parent in hierarchy declares shouldComponentUpdate

    If I have a component using ActiveState mixin and some of its parents declare shouldComponentUpdate, the child won't update when active state changes.

    This is not normal because usually parent's shouldComponentUpdate doesn't magically cut the child off updates. If child listens to some store and calls setState, it will be updated. But this is not the case with context.

    Even if parent's shouldComponentUpdate implementation takes nextContext into account, it won't even get nextContext if it doesn't declare contextTypes itself. So basically, for ActiveState to work in a project that heavily uses shallow-comparing shouldComponentUpdate or something similar, all ancestors of ActiveState-using component need to also have ActiveState.

    See this React issue and this fiddle.

    Obviously it's a React's problem per se but since router relies on context so much, it's worth documenting.

    Reviewed by gaearon at 2014-11-13 17:29
  • 12. [Docs]: Describing Layout route components structure

    The current documentation for Layout routes gives a perception that they wrap around the child route components where as they require an outlet to render the child route components.

    For example, we expect the layout component to be doing something like this:

    function Layout(props) {
      return (
        <div>
          {props.children}
        </div>
      );
    }
    

    where as it uses an outlet component to render the child route components:

    function Layout(props) {
      return (
        <div>
          <Outlet />
        </div>
      );
    }
    

    This has created some confusion in the community,

    This PR updates the docs to describe Layout component structure and the need for using an outlet component.

    Reviewed by gowthamvbhat at 2022-06-22 04:00
  • 13. Feat: Add deferred support

    • Add's deferred() support to loader's in data routers
    • Unit tests cover main usages
    • Can be manually tested via the examples/data-router app using the /deferred and /deferred/child routes
      • probably need to run via USE_SOURCE=true npm run dev
    Reviewed by brophdawg11 at 2022-06-21 21:46
  • 14. Fix the definition of the `To` type in the docs

    The To type originates in the history source code here: https://github.com/remix-run/history/blob/3e9dab413f4eda8d6bce565388c5ddb7aeff9f7e/packages/history/index.ts#L178

    This PR updates the React Router docs to have the correct definition of To. To can be a partial of Path, not Location.

    Reviewed by srmagura at 2022-06-16 16:51
  • 15. Feat: SSR support for data routers

    This PR handles some SSR edge cases for the remix router and adds an example of SSR using DataStaticRouter.

    • createRouter now takes an isSSR flag which makes minor internal behavioral changes for SSR
    • DataStaticRouter now accepts the router itself, the server is responsible for router instantiation and initial navigation
    Reviewed by brophdawg11 at 2022-06-15 16:07
  • 16. [Bug]: v6.4 DataBrowserRouter with React 18's hydrateRoot

    What version of React Router are you using?

    6.4.0-pre-7 + React 18.1.0

    Steps to Reproduce

    Issue occurs when using React 18's hydrateRoot on server-rendered content, using a <DataBrowserRouter> on the client and a <StaticRouter> on the server.

    Have created a [possibly bad] repro via CodeSandbox here

    Swapping to <BrowserRouter> removes the error, and no hydration errors occur.

    Expected Behavior

    Hydration should occur without errors when using ReactDOMClient.hydrateRoot.

    Actual Behavior

    The following error is thrown:

    Uncaught Error: Missing getServerSnapshot, which is required for server-rendered content. Will revert to client rendering.
        at mountSyncExternalStore (react-dom.development.js:16790:13)
        at Object.useSyncExternalStore (react-dom.development.js:17733:14)
        at useSyncExternalStore (react.development.js:1676:21)
        at useRenderDataRouter (components.tsx:77:28)
        at DataBrowserRouter (index.tsx:179:10)
        at renderWithHooks (react-dom.development.js:16311:18)
        at mountIndeterminateComponent (react-dom.development.js:20080:13)
        at beginWork (react-dom.development.js:21593:16)
        at HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14)
        at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16)
    
    Reviewed by manspaniel at 2022-06-13 00:35
A React component to render your pagination navigation

A React component to render your pagination navigation

Dec 12, 2021
React Pagination Utils

React Pagination Utils

May 26, 2022
HTML CSS & React - Pagination component
HTML CSS & React - Pagination component

React component to fetch GitHub followers and showcase certain amount at each page with pagination

May 8, 2022
a react usePagination() hook
a react usePagination() hook

Pagination in Javascript and React, with a custom usePagination() hook

Jun 8, 2022
React components for sorting, filtering and pagination of data.

react-data-components DataTable: Live demo and source SelectableTable: Live demo and source Getting started npm install react-data-components --save T

Apr 8, 2022
Simple pagination for React (MIT)

react-pagify - Simple pagination for React react-pagify provides a simple API for building your own custom paginator. If you want to learn more about

Jun 5, 2022
React.js pagination component based on ultimate-pagination
React.js pagination component based on ultimate-pagination

react-ultimate-pagination React.js pagination component based on ultimate-pagination. It's implemented as a higher-order component that allows easy in

Jun 4, 2022
react pagination component, simple use
react pagination component, simple use

React-pagination Preview: https://killsanghyuck.github.io/react-pagination/ Install npm install react-pagination-component Configuration totalPage :

Mar 18, 2022
React Paginations component
React Paginations component

react-paginations React Paginations Demo: https://trendmicro-frontend.github.io/react-paginations Installation Install the latest version of react and

May 14, 2019
React - Pagination Example with logic like Google

react-pagination-example React - Pagination Example with Logic like Google To see a demo and further details go to http://jasonwatmore.com/post/2017/0

Jun 7, 2022
simple library for pagination in react

IMPORTANT NOTE This repository is DEPRECATED. Please use react-pagination-js instead which has more added feature and is tested well. React-pagination

Jan 24, 2020
React Pagination Component.

React Pagination Component.

Jun 18, 2022
React Pagination using Hooks example

React Pagination using Hooks example Set port .env PORT=8081 Project setup In the project directory, you can run: npm install # or yarn install or C

Apr 20, 2022
React Pagination Bar
React Pagination Bar

React Pagination Bar Lightweight component for pagination of application pages on react Features Customizing class names without using style overrides

Jan 26, 2022
馃Л Declarative, asynchronous routing for React.
馃Л Declarative, asynchronous routing for React.

Navi Declarative, asynchronous routing for React. Navi is a JavaScript library for declaratively mapping URLs to asynchronous content. It comes with:

Jun 17, 2022
Declarative routing for React

React Router Declarative routing for React Docs View the docs here Migrating from 2.x/3.x? 3.x docs 2.x docs Packages This repository is a monorepo th

Jun 26, 2022
Declarative routing for React

React Router Declarative routing for React Docs View the docs here Migrating from 2.x/3.x? 3.x docs 2.x docs Packages This repository is a monorepo th

Jun 18, 2022
Declarative routing for React

React Router Declarative routing for React Docs View the docs here Migrating from 2.x/3.x? 3.x docs 2.x docs Packages This repository is a monorepo th

Jun 24, 2022
Declarative routing for React

Welcome to React Router 路 React Router is a lightweight, fully-featured routing library for the React JavaScript library. React Router runs everywhere

Jun 22, 2022
Declarative routing for React

Welcome to React Router 路 React Router is a lightweight, fully-featured routing library for the React JavaScript library. React Router runs everywhere

Jun 24, 2022