React Route and Switch is not working. The path renders nothing - javascript

I am new to react and I was trying to make routes but its not working properly.
Here is my code:
<div className = "music-box">
<Switch>
<Route exact path = "/">
<div id = "trending-container" className = "user-musics">
{musics && musics.map((name, i)=>{
return(
<Fragment key = {i}>
<MusicPreview
name = {name}
play = {play}
uID = {name.userID}
userName = {currentUserName}
pfp= {name.pfpURL}
user = {name.artist}
/>
</Fragment>
)
})}
</div>
</Route>
<Route exact path = {"/results"}>
<div className = "user-musics">
results
</div>
</Route>
</Switch>
</div>
Whenever I go to http://localhost:3000/results the page is blank and its not rendering anything.

You need to put Switch & Route inside BrowserRouter.
<div className="music-box">
<BrowserRouter>
<Switch>
<Route exact path="/">
<div id="trending-container" className="user-musics">
{musics &&
musics.map((name, i) => {
return (
<Fragment key={i}>
<MusicPreview
name={name}
play={play}
uID={name.userID}
userName={currentUserName}
pfp={name.pfpURL}
user={name.artist}
/>
</Fragment>
);
})}
</div>
</Route>
<Route exact path={'/results'}>
<div className="user-musics">results</div>
</Route>
</Switch>
</BrowserRouter>
</div>

Using jsx inside Route will work but it's better to create components and call them on Route like that: <Route exact path="/" component={Home} />
Here is a working codesandbox

Related

Matched leaf route at location "/" does not have an element. This means it will render an <Outlet /> with a null value, so resulting in an empty page

the return statement gives a warning and addTodo & todos dont load. Switch is not supported anymore so I've replaced it with Routes but don't know how handle that return part
Does anybody know how do I solve this issue?
return (
<>
<Router>
<Header title="To Do List" />
<Routes>
<Route exact path= "/" render={() => {
return (
<>
<AddTodo addTodo = {addTodo} />
<Todos todos = {todos} onDelete={onDelete} />
</>
)
}
}>
</Route>
<Route exact path = "/about" element = {<About/>} />
</Routes>
<Footer />
</Router>
</>
);
Click to view warnings screenshot

How to redirect user to a diferent path if token is expired

