React-Routes not rendering - javascript

here is my app.js
<Router>
<Header title="My Todos List" />
<Routes>
<Route path="/about" element={<About />} />
<Route path="/" render={() => {
return (
<>
<AddTodo addTodo={addTodo} />
<Todos todos={todos} onDelete={onDelete} />
</>)
}} />
</Routes>
<Footer />
</Router>
the render function is not rendering anything in my home page

You can use element like this
<Route path="/" elemen={
<>
<AddTodo addTodo={addTodo} />
<Todos todos={todos} onDelete={onDelete} />
</>
}
/>

you have to use children prop for render prop from RR V5+ - see the migration docs for ref
so change the Route as
<Route
path="/"
children={
<>
<AddTodo addTodo={addTodo} />
<Todos todos={todos} onDelete={onDelete} />
</>
}
/>;

Related

Nested routing react-router-dom v6 not working

I am new to React and I am following this project. But I am stuck on converting the nested routed in version6 of react-router-dom.
In V5 it is as follows:
App.js
return (
<div>
<Header />
<Switch>
<Route exact path='/' component={HomePage} />
<Route path='/shop' component={ShopPage} />
<Route exact path='/checkout' component={CheckoutPage} />
<Route
exact
path='/signin'
render={() =>
this.props.currentUser ? (
<Redirect to='/' />
) : (
<SignInAndSignUpPage />
)
}
/>
</Switch>
</div>
);
ShopPage
const ShopPage = ({ match }) => (
<div className='shop-page'>
<Route exact path={`${match.path}`} component={CollectionsOverview} />
<Route path={`${match.path}/:collectionId`} component={CollectionPage} />
</div>
);
I want to convert it in V6 and I had tried as follows:
My App.js
return (
<div >
<Header />
<Routes>
<Route path='/' element={<HomePage />} />
<Route path='/shop' element={<ShopPage />} />
<Route path='/checkout' element={<CheckoutPage />} />
<Route path='/signin' element={<>
{this.props.currentUser ?
<Navigate to="/" />
:
<SignInAndSignUpPage />
}
</>
}
/>
<Route path='/signin' element={this.props.user ? <Navigate to="/" /> : <SignInAndSignUpPage />} />
</Routes>
</div>
);
My Shopage
const ShopPage = () => {
let { pathname } = useLocation();
console.log(pathname);
return (
<div className='shop-page'>
<Routes>
<Route path={`${pathname}`} element={<CollectionsOverview />} />
<Route path={`${pathname}/:collectionId`} element={<CollectionItems />} />
</Routes>
</div>
)
};
In pathname console log I am getting /shop but the items are not showing.
How can acheive nested routing in v6?
It looks like CollectionsOverview is what is rendered exactly on "/shop". Nested routes operate a little different in v6 than they did in v5. You don't need to get the current path/url to build nested routes/links, you can just use relative routes.
Example:
const ShopPage = () => {
return (
<div className='shop-page'>
<Routes>
<Route path="/" element={<CollectionsOverview />} />
<Route path=":collectionId" element={<CollectionItems />} />
</Routes>
</div>
);
};
Optionally, you can can convert ShopPage into a layout route.
Example:
import { Outlet } from 'react-router-dom';
const ShopPage = () => (
<div className='shop-page'>
<Outlet />
</div>
);
App
return (
<div >
<Header />
<Routes>
<Route path='/' element={<HomePage />} />
<Route path='/shop' element={<ShopPage />}>
<Route index element={<CollectionsOverview />} />
<Route path=":collectionId" element={<CollectionItems />} />
</Route>
<Route path='/checkout' element={<CheckoutPage />} />
<Route
path='/signin'
element={this.props.currentUser
? <Navigate to="/" />
: <SignInAndSignUpPage />
}
/>
<Route
path='/signin'
element={this.props.user
? <Navigate to="/" />
: <SignInAndSignUpPage />
}
/>
</Routes>
</div>
);

How to go specific route without rendering some components in React?

