Last active
November 25, 2020 20:55
-
-
Save tejacques/179144077a5e57adb9d6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* I'd like to have a router with semantics that work like this | |
* Pros: | |
* - Named routes | |
* - Type Safe routing (with TypeScript) | |
* - Links are not strings so refactoring/changing them is trivial | |
* - Relative links are possible | |
* | |
* Cons: | |
* - Verbose links | |
* - Relative links are weak, inconvenient, and long | |
* | |
*/ | |
import { Router, Route, Link } from 'router'; | |
import { url } from 'route/matcher'; | |
import About from './About'; | |
import Users from './Users'; | |
import User from './User'; | |
import UserPage from './UserPage'; | |
import NotFound from './NotFound'; | |
const AppRouter = Router({ browserHistory }, { | |
Index: Route('/', App, { | |
About: Route('about', About), | |
Users: Route('users', Users, { | |
User: Route<number>(url`/user/${ {userId: Number} }`, User, { | |
Page: Route<string>(url`/${ {page: String} }`, UserPage) | |
}) | |
}, | |
NotFound: Route('*', NotFound)) | |
} | |
}); | |
render(<AppRouter/>, document.getElementById('root')); | |
// Where Links look like this: | |
<Link to={AppRouter.Index.Users.User.link(userId)} />; | |
<Link to={AppRouter.Users.User.Page.link(userId, page)} />; | |
// Relative links -- THIS DOESN'T REALLY MAKE SENSE | |
route = this.context.route || this.props.route; | |
// From /users/id/page1 to /users/id/page2 | |
<Link to={route.link(page2) />; | |
// From /users/id to /users/id/page | |
<Link to={route.Page.link(page)} />; | |
// From /users/id/page to /users/id2 | |
<Link to={route.parent.User.link(id2)} />; | |
// From /users/id/page to /users/id2/page2 | |
<Link to={route.parent.User.Page.link(id2, page2)} />; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Pros: | |
* - Named routes | |
* - Type Safe routing (with TypeScript) | |
* - Links are not strings so refactoring/changing them is trivial | |
* | |
* Cons: | |
* - No declarative route hierarchy | |
* - Verbose | |
* - Relative linking difficult/impossible | |
*/ | |
import { Router, Route, Link } from 'router'; | |
import RouteFactory from 'route-factory'; | |
const IndexRoute = RouteFactory('/', App); | |
const AboutRoute = IndexRoute.addRoute('about', About); | |
const UsersRoute = IndexRoute.addRoute('users', Users); | |
const UserRoute = UsersRoute.addRoute<number>('/user/:userId', User); | |
const NoMatchRoute = IndexRoute.addRoute('*', NoMatch); | |
render(( | |
<Router history={browserHistory}> | |
<IndexRoute/> | |
</Router> | |
), document.getElementById('root')); | |
// Where Links look like this: | |
<Link to={UserRoute.link(userId)} />; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Pros: | |
* - Short natural links | |
* - Relative linking is possible | |
* | |
* Cons: | |
* - No Named routes | |
* - No Type Safe routing, everything is a string | |
* - Links are strings so refactoring/changing them is tedious | |
*/ | |
import { Router, Route, Link } from 'react-router'; | |
render(( | |
<Router history={browserHistory}> | |
<Route path="/" component={App}> | |
<Route path="about" component={About}/> | |
<Route path="users" component={Users}> | |
<Route path="/user/:userId" component={User}/> | |
</Route> | |
<Route path="*" component={NoMatch}/> | |
</Route> | |
</Router> | |
), document.getElementById('root')); | |
// Where Links look like this: | |
<Link to=`/users/user/${userId}` />; | |
// Relative links? (cannot be done yet) | |
// From /users/id/page1 to /users/id/page2 | |
<Link to=`../${page2}` />; | |
// From /users/id to /users/id/page | |
<Link to=`./${page}` />; | |
// From /users/id/page to /users/id2 | |
<Link to=`../../${id2}` />; | |
// From /users/id/page to /users/id2/page2 | |
<Link to=`../../${id2}/${page2}` />; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default function RouteFactory = ({ path, component }) => { | |
const childRoutes = []; | |
const route = props => ( | |
<Route path={path} component={component}> | |
${childRoutes} | |
</Route> | |
); | |
route.addRoute = (p, component) => { | |
const childRoute = RouteFactory(path+p, component); | |
childRoutes.push(childRoute); | |
return childRoute; | |
} | |
pathArgRegex = /:[^\/A-Za-z]+/g; | |
route.link = (...args) => { | |
let index = 0; | |
const result = path.replace(pathArgRegex, function() { | |
return args[index++]; | |
}); | |
if (index !== args.length) throw Error("link doesn't have enough args"); | |
return result; | |
} | |
return route; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment