Link doesn't work properly inside Modal / Component with React Router - reactjs

When I add a link inside of a bootstrap modal, the new page opens, but it doesnt open under the navbar, or above the footer, and it appears with a black transparent background (inherited from the modal component).
Ps: Navbar open pages perfectly.
<HashRouter>
<Navbar />
<Route exact path="/" component={Option}/>
<Route path="/finalizar3" render={ (props) => <Checkout1 shoppingCart={this.state.shoppingCart} } />
</HashRouter>
<Modal />
The component with the link:
<Link className="btn btn-primary" type="button" strict to="/finalizar1">Finalizar Compra</Link>
The modal is outside of HashRouter because I can access from any page I'd like. Therefore this modal is in the main page. Is there a workaround to make the link open the new page just like the navbar does?

It will work if you just put the Modal component inside of HashRouter, so that the Link component inside the modal will get the right history object from the context provided by the HashRouter.
<HashRouter>
<Navbar />
<Route exact path="/" component={Option} />
<Route
path="/finalizar3"
render={props => <Checkout1 shoppingCart={this.state.shoppingCart} />}
/>
<Modal />
</HashRouter>

Related

How add a link to an icon of another component not in app.js in React.js

I am working on a react project
In the App.js
I have all my imports and routers
Now I want to apply a router to an icon on the nav that routes to settings.
And I did that by creating another component for Settings, then I import the Settings to my App.js then link it to my icon route
So when I click it, it displays Settings.
Now the issue is
On that my settings page
I have lots of contents and icons
Now I want that if I click a
( General Settings icon ) it should display General Settings.
So how will I now add route to that icon.
My General Settings(page) is a different component. And not in the App.js page
You should use nested routes, Robin Wieruch has a good post about it: https://www.robinwieruch.de/react-router-nested-routes/
/index.js
root.render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="settings" element={<Settings />}>
<Route path="general-settings" element={<GeneralSettings />} />
</Route>
</Routes>
</BrowserRouter>
);
/App.js
...
<Link to="settings">Settings icon</Link>
/Settings.js
...
<Link to="general-settings">General settings icon</Link>
<Outlet />
You can do it as the same way as if it was in the app.js
App.js (react 18)
<Route path="/url/to/settings" element={<SettingsComponent/>} />
The Component where you 'have lots of contents and icons'
<Link to={/url/to/settings}>
<Icon />
</Link>

Jest Test React Router Link navigation

