Giter Club home page Giter Club logo

rrouter's Introduction

rrouter

RRouter is a declarative routing layer for React applications.

The usage is as simple as:

var React = require('react')
var RRouter = require('rrouter')
var Route = RRouter.Route

var routes = (
  <Route>
    <Route path="/" view={MainPage} />
    <Route path="/about" view={AboutPage} />
  </Route>
)

RRouter.start(routes, function(view) {
  React.renderComponent(view, document.body)
})

See documentation for details.

rrouter's People

Contributors

andreypopp avatar mattatcha avatar pdehaan avatar simenbrekken avatar skratchdot avatar touchesir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rrouter's Issues

A more general promise method

00:46 <simenbrekken> Any chance routes could define a more general promise method? Some of my promises depend on each other.
00:47 <andreypopp> I thought of introducing some kind of synchroniser
00:47 <andreypopp> <Route sync ...> ... </Route>
00:48 <andreypopp> so that it waits for all promises to resolve before recursing
00:48 <simenbrekken> mine are sadly on the same level
00:48 <andreypopp> why not doing it inside a single function then?
00:48 <andreypopp> promiseX={getX}
00:49 <andreypopp> fuction getX() { return getDep().then(getXActually) }
00:49 <simenbrekken> I am but promiseX={getX} depends on props.Y being available
00:49 <simenbrekken> and I need both props

Error in doc: "data-fetching example"?

Hi
I dont know if its a typo or me who didn't get it but in the data-fetching example you have this routes

<Routes promiseItems={fetchItemsList} path="/items" view={Items}>
    <Route promiseItem={fetchItem} path="/items/:itemId" view={Item} />
 </Routes>

and then in nested routes:

<Route name="items" path="/items" view={Items}>
    <Route name="all" path="/all" view={AllItem}>
    <Route name="item" path="/:id" view={Item}>
</Route>

The first example should be a nested route? In this case "/items' is duplicate.
Or if its not a bug maybe you should change the first example to match the example in "Routing configuration" and "composing-routes" to be more consistent.

Also in "navigation example", there is no Routes (plural) tag only singular. Is it on purpose?

Extending Route

I have a large number of routes that I want to share a number of common props

e.g

I don't want to have to add "aProp='myProp'" to every single Route, so I tried

MyRoute = function(props) {
props.aProp='myProp';
return Route(props);
}

but that gives me errors. (length undefined etc)

Is there a nice way to achieve this?

Unclear error `no routes found in context`

I just go a Error: Invariant Violation: no routes found in context.
The error message is unclear (compared to React error messages :D )
Here is some of my code

/** @jsx React.DOM */

module React from "react"
module RRouter from "rrouter"

var Routes = RRouter.Routes
var Route = RRouter.Route

import {Fc} from "./fc"
var fc = React.renderComponent(
  <Fc />,
  document.querySelector(".fc-App")
)

import {FcHomePage} from "./fc/pages/homepage"
import {FcPageAbout} from "./fc/pages/about"

var routes = (
  <Routes>
    <Route name="main" path="/" view={FcHomePage} />
    <Route name="about" path="/about" view={FcPageAbout} />
  </Routes>
)

export default function startRouter() {
  RRouter.start(routes, function(view) {
    fc.updatePage(view)
  })
}

fc.updatePage is just a setProp
then I use

import router from "./components/router"
///...
router()

rrouter executable

Provide rrouter executable which can be used to prototype apps.

% rrouter --help

Usage: rrouter [options] <entry>

entry     Application entry point

Options:
   -v, --version   print version and exit
   --prerender     pre-render UI on server

Add a prop to Link when there are "active"

It would be nice to get something like an (dom) attribute or an additional class.
It will be really convenient to add some CSS for current active link.
Is this something relevant in the <Link> component ?

Configurable processing pipeline

Currently fetchDataDependencies is hardcoded. Instead we can make it optional and allow to configure processing pipeline:

var routes = (
  <Routes>
    ...
  </Routes>
).process(fetchDataDependencies).process(...)

This can make things more complex though...

Parent components and rendering to document

Re: #23

Using a setup similar to the above my app renders on the server using data dependencies. I get some weird issues on the client-side. In the browser the component is rendered like this:

RRouter.start(routes, function(view) {
  React.renderComponent(<App view={view} />, document);
});

And the server:

RRouter.route(routes, req.url).then(function(execute) {
  execute(function(view) {
    if (!view) {
      return next();
    }

    var app = App({view: view});
    res.end("<!doctype html>" + React.renderComponentToString(app));
  });
});

One of the routes:

function fetchData() {
  return APIRequest("data");
}

module.exports = (
  <Route>
    <Route
      path="/"
      view={Main}
      dataPromise={fetchData}
    />
  </Route>
);

It renders fine most of the time. Some times duplicate data is output in the Main component. But I'm always getting:

Error: Invariant Violation: You're trying to render a component to the document using server rendering but the checksum was invalid. This usually means you rendered a different component type or props on the client from the one on the server, or your render() methods are impure. React cannot handle this case due to cross-browser quirks by rendering at the document root. You should look for environment dependent code in your components and ensure the props are the same client and server side.

stacktrace

Doesn't seem to be a problem when view is rendered directly to document without the parent App component.

Can anyone explain this?

querystring support

I have a search route that uses query parameters, and uses a promise to fetch the search results.

If the path does not change, calling navigate will do nothing even if the query params have changed:

this.navigate('/search?' + encodedQuery)

Do you have plans to support query strings?

Parent components

I'm curious how this router is supposed to be used with components that should remain static apart from the routes.

I have a setup like this (pseudocode):

<App>
  <Navigation />
  {view}
  <maybe some other random elements>
</App>

I'm using this render function:

RRouter.HashRouting.start(routes, function(view) {
  React.renderComponent(<App view={view} />, document.body);
});

is this a bad way to do things? The problem I've realized is that I need <Navigation /> to be aware of URL parameters to highlight the current view, but only the view components are aware of these parameters as props.

Should I instead incorporate <Navigation /> into the all of the view components? Seems kind of redundant, but maybe that's the way it's supposed to be done?

Example for page-transition

Hi, I realise this package is still in heavy development but could give an example how to implement page-transition with this new router. Or give me some directions so I can try to do it by myself.

Thanks

Pass Routes props to children

Should a child route include props from it's parent?

var routes = (
  <Routes flux={flux}>
       // Should the 'login' route have the 'flux' prop?
      <Route name="login" view={LoginPage}/>
  </Routes>
);

Link doesn't work for me

I just got this error when adding my first <Link to="/">Main</Link>.
It seems trace returned by getScopedTrace() is undefined or not a string.

Any idea why ?

