-
-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I don't understand how "Universal Router" is working #72
Comments
It doesn't handle the navigation part just routing. In order to watch for changes in URL you may want to use // history.js
import createBrowserHistory from 'history/createBrowserHistory';
export default createBrowserHistory();
// main.js
import history from './history';
function render(location) { ... }
history.listen(location => {
render(location);
});
render(history.location);
// Links
import history from './history';
function onClick(event) {
event.preventDefault();
history.push(event.currentTarget.attr('href'));
} |
Thanks, @koistya, but without this part "router" unuseful for me. And I don't know why you call this library a "router". |
It's by decoupling from the Still, I got a question @koistya about how this example that you gave above works together with React. Is it really a good approach to call |
@BernardoS,
Yes, it is normal to re-render the app on location change. React takes care about performant updates. See Design Principles of React.js. One more example: // router.js - isomorphic (universal) code
import UniversalRouter from 'universal-router'
import React from 'react'
export default new UniversalRouter([ // all your routes here
{ path: '/', action: () => <h1>Home</h1> },
{ path: '/users', action: () => <h1>Users</h1> },
{ path: '/user/:id', action: (ctx) => <h1>User #{ctx.params.id}</h1> }
]) // client.js - entry point for browser
import ReactDOM from 'react-dom'
import router from './router.js'
const container = document.getElementById('app')
async function render() {
const page = await router.resolve(location.pathname)
ReactDOM.render(page, container)
}
render() // run client-side application
// in case if you need single page application
window.addEventListener('click', event => {
if (event.target.tagName === 'A') {
event.preventDefault()
const anchor = event.target
const state = null
const title = anchor.textContent
const url = anchor.pathname + anchor.search + anchor.hash
history.pushState(state, title, url)
render()
}
}) // server.js - entry point for node.js server
import http from 'http'
import ReactDOMServer from 'react-dom/server'
const server = http.createServer(async (req, res) => {
const page = await router.resolve(req.url)
const html = ReactDOMServer.renderToString(page)
res.end(`<!doctype html><div id="app">${html}</div>`);
});
server.listen(3000); // run server-side application |
@frenzzy I don't see where in the Design Principles of React.js you're seeing that is a good practice to do that. Thanks for the other example but still, It seems that rendering the whole tree is a thing to be avoided in a React application. It apperently has the same performance as changing the state of the root component in the tree, and as you can see in multiple places and frameworks, such as Redux and Flux, the idea is to re-render the closer to the leaves in the tree as possible, that's why the normal practice in a I'd love to see a big complex example of this re-rendering the root of the application idea in practice to see if i'm not going to suffer performance issues |
The top-level element of any multi-page web application is the page. The only way to change a page is to replace it with a new one, which usually means changing the whole tree. The only case the whole tree update is not desirable when both pages contain the same elements. React cares about it under the hood by skipping DOM updates (React Only Updates What's Necessary). But in memory (in virtual-DOM) react will re-render the whole tree by default and there are some optimization techniques (Avoid Reconciliation). |
Still. Even if (React Only Updates What's Necessary) it also calls Saying with an example. If I had three routes like If I were only in You're basically suggesting that it's a good approach to call the whole process of validation of the whole tree to navigate through this routes. But this is an incremental case, where there's no reason to re-render I got you're saying is no big deal because it's not gonna cause a re-render in the DOM itself, but it will re-render the whole virtual-dom tree. Therefore, doesn't seem like a good approach if you have a big application, this re-render could be too costy. I know most of the routers do this, and that's the normal defacto way, but the new version of React Router has a little bit more elegant approach, where it only re-renders what has really changed. |
My mistake @frenzzy . I couldn't be more wrong when I said that
I've got a little puzzled with React Router V4 and decided to do the exact test that I proposed abose import React, {Component} from 'react'
import {Route, Link} from 'react-router-dom'
export default class App extends Component {
render () {
return (
<div>
<ul>
<li><Link to="/">Root</Link></li>
<li><Link to="/items">Items</Link></li>
<li><Link to="/items/123">Item 123</Link></li>
<li><Link to="/items/124">Item 124</Link></li>
</ul>
<Route path="/" component={Root}/>
</div>
)
}
}
class Root extends Component {
render () {
console.log('render Root')
return <div>
this is Root
<Route path="/items" component={Items}/>
</div>
}
}
class Items extends Component {
render () {
console.log('render Items')
return <div>
this is Items
<Route path="/items/:id" component={Item}/>
</div>
}
}
class Item extends Component {
render () {
console.log(`render Item with id ${this.props.match.params.id}`)
return <div>
this is Item {this.props.match.params.id}
</div>
}
} Ends up that the react-router v4 does the same proccess o re-rendering all the components that are connected, no matter if the changes are only in the |
Hello, guys!
Your router looks great on a slides and simple in docs. Actually, too simple.
It promos like 'isomorphic', but I can't find how to work with HTML5 History API and NodeJS http requests too. It seems this router can't capture nothing and I need to call function "resolve" manually each time the route is changed (on the server and on the client in different ways). So, could you explain which part of this router is "isomorphic" and why it's called "router", if it can't observe routing paths by itself?
Thanks!
--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/39745948-i-don-t-understand-how-universal-router-is-working?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F18115217&utm_medium=issues&utm_source=github).The text was updated successfully, but these errors were encountered: