Display only one component with React Router - javascript

i'm creating a simple movie app with React along with the movie rest api from TMDB. My Home page is welcoming the users showing the most popular movies trending nowadays. Now i would like to insert on the navbar a link to open another page that will show all the categories. I'm new to React Router so i might have doing it wrong, but when i try to redirect to the "category" component, the component will show on the same page without hiding the home page. That's the code:
<Router>
<Container maxWidth="xl">
<SearchAppBar handleChange={handleChange} query={query} />
<TitlebarGridList movies={movies} />
<Typography
component="div"
style={{ backgroundColor: "white", height: "100vh" }}
/>
</Container>
<Switch>
<Route exact path="/categories">
<Category />
</Route>
</Switch>
</Router>
If i type on the browser /category, the category component will showe behind the App homepage. How can i show only that one i want?
Thank you

try also to wrap the container with a route having / as path :
<Router>
<Switch>
<Route exact path="/">
<Container maxWidth="xl">
<SearchAppBar handleChange={handleChange} query={query} />
<TitlebarGridList movies={movies} />
<Typography
component="div"
style={{ backgroundColor: "white", height: "100vh" }}
/>
</Container>
</Route>
<Route exact path="/categories">
<Category />
</Route>
</Switch>
</Router>

Related

Nested Routing not working in react-router version 6 [duplicate]

I was refactoring my React app after updating React Router to v6 and I got rid of the error I was getting in my routes, except now the desired layout is broken.
I need to include a permanent toolbar and a sidebar to be visible only in some pages. I tried to follow the docs but now the layout component is placed above all the pages it should be wrapping, not just overlapping them, but actually concealing them behind it.
The Layout component:
function Layout({ children }) {
return (
<div className="layout">
<Header />
<SidePanel />
<div className="main" style={{ marginTop: "100px" }}>
{children}
</div>
</div>
);
}
export default Layout;
The AppRouter component:
function AppRouter() {
return (
<Router>
<Routes>
<Route path="/" exact element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/sign-up" element={<SignUp />} />
<Route element={<Layout />}>
<Route path="/diary" element={<Diary />} />
<Route path="/results" element={<Results />} />
<Route path="/details" element={<Details />} />
<Route path="/about" element={<About />} />
</Route>
</Routes>
</Router>
);
}
export default AppRouter;
Layout should render an Outlet for the children Routes to be rendered into.
import { Outlet } from 'react-router-dom';
function Layout() {
return (
<div className="layout">
<Header />
<SidePanel />
<div className="main" style={{ marginTop: "100px" }}>
<Outlet />
</div>
</div>
);
}
Outlet
An <Outlet> should be used in parent route elements to render their
child route elements. This allows nested UI to show up when child
routes are rendered.

Using material ui tabs with react router?

I have a project in react/typescript. I have a react router that looks like this
const Root = () => (
<>
<NavBar/>
<Router>
<Route path="/" component={Home} />
<Route path="/timer" component={TimerPage} />
</Router>
</>
);
And I have a material-ui appbar that looks like this
export default function NavBar() {
return (
<div>
<AppBar position="static">
<Tabs>
<Tab label="Timer" to="/timer" component={TimerPage} />
</Tabs>
</AppBar>
</div>
);
}
There are a few issues - first the 'to' in Tab doesn't compile. Secondly, how do I make these two components work together, given they do very similar things?
If you are trying to navigate to another page, wrap your tab component, let react-router handle with the navigation and navigate using react-router history,
<Tabs value={value} onChange={handleChange} aria-label="simple tabs
example">
<div onClick={() => history.push("/timer")}>
<Tab label="Timer" />
</div>
</Tabs>
<Router>
<Route path="/" component={Home} />
<Route path="/timer" component={TimerPage} />
</Router>
Route should be inside Switch. Also, if you write path="/" this means that whatever page you will visit will still go to "home" page. This is because react-router does something like "least" checking of routes. So, if you had defined path "/images", before "/images/1", both will route you to "/images". Instead you could change the order of these paths, or add exact keyword before the first one.
Take a look at example below.
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/timer" component={TimerPage} />
</Switch>
</Router>
or
<Router>
<Switch>
<Route path="/timer" component={TimerPage} />
<Route path="/" component={Home} />
</Switch>
</Router>
As for your second issue, you should put your AppBar (or div or any container) inside Router and assign Link to component property of Tab:
<Router>
<AppBar position="static">
<Tabs>
<Tab label="Timer" to="/timer" component={Link} />
</Tabs>
</AppBar>
</Router>
Keep in mind that Link component is imported from react-router and not from #mui.

