How to exclude a path from <Route> using react-router-dom? - react-router-dom

This code will render only when the path is "/"
<Route exact path={"/"} component={Header}/>?
But what would do the opposite? That is, what is the best way to render always EXCEPT for "/"? Is there an "else" equivalent?

I am just putting it here just not to let the question unanswered. This is actually the same as you proposed in the comment.
<Switch>
<Route exact path="/" />
<Route path="*" component={Header} />
</Switch>
Unfortunately I haven't found a better solution as you requested.

Related

react-router-dom NavLink sub-pages

I'm using NavLink menu items like this:
<NavLink to="/" exact >Dashboard</NavLink>
<NavLink to="/catalog" >Catalog</NavLink>
and it's working fine. My menu items are active as they should.
I would like that subpages from catalog also keep active class on catalog menu item. Subpages like:
/catalog/:id
/catalog/something/something-else
...etc
Is there a way to do that?
You can do somethink like this:
<Route path="/catalog">
<Route path=":subpage" element={<Element/>} />
</Route>

Routing in ReactJS

Can anyone explain to me how Routing works in Reactjs?
browserHistory.push('/location')
only updates the URL bar and doesn't redirect to it.
browserHistory.goBack()
works but only when the page has been visited before, hence the name.
Which makes it difficult for me to understand how browserHitory.goForward() works?
I have been trying to redirect to dashboard after a successful login. That's it.
From what I have read, React does not allow reloading a page. It will show a cannot GET /path error if we try to refresh the page or write the address in the url; unless the request is made on the server. I tried to create routes on server, but cannot get the syntax as to how I achieve it. I have only coded in Node to the extent of sending res.send() to the client app. How do I render that path? Because rendering to that path would mean that the Node's App.js has the view engine of the React app.
I don't know if it's clear enough, but any advice would be helpful.
Thanks.
first of all define all urls in router that is
You can watch these two videos for complete routing part1 part2
You forgot to add
use browserHistory.replace('/location')
another thing is that dont include / in child routes for example use like this <Route path='submissions' component={Submissions} />
export default ( <Router history={browserHistory}>
<Route component={App}>
<Route path='/' component={Home} />
<Route path='/submissions' component={Submissions} />
<Route path='/location' component={Location} />
<Route path='/login' component={Login} />
<Route path='/dashboard' component={Member} />
</Route> </Router> );
You're probably more generically wondering how single page applications routing works.
There are endless resources about this subject on the web.
This is a reactish article I have immensely appreciated: https://hackernoon.com/routing-in-react-the-uncomplicated-way-b2c5ffaee997
Index.js
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
Component BrowserRouter wraps the history object in the browser and passes it to down to component tree. Anywhere in the component tree we are able to use the history object. Then we need to register our routes in app.js.
app.js
import { Route, Redirect, Switch } from "react-router-dom";
class App extends Component {
render() {
return (
<div>
<NavBar />
<main className="container">
<Switch>
<Route path="/not-found" component={NotFound} />
<Route path="/register" component={RegisterForm} />
<Route path="/login" component={LoginForm} />
<Redirect from="/" exact to="/home" />
<Redirect to="/not-found" />
</Switch>
</main>
</div>
);
}
}
export default App;
If we did not use the "Switch", react would read "/" first and since that route is returning homepage, every route would return homepage too. For example,
<Route path="/register" component={RegisterForm} />
this would return "RegisterForm" and homepage. With using "Switch" we have to order our routers from most specific one to the most generic one. Means “/” should be in the bottom.
Now we have an issue. Every time we navigate from one page to another, we will have http requests from server. All of the components are part of the bundle and already downloaded when app loads so there is no need to reload them. Instead of reloading entire page with all assets, we should only update what we have in the content area. Solution is all the anchors should be replaced with “Link” from react-router-dom. Link component doesn't have “href” attr instead has “to”. Every time we click on links, “Link” has a click event. It will preventDefault(). So lets create a simple button with Link:
import { Link } from "react-router-dom";
<div className="col">
<Link to="/products/new" className="btn btn-primary my-2">
New Products
</Link>
</div>
In the beginning I said BrowserRouter wraps the history object in the browser and passes it to down to component tree. So we access it by "Route". When we registered our routes, "Route" automatically injects "History, Location, Match" props into the components. If you need to pass additional props to routed components; instead of component attribute we should use render attribute.
<Route path="/products" render={(props) => <Products sortBy= “newest” {...props} /> } />
Note that If we didnt pass “props”, History,Location and Match would disappear.
When user clicked on a button or submit a form, we wanna navigate it to a different page.
“History” object is responsible for navigation: go back, go forward, push and replace
PUSH: push method will add a new address in the browser history, so you click the back button and you go back to where you were.
REPLACE:replaces the current address, so we will not have history.
handleSave = ( ) => { this.props.history.push ("/products"); };
we can read route parameters and passed them to a component using the “match” object.
So we can render this info in our ProductDetails page as below.
<div>
<h2> productDetails-{this.props.match.params.id} </h2>
</div>
Query string parameters are in “location” object.

react-router server rendering without matched component's html content

I'm using react-router 1.0.0-rc3, and following this server rendering guide.
Here is the point part:
const html = renderToString(
<Provider store={store}>
<RoutingContext {...renderProps} />
</Provider>
);
Here is my route part:
<Route path="/" component={Container} >
<IndexRoute component={App} />
<Route path=":source/:owner/:name/:branch/tree/:corpus*" component={App} />
<Route path=":source/:owner/:name/:branch/ticket/(:ticket)" component={App} />
</Route>
I got html output as an empty div element like:
<div data-reactid=".whl3ehjj0g" data-react-checksum="12324050"></div>
There is no <App /> component rendered in the server, and the <App /> rendered normally after receiving server rendering response in the client, and all the routes funtions work well in the client.
So, anything I missed?
Ok, I figure it out, actually it's not related to react-router, it's cyclic dependencies in my code cause the problem. :(
My problem was doing require when I was doing export default in my component instead of module.exports. That fixed the issue for me!

AuthorizationRuleProvider rule and Domain group name with space in it

I have a domain group with space in it, it does not work. The only related thing I find on google is this unanswered question
http://webclientguidance.codeplex.com/discussions/9242
<rules>
<add name="User" expression="R:MyDomain\MyApp Users" />
</rules>
I am getting this exception :
Found token "end of file" when expecting word at position 17.
The solution was painful simple
<add name="User" expression="R:"MyDomain\MyApp Users"" />

Seam page navigation with includes

I'm using seam page navigation rules. and did not experience any problem with adding rules which redirect from one page to another.
But since I designed my page views using those redirection simply don't happen anymore for those pages.
Tried to define the rule to the view that gets included, then to the view that includes the others (which to me was making more sense) but none work.
Is there anything special about page navigation in seam using included view-id ?
main.xhtml:
<h:outputLabel value="Details:"/>`
<a4j:include viewId="contacts.xhtml" id="contactsDetails"/>`
<page view-id="/*" login-required="true">
<navigation>
<rule if="#{myBean.readyToSee}">
<redirect view-id="/see-contat.xhtml"/>
</rule>
</navigation>
</page>
I'm using jsf, xhtml as my page views.
Thanks
Its difficult for me to answer this question because I simply don't understand it. However I will try to guess what you are asking.
You have a page ie: /somePage.xhtml and inside that page you include some other pages.
I tend to write all my page navigation in pages.xml. I like having everything in one place, because it makes things cleaner and easier to maintain.
You can use wildcards also in the pages.xml file.
So you can do something like this.
<page login-required="true" view-id="/admin/*">
<restrict>#{s:hasRole('orgadmin') or s:hasRole('sysadmin')}</restrict>
<navigation from-action="#{userAdmin.editUser}">
<redirect view-id="/admin/create_user.xhtml" />
</navigation>
<navigation from-action="#{applicationProcessAdmin.saveScheme}">
<rule if-outcome="failure">
<redirect view-id="/admin/processes.xhtml" />
</rule>
</navigation>
</page>
In the above example, I am using a wildcard to say that all navigation that happens from /admin/* that uses some specific action, should redirect to some page i have.
You can also be very specific with the pages
<page login-required="true" view-id="/officer/admin/contacts.xhtml">
<begin-conversation join="true" />
<navigation from-action="#{officerAdmin.saveContact}">
<redirect/>
</navigation>
</page>
If this doesn't help you, you need to clarify your question better.
Update
Try changing your
<page view-id="/*" login-required="true">
<navigation>
<rule if="#{myBean.readyToSee}">
<redirect view-id="/see-contat.xhtml"/>
</rule>
</navigation>
</page>
To this instead
<page view-id="/*" login-required="true">
<navigation from-action="#{myBean.readyToSee}">
<rule if="#{myBean.readyToSee}">
<redirect view-id="/see-contat.xhtml"/>
</rule>
</navigation>
</page>
UPDATE 2
Does all your navigation fail? Or is it only some?
Try removing the /* on page view and replace with just *
If you do this will work:
#Name("myBean")
public class MyBean {
public String doSomething() {
return "success";
}
}
Now from your xhtml (Does not matter which include page it is from)
<!-- Depending on what button you are using, <h:form> is mandatory -->
<h:form>
<h:commandButton value="TEST" action="#{myBean.doSomething}" />
</h:form>
And in your pages xml
<page view-id="*">
<navigation from-action="#{myBean.doSomething}">
<rule if-outcome="success">
<redirect view-id="/test.xhtml" />
</rule>
</navigation>
</page>
The above will work. If it does not, the error is somewhere else in your code.

Resources