I have the following component that I want to test using Jest Enzyme.
<BrowserRouter>
<Switch>
<Route path='/' component={Home}/>
<Route path='/view' component={View}/>
</Switch>
</BrowserRouter>
class Home extends React.Component {
render {
<Link to='/view'>
<button onClick={() => foo}>View Data</button>
</Link>
}
}
This code is working in application correctly.
However, when I test button click using jest-enzyme, component path or content doesn't change
it('should redirect on button click', () => {
const component= mount(
<MemoryRouter initialEntries={{['/', '/view']}}>
<Route path='/' component={Home}/>
<Route path='/view' component={View}/>
</MemoryRouter>
)
expect(component.find('Home')).toHaveLength(1); //passes
expect(component.find('LinkAnchor').props().href).toEqual('/view'); //this also passes
component.find('button').simulate('click');
expect(component.find('View').toHaveLength(1); //This FAILS
});
My question:
Is only way to test Link could be checking href in it's internal a tag?
Can we test page navigation like it works properly for ?
In this case you probably want to test the history object of the MemoryRouter to be updated when you have clicked the link.
However, you are running into this problem because you're wrapping a button with a link and you are pressing the button not the link.
If you need button styling for your links, you should update the Link component instead:
return (
<Link to='/view' className='buttonClass' onClick={() => foo()} />
);

React: When navigating away from mounted component, show it again if click browser back button

Here is a part of my root component code:
const App = () => {
return (
<Switch>
<Route path="/products">
<AllProducts />
</Route>
<Route path="/teams">
<AllTeams />
</Route>
<Route exact path="/">
<Home />
</Route>
</Switch>
{isVisible && (
<Overlay />
)}
);
};
I have a Home component, from where I can navigate to other pages using a router. In Home component I have a button and when clicking on it, I set isVisible variable to true and <Overlay /> component is being opened as an overlay (similar to modal) and when it's open, the / pathname does not change, because it's outside router. There may be many links and I can navigate to other routes, for example /teams and also go much more deeper away from it. And the question is, if I hit the browser back button at some point, how to show this <Overlay />, like it were in the browser history?
Add it as a query param.
A query string is a part of a uniform resource locator (URL) that assigns values to specified parameters.

React router works only after refresh

I have problem with react router.
This is my Router:
<Router>
<div>
<Route exact path="/dashboard" component={projetList} />
<Route path="/dashboard/:id" component={
(props) => <Editor documentID={props.match.params.id} />
} />
</div>
</Router>
And Link to:
<Link to="/dashboard">
<button type="button" class="btn btn-outline-success">
</Link>
Problem description:
When I click my element - browser try to go to the http://localhost:3000/dashboard
but the site is blank.
When I refresh my site (F5 button) then my component load.
Also check out this link: Routes are not navigating when React v15.5 setup with react-redux v5 is. And make sure you put the in the right place. Check this for example :
<browserRouter>
https://pastebin.com/M9hU4Bg4

execute route change from siblings component in React Router V4

I am learning React.js. I am using React router version 4.3.1 and React router dom 4.3.1.
My current app structure is given below.
<React.Fragment>
{/* sidebar component */}
<SideBar store = {Mystore} />
<div className="main-panel">
{/* navbar component */}
<NavBar store = {Mystore}/>
{/* content component */}
<Content store = {Mystore}/>
{/* footer component */}
</div>
</React.Fragment>
in my content component i have a Router set up as given below.
<BrowserRouter>
<React.Fragment>
<Route exact path="/phoenix/public" component={Login} />
<ProtectedRoute exact path="/phoenix/public/sample" component={SamplePage} />
<ProtectedRoute exact path="/phoenix/public/view_ticket" component={ViewTicket} />
<ProtectedRoute exact path="/phoenix/public/create_ticket" component={CreateTicket} />
<ProtectedRoute exact path="/phoenix/public/dashboard" component={Dashborad} />
</React.Fragment>
</BrowserRouter>
Here ProtectedRoute is a functional component which checks if the user is authenticated and returns a Route
My sidebar has some a tags like below.
<li>
<a href="dashboard">
<i className="ti-panel" />
<p>Dashboard</p>
</a>
</li>
My goal is to navigate to different Routes without page refresh on click from side bar. But clicking href reloads the page and all my state in my Mobx refreshes. I have tried to Redirect but could not get the Router which is stated in siblings component (content is siblings of sidebar). I have no idea how to achieve this.
As stated in the comments on your question, regular <a> tags will not work, and refresh the page. So you will need to use Link or NavLink.
If you want to make it work in your sidebar (child component) you will need to wrap the <BrowserRouter> around all the components where you want to use the routes.
For example like this (using your code):
<BrowserRouter>
<React.Fragment>
{/* sidebar component */}
<SideBar store = {Mystore} />
<div className="main-panel">
{/* navbar component */}
<NavBar store = {Mystore}/>
{/* content component */}
<Content store = {Mystore}/>
{/* footer component */}
</div>
</React.Fragment>
</BrowserRouter>
And your Sidebar will be something like this:
<React.Fragment>
<Link to="/dashboard">Dashboard</Link>
...
</React.Fragment>
Then in your content component. You need to delete the <BrowserRouter>
I fixed my problem by having BrowserRouter like below as suggested by #PreDinnerSnack.
<BrowserRouter>
<React.Fragment>
{/* sidebar component */}
<SideBar store = {Mystore} />
<div className="main-panel">
{/* navbar component */}
<NavBar store = {Mystore}/>
{/* content component */}
<Content store = {Mystore}/>
{/* footer component */}
</div>
</React.Fragment>
</BrowserRouter>
Then i used Navlink in My Sidebar component. Which fixed the problem of navigating to the desired route without page refresh. But then i faced another problem as Content was not Refreshing according to the route.
For that problem I found the observer HOC of Mobx was interfering with my router. I had to wrap my content with withRouter as below to fix this problem.
withRouter(observer(Content));
I hope my solution will come in handy for someone as i found no tutorial with the examples of React Router implementation like mine on the web.

Resources