I'm making a simple site for a project, and i want to redirect player to a login page if the token is expired, but I'm not really sure how to do it properly, here's what I've tried, im using react-jwt to check the token
function App() {
return (
<div style={{display:'flex', flexDirection:'column', height:'100vh'}}>
<Navbar/>
<div style={{display:'flex', flex:1}}>
<Routes>
<Route path="/login" element ={<LoginForm/>} />
<Route path="/signUp" element ={<SignUpForm/>} />
<Route path="/addMovie" element= {<AddMovie/>} />
<Route path="/" element={isExpired(localStorage.getItem('token') ? <FilmList/> : <LoginForm/> )} />
<Route path="/details" exact element ={<MovieDetails/>} />
</Routes>
</div>
</div>
);
}
or something like
<Route path="/"
render={props=>{
if(isExpired(localStorage.getItem('token'))){
return <Navigate to='/login'/>;
}
return <FilmList/>
}}
/>
The first one just returns nothing, and the second one gives a warning in console:
Matched leaf route at location "/" does not have an element. This
means it will render an with a null value by default resulting in an
"empty" page.
Is there a way to make it work ?
In react-router-dom v6 gone are custom route components, and the Route component must have a valid ReactElement on the element prop. A function is incorrect. Your second snippet is close.
Create an AuthWrapper to conditionally render an Outlet for a nested route or a redirect.
const AuthWrapper = () => {
return isExpired(localStorage.getItem('token')
? <Navigate to="/login" replace />
: <Outlet />;
};
Wrap any routes you want to protect into a Route rendering the AuthWrapper.
function App() {
return (
<div style={{display:'flex', flexDirection:'column', height:'100vh'}}>
<Navbar />
<div style={{display:'flex', flex:1}}>
<Routes>
<Route path="/login" element={<LoginForm />} />
<Route path="/signUp" element={<SignUpForm />} />
<Route path="/addMovie" element={<AddMovie />} />
<Route element={<AuthWrapper />}>
<Route path="/" element={<FilmList />} />
</Route>
<Route path="/details" element={<MovieDetails />} />
</Routes>
</div>
</div>
);
}
One solution would be to use the Redirect component from react-router-dom.
Fo into your FilmList component and in the rendering part do the following check:
if (isExpired(localStorage.getItem('token')){
return <Redirect to='/login' />
}
before you return your 'normal' FilmList
FOR RRDv6 that doesn't support Redirect you can use the Navigate component:
if (isExpired(localStorage.getItem('token')){
return <Navigate to='/login' replace={true} />
}

Bind slug like the first URL segment

I'm developing react app use react-router-dom. I have unusual the app behavior. The app doesn't have home page. We can go to the app use 'slug'. For example: http://siteExample.net/my-subsite. If my-subsite exist in our database We need to work with this slug.
My code snippet for routes:
const App = ({ isAuth, onSetSlug, slug}) => {
useEffect(() => {
onSetSlug(window.location.pathname.split('/')[1])
}, [])
return (
<Router>
<div className="App">
<Suspense fallback={<Loading />}>
<MainModal />
<ScrollToTop>
{!isAuth ? (
<Switch>
<Route path={'/:slug'} exact component={lazy(() => import('./containers/notAuth/home'))} />
<ContentWrapper
container
component="main"
adaptSidebar={5}
adaptContent={7}
>
<Switch>
<Route path={'/:slug/login'} exact component={lazy( () => import('./containers/notAuth/login'))} />
<Route path={'/:slug/signup'} exact component={lazy(() => import('./containers/notAuth/signup'))} />
<Redirect to={'/:slug'} />
</Switch>
</ContentWrapper>
<Redirect to={'/:slug'} />
</Switch>
</ScrollToTop>
</Suspense>
</div>
</Router>
)}
There is a issue that :slug/login doesn't replace on my-subsite/login for example.By the way it's working only for my local machine. When I publish it to remote host it doesn't work completely.
Remove the exact prop on the outer/root route since it necessarily excludes matching any subroutes.
<Switch>
<Route
path={'/:slug'} // <-- want this path prefix to match
component={lazy(() => import('./containers/notAuth/home'))}
/>
<ContentWrapper
container
component="main"
adaptSidebar={5}
adaptContent={7}
>
<Switch>
<Route
path={'/:slug/login'}
exact
component={lazy( () => import('./containers/notAuth/login'))}
/>
<Route
path={'/:slug/signup'}
exact
component={lazy(() => import('./containers/notAuth/signup'))}
/>
<Redirect to={'/:slug'} />
</Switch>
</ContentWrapper>
<Redirect to={'/:slug'} />
</Switch>

React router not working on live production

I have built a UI amazon-clone with create-react-app
it only shows dummy data.
the problem is after publishing it to Vercel, the routing not working as expected! after clicking the links you see a blank page "URL params are correct", you have to manually reload the page to work!
also if you clicked a button no event trigger and you get a blank page!
I wrapped all my routes to MainRoute Component:
const MainRoute = withRouter(({ location }) => {
return (
<>
{location.pathname !== "/login" && location.pathname !== "/signup" ? (
<Header />
) : null}
<Switch>
<Route exact path="/" render={() => <Home />} />
<Route exact path="/products" render={() => <Products />} />
<Route
exact
path="/products/:productID"
render={() => <ProductPage />}
/>
<Route path="/checkout" render={() => <Checkout />} />
<Route path="/payment" render={() => <Payment />} />
<Route path="/login" render={() => <Login />} />
<Route path="/signup" render={() => <Signup />} />
<Route render={() => <NotFoundPage />} />
</Switch>
{location.pathname !== "/login" && location.pathname !== "/signup" ? (
<Footer />
) : null}
</>
);
});
export default withRouter(MainRoute);
my App Component:
function App() {
return (
<div className="app_wrapper">
<Router>
<MainRoute />
</Router>
</div>
);
}
export default App;
repo
https://github.com/aseelban/amazon-clone-app
link:
https://amazon-clone-app-llyl1tfcn.vercel.app/
it works correctly (under Brave browser) the authentication routes, could you please specify which route the issue occurs.!
Thanks, everyone for the help.
I solved this problem by removing HOC withStyles and instead use react-jss.

using Multiple header in react router

class App extends Component {
render() {
let pathName=window.location.pathname;
console.log('pathName==>',pathName);
let loginhideheaderpath = pathName==="/" || pathName==="/login";
let securnetheaderpath = pathName==='/Contentlanding/Reports';
let gallerypath = pathName==='/Contentlanding/Gallerylanding'
return (
<>
{ securnetheaderpath ? <Securnetheader /> : ( loginhideheaderpath) ? null :(gallerypath) ? <Galleryheading /> : <Header /> }
<Router history={history}>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/login" component={Login} />
<Route exact path="/Contentlanding" component={Contentlanding} />
<Route exact path="/Contentlanding/Birthdaylist" component={Birthdaylist} />
<Route exact path="/Contentlanding/Reports" component={Reports} />
<Route exact path="/Contentlanding/Gallerylanding" component={Gallerylanding} />
<Route component={Nodocumentfound} />
</Switch>
</Router>
</>
);
}
}
In my project i am using mutiple headers, i am rendering the header for components based on URL.
my condition is working fine. the problem is when i use the browser back button the header are not changing. any solution to fix this Thanks in advance.

Categories

Resources