react routing two cmponents - javascript

very new to react router. i know this code isn't written the cleanest but how come when i click the button (Link to='/question') it renders
and BUT also renders the button still. i tried
setting it into a new route but unfortunately still doesn't work.
also is this how you would structure a basic router that needs to
render two separate components? i see i can do render={} or component={}
but not really sure how to render more than one component with one
router---- wit those two questions considered i basically just want
this button to render a new page ('/question') that has two components on it--- AFIB and QFIB and nothing else (right now its rendering the button and the two new components in addition... here is the code:
<div class='qAndAContainer'>
<Router>
<Link to='/question'><button className="px-4 nextQuestion startButton py-2 bg-pink-600 text-white text-sm uppercase font-medium rounded hover:bg-pink-500 focus:outline-none" >Begin
</button>
</Link>
<Route path='/question' component={(props) => (
<QFIB {...props} />
)} />
<Route path='/question' component={(props) => (
<AFIB {...props} />
)} />
</Router>
</div>
)
}
export default StartTest

React Router's Route component is basically a glorified string-match for your browser's URL.
In this case, what you're presenting to React Router is three Routes with the same strings to match, so it shows them all!
This is actually useful, for example rendering the same navigation bar for /dashboard AND /dashboard/messages.
But in your case, you just want one route or the other. So for React Router to understand you just want one of many, you need to wrap your Routes with a Switch component. React Router will only render the first match it finds, from top to bottom. Try to order your Routes in a Switch from most specific (longest paths) to least to get the best results.
I don't really care for the render or children props of Route (although they have their purposes), I usually prefer composing just like normal components.
<Router>
<Switch>
// this will actually match /question123/asdf/kdkd?foo=bar as well...
<Route path="/question">
<QFIB />
<AFIB />
</Route>
// `exact` tells the Route is must be... exact
<Route path="/" exact>
<Link to="/question">Go to Questions</Link>
</Route>
</Switch>
</Router>

Related

Route from one component to another reactjs

I have my app like that
<Router>
<div className="App">
<Link to="/" style={{ textDecoration: "none" }}>
<header>Project Issues</header>
</Link>
<Switch>
<Route exact path="/">
<Issues />
</Route>
</Switch>
</div>
</Router>
Inside Issues component, I choose to render one of two components based on a window width condition, one of the two components is called TwoPagesLayout, in this component when the user clicks on some text, it should go to another component called IssueDetails.
Here's the part of the TwoPagesLayout component:
{issues.map((issue: any) => (
<div>
<Link to="/Details" style={{ textDecoration: "none" }}>
<p className="issue-title">{issue.title}</p>
</Link>
<hr></hr>
<Switch>
<Route exact path="/Details">
<IssueDetails issue={issue} />
</Route>
</Switch>
</div>
))}
The problem is when I click on the text, it goes to that url "http://localhost:3000/Details" but it appears as a blank white page, it doesn't render what is inside the page.
Hope I have made it clear, I am new to react so I think the question maybe sounds common.
<Route exact path="/">
<Issues />
</Route>
Since you've marked this as exact, once the url changes to /Details, it no longer matches, and so Issues unmounts. Since Issues unmounts, so too does its descendant IssueDetails. You probably want to do:
<Route path="/">
<Issues />
</Route>
The Issues component will only render on the "/" path. When the page is showing "/Details" the Issues component will not render, and that includes the nested Router.
For this reason (they’re confusing), I personally try to avoid nested routers, so I would suggest keeping all the Route components together unless you have a reason otherwise!

How to load a component from a button click in react?

I'm creating a simple react app. I need to load a component from a button click. When I click the edit button I need to load the edit component. I tried it using <Link>. But I can't understand how to give the relative path. It means it need to load it like http://localhost:3002/viewTicket/603c9a02a2ccd501f45f820e/edit. I need to load it from http://localhost:3002/viewTicket/603c9a02a2ccd501f45f820e. How can I give the relative path?
App.js
<Provider store={configureStore()}>
<BrowserRouter>
<div className="App">
<LayoutWrapper>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/viewTicket/:id" exact component={ViewTicket} />
<Route path="/viewTicket/:id/edit" exact component={EditTicket} />
</Switch>
</LayoutWrapper>
</div>
</BrowserRouter>
</Provider>
Ticket.js
<Link to="/viewTicket/:id/edit">
<Button size="lg" onClick={this.handleEdit}>
<Pencil />
Edit
</Button>
</Link>
But url lokks like this.
Is there any other way to do this?
You forgot to include the actual ID in the URL. You're just directing the user to this literal string that has ":id" in it:
<Link to="/viewTicket/:id/edit">
Whatever your ID values is (for demonstration let's assume it's in a variable called id), you'd use that to build your URL:
<Link to={`/viewTicket/${id}/edit`}>
As an aside, this is a very strange structure and will likely lead to confusion:
<Link to="/viewTicket/:id/edit">
<Button size="lg" onClick={this.handleEdit}>
Putting a button inside of a link means that you're trying to simultaneously do two different things. Should this.handleEdit be invoked? Or should the user be redirected by the link? It's best to invoke a single operation. If some logic needs to happen inside of this.handleEdit before redirecting the user, then remove the <Link> and manually redirect the user (likely using the useHistory hook) after performing that logic.

