I understood that routing libraries for SPAs like https://github.com/ReactTraining/react-router help to parse the URL and put the app into a corresponding state of a state machine.
Is there more to routing than this?
Why is routing needed in the first place?
Why are URLs important? For example in a desktop app there are no URLs, so what's the big deal about them in a web app?
I also have this problem: "Why do we need routing?". You can write apps without routing at all. The code can get messy but still, it is not impossible.
My biggest reason for having routing is because if the user hits the Back button of the browser (Forward button as well, for that matter), he will not be navigating within the app. The user might expect to navigate within the app using the history of the different "pages" he loaded previously. Instead, he will be thrown out of the web app. Hitting the Refresh button would also throw him to the root of the app.
From the user's point of view, it is a regular web app (he doesn't need to know how it is designed: SPA or otherwise) and it should work as any web app/website should work. Routing ensures this, doesn't it?
This is a very good question, and one that I don't see discussed as often as I think it should be. The short answer is that often, in a Single Page Web Application, you don't need routing. If you are building an application which doesn't require its pages to be indexed by Google, and you either don't care, or don't want the user to be able to Bookmark pages, then there is no reason to implement routing.
In an SPA, routing adds additional complexity and effort, so if you can avoid doing it, you should. Of course, modern frameworks such as Angular and React provide facilities for making routing much easier, but even then some things can be hard to do with routing, for example animating between pages.
A good example of a web application where routing would be redundant would be a multi-page form which you want to control the user's passage through and possibly prevent them from returning to pages which have became inapplicable.
Implementing such a form with routes would be a nightmare as you would have to prevent the user from visiting certain pages in their history.
It's useful to ask yourself what a route actually is in a SPA. It's easy to think of it as just a 'web-page', but what it really is is a state, and when you navigate between routes what you are really doing is navigating between different states of the app. The fact that the appearance of the app may change between states is incidental to what is really going on. So what a route does is give the user a means of returning to particular states of the app.
You should only implement a route in an SPA when there is a state of the app which you want the user to be able to return to.
An alternative, and perhaps more useful way of doing this, would be to implement Undo and Redo mechanisms.
Of course, even when you don't have routes you still have to care about what happens when the user clicks the History Back button, but then you simply have a modal alert which warns them that they are about to leave the app should they proceed with the navigation.
In desktop applications you have buttons and other controls to get what you want. So routing in UI apps would be the set of all UI controls.
In web apps on the other hand, all functionality is accessed via some text which is the links and the parameters.
A URL is the path to access a functionality. Routing is like the mechanism to decide which functionality to call based on the provided URL and params.
So basically routing is a mapping between an URL and the functionality of a web server.
Routing in SPAs is used to load certain parts of the web app e.g. yourappurl.com/profile/userid/ will load the profile part of an SPA with the right user profile corresponding to the userid. This can be seen in the GitHub example you provided:
<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>
SPA refers to the fact that in general you have an index.html as your "main view" and then depending on the routing you add/remove certain parts from the index.html with frameworks like React or AngularJS etc.
I have the same question from time to time.
I would like to say router in SPA is a component hierarchy helper.
As #tech4242 pointed out, we don't have an something like segue in iOS. So what should we use to help users navigate if we don't use router? We are talking about SPA here. So we can manage this in store or state. Yes, that's feasible but not preferable.
Try to think this from the perspective of using a component-oriented library (either React or Vue). Using router help us use a certain component for a specific route. When users move back and forth between different route, we are relying on the route to tell what component to display. We simply couple a component with a specific route, which makes our root component (normally called App) clear, maintainable and readable. Without router, either the root component or state would be messy and hard to maintain.
Related
I'm writing React app inside a non-React app, and I have no control over the relative route of my app (for example could be foo.com/bar/my-react-app). So the requirement is matching routes against the end of the URL(this is safe because the React js files are being loaded only when the user navigates to the route of my react app, so no collisions).
based on my check, the path check of Route in router-router v6 is not flexible or configurable, but in my case i need a custom check, with the end of the string's route.
for example one of the next checks would do the trick:
prefix is not possible
<Route path="*/admin" element={<UserApp />} />
custom function is not possible either
<Route path={(route)=>route.endsWith("admin")} element={<UserApp />} />
I started looking at the source code and they using primarily <string>.startsWith and do not expose many customization options, so I came here to you experts before wasting a few hours trying to recreate the path match behavior with the low level components.
by the way BrowserRouter basename attribute does not help me either because i have no guarantee of the URL+route my app would be installed, so the check must rely on the end of the location string.
so, there is an easy way to make a route with custom path validation?
For anyone who encountered in my case - v6 is much less flexible as it does not support path-to-regexp path matches nor custom render method for Route... so Route path="*/admin" would just work out of the box in v5
they should have left it in the API in my opinion. migrating back to v5 was trivial for my case and solved the issue.
I am new to react and I haven't cleared all things in my mind yet.
I am currently working on a project where I need to build a react app with a landing page, a sign up/in page, an ask-a-question page and a answer-question page. Something like a stack overflow clone.
To my knowledge so far I get that I have two choices. 1) use react-router and have a function rendering what I want for each page or 2) have a state like showPage and with some if/else if render the page I want.
What is the correct way to do what I want? And in general when should I use react-router and when just state.
Thanks in advance
You'll always use routing if you have multiple pages to render. As you said you have 3 pages currently you'll need to work on.
Landing page
Sing in/ register
FAQ
What you'll want to do is wrap everything inside your app.js in Router and have say a pages folder that'll have all the pages you want to render.
In React, routers help create and navigate between the different URLs
that make up your web application. They allow your user to move
between the components of your app while preserving user state, and
can provide unique URLs for these components to make them more
shareable. With routers, you can improve your app’s user experience by
simplifying site navigation.
Read more here
You need to separate all this because when your project grows you'll thank yourself for creating specific file for specific workload. It'll be easier to manage. And when you're working on large scale projects you'd want to create layouts and have even bigger distributions.
layouts
|__admin_layout.js
|__user_layout.js
here admin layout will handle all routes specific to admin and user layout will handle all routes specific to users.
Routing helps you manage your pages much better
I need to render a page for base url in react. I defined base url as,
<Router basename="/baseUrl">
<Switch>
<Route path={"/childUrl"}
</Switch>
</Router>
I am able to render page via /baseUrl/childUrl. When accessing, /baseUrl it redirects to /baseUrl/childUrl. How can I set a different page to /baseUrl
I know this is old, but in case anyone else stumbles upon this I would recommend using redux-first-router. It lets you dispatch actions either by changing the url in your browser, or the regular react way. This lets you control how components are rendered and keep the state of your application in sync with the url, without having multiple sources of truth.
Michael Sargent did a brilliant explanation, which can be found here.
And of course, you can also check out the git repo.
I couldn't understand the theoretical part of choosing routes. There are many examples out there which implements routes like /authentication /user:id but how can we decide which routes we need in our application. I am not able to distinguish do I have to use route for something or not.
"how can we decide which routes we need in our application"
Routes are entry points into your application. Anything the user types in manually in the address bar, copy-pastes from somewhere, clicks on a link in an email, etc. can be an entry point.
So whenever you have an entry point (page loading for the first time) that is NOT simply the default route or default page loading behavior, you need a new route.
For single page apps, this usually boils down to looking at the URL with JS code at runtime and deciding which view/component to render. Most projects rely on libraries like react-router to formalize and automate this functionality.
A lot of us will be familiar with the enterprise web applications that are the be all and end all of the business data. They are usually a collection of various modules behind a login authentication and role based authorization. Instead of the user login in to various smaller application they login once and have a dashboard/menu of what they have access to.
The user login
Their roles are retrieved and stored in session
Application load with a large menu populated according to their roles (CRM, CMS, no admin panel, etc.)
We have been thinking of how we could leverage some of the newer frameworks out there (Angular, React, Vue) or if we should at all for these kind of applications.
I am a struggling when it come to state management. I understand the idea of managing the state using something like Redux with React for smaller components but if various part of a larger application are completely unrelated to each other I am left wondering how complex and how large this state might get to be?
Using React as an example my root component after login might be (I am not sure as I am not extremely familiar with React yet).
const Root = () => {
return (
<div className="container">
<Router history={browserHistory}>
<Route path="/" component={dashboard}/>
<Route path="/crm" component={crm}/>
<Route path="/cms" component={cms}/>
<Route path="/module1" component={module1}/>
...
<Route path="/moduleN" component={moduleN}/>
</Router>
</div>
)
}
ReactDOM.render(<Root />, document.getElementById('root'));
Is this the better approach even if the multiple routes have nothing in common (the cms doesn't care about the crm) that they should all share the state or would actually reloading the page and going to different smaller more focused single page applications be preferred?
For example, using traditional server side logic to present the menu going to different html file for each modules.
What you are referring to is called lazy loading, that will break down your routes in different JS files and only load them on requests. You can refer to this link on how to use lazy loading in vue.js
https://router.vuejs.org/en/advanced/lazy-loading.html
Here is a way in React (does not seem to be native, correct me if I am wrong)
Dynamic loading of react components