8

I'm trying to find an example of using react-router through the javascript API but have been unable to find anything so far.

My goal is to use react-router with reagent and clojurescript. So if anyone has gotten this working (even with Om), I'd appreciate a push in the right direction. Otherwise, just a straight javascript example without JSX would be helpful.

Edit 1 -- Getting closer to a solution

Thanks to @FakeRainBrigand for the help translating the JSX into plain JS.

Here is the React.js 0.11.2 version (which is what the current release of Reagent uses -- 0.4.3).

/** @jsx React.DOM */
Routes({location: "history"},
       Route({name: "app", path: "/", handler: App},
             Route({name: "inbox", handler: Inbox}),
             Route({name: "calendar", handler: "{Calendar}"})))

Hint: You can perform the JSX->JS transformation using JSXTransformer.js for your version of React. Just include it in your page and use your browser's developer console to execute JSXTransformer.transform('/** @jsx React.DOM */<Route location="history">...</Route>').code

Here is the Clojurescript version:

(ns mytest.core
  (:require [reagent.core :as reagent :refer [atom]])

(defn home []
  [:div [:h1 "Home Component Placeholder"]])

(defn info []
  [:div [:h1 "Info Component Placeholder"]])

(defn build-component [comp]
  (reagent/as-component (if (fn? comp) (comp) comp)))

(defn react-router []
  (js/ReactRouter.Routes #js {:location "history"}
                         (js/ReactRouter.Route #js {:name "app" :path "/" :handler (build-component home)}
                                               (js/ReactRouter.DefaultRoute #js {:handler (build-component home)})
                                               (js/ReactRouter.Route #js {:name "about" :path "/about" :handler (build-component info)}))))

Unfortunately, the components Reagent creates by default don't seem to be "standard" React components, in that React.isValidClass(myReagentComponent) === false. So all that is left is to figure out how to generate the components in the form that passes that test. I have a Stack Overflow question posted for that.

3 Answers 3

10

In 0.12 in JavaScript it looks like this:

var Router = require('react-router');
var Route = React.createFactory(Router.Route);
var DefaultRoute = React.createFactory(Router.DefaultRoute);
var NotFoundRoute = React.createFactory(Router.NotFoundRoute);

React.render((
  React.createElement(Router, {location: "history"}, 
    Route({path: "/", handler: App}, 
      DefaultRoute({handler: Home}), 
      Route({name: "about", handler: About}), 
      Route({name: "users", handler: Users}, 
        Route({name: "recent-users", path: "recent", handler: RecentUsers}), 
        Route({name: "user", path: "/user/:userId", handler: User}), 
        NotFoundRoute({handler: UserRouteNotFound})
      )
    ), 
    NotFoundRoute({handler: NotFound})
  )
), document.body);
Sign up to request clarification or add additional context in comments.

Comments

5

An example without JX and without using createElement (which doesn't make sense to me in case of routes):

// this snippet was tested with react 0.13.1 
// and react-router 0.13.2
import Router from 'react-router';
import App    from './components/App';
import Inbox  from './components/Inbox';

const AppRoute = Router.createRoute({
  path: '/',
  name: 'app',
  handler: App
});

const InboxRoute = Router.createRoute({
  name: 'inbox',
  handler: Inbox,
  parentRoute: AppRoute
});

// Important: you have to export the root route wrapped in array 
export default [AppRoute];

Comments

2

I've just finished putting together an experiment repository for doing this https://github.com/ghedamat/reagent-react-router

The main idea is using the new apis that Reagent provides since version 0.5.0-alpha3 for interop with React

reagent/reactify-component let's you use reagent components in React code (which is what the router requires)

and reagent/adapt-react-class enables the vice-versa.

What I'm attempting to do is wrap Components like Link and RouterHandler and use them directly in reagent.

i.e:

[:ul.nav.navbar-nav
  [:li
    [Link {:to "app"} "home"]]
  [:li
    [Link {:to "about"} "about page"]]]

Conversely you can pass Reagent's components as handlers to the ReactRouter.Router object.

(def routes
  (Route {:name "app" :path "/" :handler app-page}
    (Route {:name "about" :path "about" :handler about-page}))
  (DefaultRoute {:handler default-page-meta})))

The implementation is quite simple (and similar to your updated question): https://github.com/ghedamat/reagent-react-router/blob/master/src/cljs/reagent_react_router/react_router.cljs Look at the README for a more in-depth discussion.

It's working so far but could definitely use more inputs/help.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.