react router dom v5 not rendering children

I tried a lot of tricks seen on the internet and on the official documentation of react router dom, like for example with or without "exact", other types of syntax but none of them allowed me to solve this mystery.
But, the question is why the second router does not display its components?
//index.js
ReactDOM.render(
<Provider
store={createStoreWithMiddleware(
reducers,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()
)}
>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
document.getElementById('root')
);
Main router from app.js, work perfectly.
//app.js
<Router>
<TransitionGroup>
<Switch location={location}>
<Route exact path="/" render={() => <HomeView handleClick={handleClick} />} />
[...]
<Route path="/Profil" render={() => <ProfilView />} />
</Switch>
</TransitionGroup>
</Router>
Profil page with a second router that not rendering components
<Row>
<Col xs={2} className='justify-content-center'>
<GroupBouton />
</Col>
<Col xs={10} className=''>
<Switch location={location}>
//when I go to this page I see the route below
<Route exact path={path} render={() => <h3>Choose a movie from the list above </h3>} />
//But this route is not rendering till I actualise the page by pushing F5
<Route path={`${path}/Myprofil`} render={() => <Myprofil />} />
</Switch>
</Col>
</Row>

How to render component inside a component based on route

I have routes like this:
<Provider store={store}>
<BrowserRouter>
<Route path="/" component={App} />
<Route path="/customers" component={Customers} />
<Route path="/tickets" component={Tickets} />
</BrowserRouter>
</Provider>
When the route is /customers I want Customers component inside App component. When the route is /tickets I want Tickets inside App and not Customers. I could check the route using
this.props.location.pathname == '/customers' but that's what the Router is for, right? I shouldn't be checking the route and rendering.
Based on my routes above, I see Customers component below App and not inside it.
The App consists of header and stuff. I don't want to add header code to all my components.
App.js:
<Header style={{ height: '39px', lineHeight: '39px' }}>
<Link to="/home">
<div className="logo" style={{ float: 'left' }}>
<img src="" />
<h2>Appnam</h2>
</div>
</Link>
{navEl}
</Header>
<Content >
// Customer or Tickets component here based on route
</Content>
How do I render the components inside App based on the route.
Assuming you have App as the main component, and you want the Tickets and Customers components inside the App component, you can make use of nested routes
<Provider store={store}>
<BrowserRouter>
<Route path="/" component={App} />
</BrowserRouter>
</Provider>
Inside App component
class App extends React.Component {
render() {
return (
<div>
{/* rest of App code */}
<Route path="/customers" component={Customers} />
<Route path="/tickets" component={Tickets} />
</div>
)
}
}
make use of.
<Provider store={store}>
<BrowserRouter>
<Route exact path="/" component={App} />
<Route exact path="/customers" component={Customers} />
<Route exact path="/tickets" component={Tickets} />
</BrowserRouter>
that will work

useState reset after history push

We have a sidebar that uses history.push to navigate from one page to another in a SPA. When this happens context providers are preserved but the pages useState goes back to its default value. I looked at the code for Link and its not doing anything different then the history push.
We can rewrite to use Link but I read that history push should work and that is all Link is doing anyway. The code below uses route render but have tried with just the JSX like others also.
<Router history={history}>
<div className={classes.body}>
<div className={classes.root}>
<Drawer appConfig={appConfig} />
<div style={{ width: '100%', height: '100vh', overflow: 'hidden' }}>
<Switch>
<Route type="public" path="/dialogs" exact render={Markets} />
<Route type="public" path="/notifications" exact>
<Notifications />
</Route>
<Route type="public" path="/:marketId" exact>
<Market />
</Route>
<Route type="public" path="/:marketId/about" exact>
<About />
</Route>
<Route>
<PageNotFound />
</Route>
</Switch>
</div>
</div>
</div>
</Router>
function Markets(props) {
const { intl } = props;
const { marketDetails, loading } = useAsyncMarketContext();
const [addMode, setAddMode] = useState(false);
function toggleAdd() {
setAddMode(!addMode);
}
function onMarketSave() {
toggleAdd();
}
return (
<Activity
title={intl.formatMessage({ id: 'sidebarNavDialogs' })}
isLoading={loading}
titleButtons={<IconButton onClick={toggleAdd}><AddIcon /></IconButton>}
>
<div>
{!addMode && <MarketsList markets={marketDetails} /> }
{addMode && <MarketAdd onCancel={toggleAdd} onSave={onMarketSave} />}
</div>
</Activity>
);
}
The expectation is that if addMode is true it will retain its value when clicking to /notifications and back.

Categories

Resources