I am using react-router-dom v6. I want my Login page to be rendered without the Sidebar and Topbar components. How to do it?
function App() {
return (
<Router>
<Container>
<Sidebar />
<Content>
<Topbar />
<MainContent>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<UserList />} />
<Route path="/users/:id" element={<User />} />
<Route path="/newUser" element={<NewUser />} />
<Route path="/products" element={<ProductList />} />
<Route path="/products/:id" element={<Product />} />
<Route path="/newProduct" element={<NewProduct />} />
<Route path="/login" element={<Login />} />
</Routes>
</MainContent>
</Content>
</Container>
</Router>
);
}
I don't want my login page to render inside the MainContent but taking the whole page without Sidebar and Topbar.
I tried moving the Routes upper and have the login route above the sidebar but there is an error Error: [Sidebar] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
Since SideBar and TopBar appear to be part of a "layout", and you want a different "layout" specifically for "/login" then I suggest abstracting the container components into layout components. Each layout container should render an Outlet for their respective nested routes.
const AppLayout = () => (
<Container>
<Sidebar />
<Content>
<Topbar />
<MainContent>
<Outlet />
</MainContent>
</Content>
</Container>
);
const LoginLayout = () => (
<Container>
<Content>
<MainContent>
<Outlet />
</MainContent>
</Content>
</Container>
);
...
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<AppLayout />}>
<Route index element={<Home />} />
<Route path="users" element={<UserList />} />
<Route path="users/:id" element={<User />} />
<Route path="newUser" element={<NewUser />} />
<Route path="products" element={<ProductList />} />
<Route path="products/:id" element={<Product />} />
<Route path="newProduct" element={<NewProduct />} />
</Route>
<Route path="/login" element={<LoginLayout />}>
<Route index element={<Login />} />
</Route>
</Routes>
</Router>
);
}
function App() {
return (
<Router>
<Container>
{
Login || <Sidebar />
}
<Content>
{
Login || <Topbar />
}
<MainContent>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<UserList />} />
<Route path="/users/:id" element={<User />} />
<Route path="/newUser" element={<NewUser />} />
<Route path="/products" element={<ProductList />} />
<Route path="/products/:id" element={<Product />} />
<Route path="/newProduct" element={<NewProduct />} />
<Route path="/login" element={<Login />} />
</Routes>
</MainContent>
</Content>
</Container>
</Router>
);
}
try conditional rendering. It works for me!

How to make "404 - Not Found" page/route with react-router?

How do I add 404 - Not Found page in React with React-Router?
Here's my attempt:
// routes.tsx
export const routes = [
{
path: '/students',
render: (props: any) => <List {...props} title={`Students`} />,
},
{
path: '/teachers',
render: (props: any) => <List {...props} title={`Teachers`} />,
},
]
// App.tsx
import { routes } from './routes'
function App() {
const routeComponents = routes.map(({ path, render }, key) => (
<Route exact path={path} render={render} key={key} />
))
return (
<ThemeProvider theme={theme}>
<CSSReset />
<Suspense fallback={<Loader />}>
<Router>
<Switch>
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
<Layout>{routeComponents}</Layout>
{/* <Route component={NotFound} /> */}
<Route path="*" component={NotFound} />
</Switch>
</Router>
</Suspense>
</ThemeProvider>
)
}
export default App
But I can't see my custom "404 - Not Found" page when I go to 'http://localhost:3000/nothing', but <Layout /> component.
What I am doing wrong?
Stack: TypeScript, React#v16.13.1, react-router-dom#v5.1.2
404 Page on react does not need to have a path as it needs to be a page rendered when roue is not found between the paths of the pages you already have. It should work this way:
<Switch>
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
{routeComponents()}
<Route component={NotFound} />
</Switch>
Left blank path="". It will render 404 page.
see -
<Route path="" component={PageNotFound} />
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
This can fix
https://stackoverflow.com/a/64651959/16361679
return (
<ThemeProvider theme={theme}>
<CSSReset />
<Suspense fallback={<Loader />}>
<Router>
<Switch>
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
<Layout>
<Switch>
{routeComponents}
<Route path="*" component={NotFound} />
<Switch>
</Layout>
</Switch>
</Router>
</Suspense>
</ThemeProvider>
)

React nested routing problem (cannot displayed the child component)