React-router-dom doesn't render routes defined after a custom component in switch

I was trying different ways of declaring routes in a modular way. I came across to a strange behaviour:
<Switch>
<Route path='/1' component={Route1} />
<ModuleLikeRoutes />
<Route path='/2' component={Route2} />
</Switch>
React router completely ignores /2 and doesn't render Route2. I couldn't find any reason why.
I know I can import a 'module' component like
<Route path='/module' component={ModuleComponent} />
and probably it's the better way to do it. But I'm just curios how/why it ignores the routes after a custom component. Why I cant render Route2 in the example?
Here is a working fiddle https://jsfiddle.net/o4dtrpag/
A Switch will render only one of its children. If the path doesn't match /1 it will check the second one which is ModuleLikeRoutes, and that will be rendered every time, effectively making all components after it meaningless.
I am not sure if it is a bug or a not-supported feature by the library. However, the below code works by order the ModuleLikeRoutes to the last position.
<Switch>
<Route path='/1' component={Route1} />
<Route path='/2' component={Route2} />
<ModuleLikeRoutes />
</Switch>

multi tabbed javascript application with URL support using ReactJS

I am designing a multi-tabbed or multi-paged javascript web application that allows the URL to change depending on which tab you selected.
The best example I have seen is done by Zendesk
By calling it multi-tabbed, am I describing it correctly?
The tabs can be closed or opened depending on what is clicked.
How to create something like this using ReactJS? If there is a good tutorial, I am also happy to read through it.
This can easily be done with react router. If you are not familiar with react router go to the react router github page and check out the tutorials and docs. Here's an example of what it may look like to get you going.
Routes
<Route path="/" component={Application}>
<IndexRoute component={Home}/>
<Route path="tabs" component={TabLayout}>
<Route path="1" component={Tab1} />
<Route path="2" component={Tab2} />
</Route>
<Route path="about" component={About}/>
<Route path="*" component={NotFound} isNotFound/>
</Route>
Tab Layout
/* This is the layout for your tabs. Using react router to link to different tabs.
When the route changes props.children will be updated to reflect the current
route. You can add active classes to your tabs. Reference the react-router docs to
see how to do that
*/
import {Link} from 'react-router';
const TabLayout = props => {
return (
<section className="tab-container">
<div className="tabs">
<Link to="/tabs/1">Tab 1</Link>
<Link to="/tabs/2">Tab 2</Link>
</div>
<div className="content">
{props.children}
</div>
</section>
);
};
Tab 1 and tab 2 look like this
// Tab1 and Tab2 are just react components. For simplicity I am just using
// a stateless component.
const Tab1 = props => {
return (
<h1>Tab 1</h1>
);
};

React Router Undefined Routes Handling

I've noticed a strange behavior in react-router.
I have my routes defined like so:
var routes = (
<Route name='app' path='/' handler={Master}>
<DefaultRoute handler={HomePage} />
{/* inject:route */}
<Route name='home' handler={HomePage} />
<Route name='issues' handler={IssuesPage} />
<Route name='security' handler={SecurityPage} />
<Route name='contactUs' handler={ContactUsPage} />
<Route name='docs' handler={DocsPage} />
{/* endinject */}
<Redirect from='/' to='/home' />
<NotFoundRoute handler={HomePage}/>
</Route>
);
Router.run(routes, function (Handler) {
React.render(<Handler />, document.body);
});
in our fork of https://github.com/shovon/generator-react-material-ui.
Clicking links in the LeftNav produces expected results.
Upon starting gulp, the redirect from / to /home works.
What seems weird and undesirable is when I type in something like http://localhost:3000/#/some-undefined-route.
As expected, the DefaultRoute handler takes over, and the home page content is visible. HOWEVER, the weird URL remains. What I would expect is for any undefined route to redirect to a pre-defined catch-all. For example, I want http://localhost:3000/#/some-undefined-route to automatically redirect to http://localhost:3000/#/home -- not just show that content.
We're trying to use a mixin with transitionTo() to achieve the desired effect, but I'm still wondering if anybody knows the "right" way to handle this. I also wonder if what I'm seeing is actually the intended react-router behavior. If I'm missing something, I'd love to be enlightened. Cheers!
Update
From taurose at react-router:
Have you tried
<Redirect from="*" to=".." />
when responding to https://github.com/rackt/react-router/issues/732.
What might help anybody else with a similar question is to be aware that you will have to provide a Redirect for each sub-route, as well.
Apparently, this set up is designed to allow more detailed route control and handling of things like 404s.
Initially, we suspected that might be the case, but I didn't understand how the splat ( from="*" ) works.
Maybe this will be useful to others.
Cheers.

Categories

Resources