Possibly unhandled TypeError. trace is undefined
getPattern@http://localhost:2402/index.js:24736:19
makeHref@http://localhost:2402/index.js:24724:7
[182]</Link<.href@http://localhost:2402/index.js:24518:1
[75]</</ReactCompositeComponentMixin._bindAutoBindMethod/boundMethod@http://localhost:2402/index.js:13251:7
[182]</Link<.render@http://localhost:2402/index.js:24530:21
[75]</</ReactCompositeComponentMixin._renderValidatedComponent<@http://localhost:2402/index.js:13211:9
[106]</</ReactPerf.measure/<@http://localhost:2402/index.js:18609:9
[75]</</ReactCompositeComponentMixin.mountComponent<@http://localhost:2402/index.js:12764:1
[106]</</ReactPerf.measure/<@http://localhost:2402/index.js:18609:9
[103]</ReactMultiChild.Mixin.mountChildren@http://localhost:2402/index.js:18119:1
[80]</</ReactDOMComponent.Mixin._createContentMarkup@http://localhost:2402/index.js:13998:1
[80]</</ReactDOMComponent.Mixin.mountComponent<@http://localhost:2402/index.js:13918:1
[106]</</ReactPerf.measure/<@http://localhost:2402/index.js:18609:9
[75]</</ReactCompositeComponentMixin.mountComponent<@http://localhost:2402/index.js:12772:1
[106]</</ReactPerf.measure/<@http://localhost:2402/index.js:18609:9
[103]</ReactMultiChild.Mixin.mountChildren@http://localhost:2402/index.js:18119:1
[80]</</ReactDOMComponent.Mixin._createContentMarkup@http://localhost:2402/index.js:13998:1
[80]</</ReactDOMComponent.Mixin.mountComponent<@http://localhost:2402/index.js:13918:1
[106]</</ReactPerf.measure/<@http://localhost:2402/index.js:18609:9
[75]</</ReactCompositeComponentMixin.mountComponent<@http://localhost:2402/index.js:12772:1
[106]</</ReactPerf.measure/<@http://localhost:2402/index.js:18609:9
[73]</</ReactComponent.Mixin._mountComponentIntoNode@http://localhost:2402/index.js:11651:11
[131]</</Mixin.perform@http://localhost:2402/index.js:21486:7
[73]</</ReactComponent.Mixin.mountComponentIntoNode@http://localhost:2402/index.js:11633:1
[101]</</ReactMount._renderNewRootComponent<@http://localhost:2402/index.js:17477:1
[106]</</ReactPerf.measure/<@http://localhost:2402/index.js:18609:9
[101]</</ReactMount.renderComponent@http://localhost:2402/index.js:17527:1
[106]</</ReactPerf.measure/<@http://localhost:2402/index.js:18609:9
startRouter/<@http://localhost:2402/index.js:25458:5
[192]</Routing.prototype.onChange/</<@http://localhost:2402/index.js:25082:11
[76]</ReactContext.withContext@http://localhost:2402/index.js:13465:7
[192]</Routing.prototype.onChange/<@http://localhost:2402/index.js:25083:1
tryCatch1@http://localhost:2402/index.js:5352:9
Promise$_callHandler@http://localhost:2402/index.js:2746:9
Promise$_settlePromiseFromHandler@http://localhost:2402/index.js:2763:1
Promise$_settlePromiseAt@http://localhost:2402/index.js:2919:9
Promise$_settlePromises@http://localhost:2402/index.js:3057:9
Async$_consumeFunctionBuffer@http://localhost:2402/index.js:579:9
Async$consumeFunctionBuffer@http://localhost:2402/index.js:542:9
Promise$_Scheduler@http://localhost:2402/index.js:4591:17

Inconsistency for HashRouting with visible href & url in address bar

It's really nice to have this HashRouting thing.
But I've a small concern about the url we can have if we right click + new tab on the link
I've a route like this:

      <Route name="route-packages" path="packages" view={FcPackages}>
        <Route name="route-package" path=":package_id" view={FcPackage} />
      </Route>

#packages in the address bar, but not when hovering

Render view w/o waiting for data deps to resolve

This will allow to render a preloader while data deps are resolved.

Decide what to pass to views instead of unresolved yet props

  • null — good because make components unaware of where data comes from, that means data isn't there and that's all
  • promise — good because if promise can be tracked for progress we can render complex loading indicators with percents complete or progress bars
  • both — null as propName, promise as propNamePromise

Nested routes don't pass params

I have a link:

<Link
  to="/collections/collection/playlists/playlist"
  collection={this.props.collectionId}
  playlist={playlist.id}>
  View all
</Link>

With a routing configuration like this:

<Route name="collections" path="/collections"
       view={CollectionsIndex} dataPromise={$promise}>
  <Route name="collection" path=":collection" view={CollectionsShow}
         dataPromise={$promise}>
    <Route name="playlists" path="playlists">
      <Route name="playlist" path=":playlist" view={CollectionsPlayer}
             dataPromise={$promise} />
    </Route>
  </Route>
</Route>

When routed to /collections/collection/playlists/playlist the promise is only passed the playlist ID and not the collection ID. Is there a specific reason it works in this way? To make an API request I need collection and playlist IDs.

Greater Flexibility for Different Promise Implementations in Promise Props?

Currently, the makeTask method for fetching asynchronous data relies on a Bluebird-specific promise inspection method (Promise#isFulfilled) during processing of *Promise props. This prevents using thenables from other promise libraries as input, which severely hampers flexibility in environments such as the browser.

Perhaps rrouter could cast incoming promises to Bluebird promises in order to retain the introspection ability? Otherwise, is there any way the library may be adapted to not rely on any one promise implementation in particular on the client?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.