I am new to react development. And I want to implement the routing mechanism in my page.
For example, there's component contains routes with the <Home /> and <Login /> component.
function App() {
return (
<div className="App">
<Switch>
<Route exact path="/home">
<Home />
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</div>
);
}
The <Home /> component contains a <Navbar /> and a <Switch /> with two <Route />:
Home.js
function Home() {
return (
<div>
<Navbar />
<div>
<Switch>
<Route exact path={`/home`}>
<Menu />
</Route>
<Route path={`/home/temperature`}>
<div>temperature</div>
</Route>
</Switch>
</div>
</div>
)
}
However, I defined the <Link /> in the <Menu /> component as below:
function Menu() {
return (
<div>
<li>
<Link to={`/home/temperature`}>temperature child page</Link>
</li>
</div>
)
}
Originally, the page would displayed the <Home /> component with <Menu /> and <div> temperature </div>
I expected that when I clicked the link (<Link to={/home/temperature}>temperature child page</Link>) then it would replace the <Menu /> component with the only the <div>temperature</div> (Dispalyed the <Navbar/> and <div>temperature</div>, but it could not display anything.
How should I correct it?
Solution:
I finally figure out why I cannot get child component in my js script.
Firstly, I need to wrap the <Switch> with <Router> in <App> component.
Then, by reference this , I realized that I should not specify the exact in <Route path="/home"> to make sure that the nested route can work as well.
function App() {
return (
<div className="App">
<Router>
<div>
<Switch>
<Route path="/home">
<Home />
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</div>
</Router>
</div>
);
}
simple routing
<Router>
<Switch>
<Route path={"/home"} exact component={Home} />
</Switch>
</Router>
nested routing
<Router>
<Switch>
<Route path={"/home"} exact component={Home}
<Rout path={"/temperature"} exact component={Temperature} />
</Route>
</Switch>
</Router>
`

React router 4 how to nested routes /admin and /

I have problem with nested routing.
On the normal site I have other urls than on the / admin page and i have different design and html.
I prepared this sample routing but after the page refreshes, the page gets white without any error.
Can I ask for a consultation what did I do wrong?
APP COMPONENT
class App extends Component {
render() {
return (
<BrowserRouter>
<div className="container">
<Route exact path="/" render={(props) => (
<Page {...props} data={data} />
)} />
<Route exact path="/admin" render={(props) => (
<Admin {...props} data={data} />
)} />
</div>
</BrowserRouter>
);
}
}
PAGE COMPONENT
class Page extends React.Component {
render() {
return (
<BrowserRouter>
<div>
<Header />
<Route exact path="/" render={(props) => (
<Home {...props} videosJson={this.props.data} />
)} />
<Route path="/about" component={ About } />
<Route exact path="/video" render={(props) => (
<VideoGallery {...props} videosJson={this.props.data} />
)} />
<Route path="/video/:id" render={(props) => (
<VideoPage {...props} videosJson={this.props.data} />
)} />
<Route exact path="/photo" render={(props) => (
<PhotoGallery {...props} videosJson={this.props.data} />
)} />
<Route path="/photo/:id" render={(props) => (
<PhotoPage {...props} videosJson={this.props.data} />
)} />
<Route path="/contact" component={ Contact } />
<Footer />
</div>
</BrowserRouter>
)
}
}
ADMIN COMPONENT
class Admin extends React.Component {
render() {
return (
<BrowserRouter>
<div>
<Route exact path="/admin" render={(props) => (
<Dashboard {...props} />
)} />
</div>
</BrowserRouter>
)
}
}
Your React application which uses React-Router should only have one instance of a Router defined, as stated in the documentation:
The common low-level interface for all router components. Typically
apps will use one of the high-level routers instead
The error you are getting is because you are defining additional routers (in your case there are multiple instances of BrowserRouter) in your Page and Admin components.
Also some of your Routes are ambiguous e.g.
<Route exact path="/" render={(props) => (
<Page {...props} data={data} />
)} />
and:
<Route exact path="/" render={(props) => (
<Home {...props} videosJson={this.props.data} />
)} />
One Route says that root ('/') should navigate to the Page component, the other says that root should navigate to the Home component, hence there is a conflict. Make sure the routes are unique.
I change my approach to this situation but dont work. Url /admin load Header and Footer component although he should not and component Dashboard not load.
Any sugestion?
<BrowserRouter>
<div className="container">
<Page>
<Header />
<Route exact path="/" render={(props) => (
<Home {...props} videosJson={data} />
)} />
<Route path="/about" component={ About } />
<Route exact path="/video" render={(props) => (
<VideoGallery {...props} videosJson={data} />
)} />
<Route path="/video/:id" render={(props) => (
<VideoPage {...props} videosJson={data} />
)} />
<Route exact path="/photo" render={(props) => (
<PhotoGallery {...props} videosJson={data} />
)} />
<Route path="/photo/:id" render={(props) => (
<PhotoPage {...props} videosJson={data} />
)} />
<Route path="/contact" component={ Contact } />
<Footer />
</Page>
<Admin>
<Route exact path="/admin" render={(props) => (
<Dashboard />
)} />
</Admin>
</div>
</BrowserRouter>
Admin Component:
class Admin extends React.Component {
render() {
console.log("ADMIN:", this.props);
return (
<div className="row">
<h1>ADMIN</h1>
{this.props.children}
</div>
)
}
}
Page Component:
class Page extends React.Component {
render() {
console.log("PAGE:", this.props);
return (
<div>
{this.props.children}
</div>
)
}
}

Categories