react-router-dom cannot render page [duplicate] - react-router-dom

I am building a Netflix clone application, and I am using react-router-dom v5 to switch between different pages. However, when I click the Link tag in Navbar.jsx, the URL changes, but the corresponding component doesn't render. I have consulted numerous StackOverflow posts on this topic, however, I can't get it to work. Below is the code. Please help me, as I'm stuck on this for 3 days 😥.
What it should show, when navigating to /series from /:
What it is actually showing:
index.js
import React from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
const container = document.getElementById("root");
const root = createRoot(container);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
App.jsx
import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import "./app.scss";
import Home from "./pages/home/Home";
import Watch from "./pages/watch/Watch";
const App = () => {
return (
<Router>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/movies">
<Home type="movies" />
</Route>
<Route path="/series">
<Home type="series" />
</Route>
<Route path="/watch">
<Watch />
</Route>
</Switch>
</Router>
);
};
export default App;
Home.jsx
import React from "react";
import Featured from "../../components/featured/Featured";
import Navbar from "../../components/navbar/Navbar";
import "./home.scss";
const Home = ({ type }) => {
return (
<div className="home">
<Navbar />
<Featured type={type} />
</div>
);
};
export default Home;
Navbar.jsx
import React, { useState } from "react";
import "./navbar.scss";
import { Link } from "react-router-dom";
const Navbar = () => {
const [isScrolled, setIsScrolled] = useState(false);
window.onscroll = () => {
setIsScrolled(window.scrollY === 0 ? false : true);
return () => window.onscroll == null;
};
return (
<div className={`navbar ${isScrolled ? "scrolled" : ""}`}>
<div className="container">
<img src="./netflix_logo.jpg"
alt="netflix logo"
/>
<Link to="/" className="link">
<span>Home</span>
</Link>
<Link to="/series" className="link">
<span>Series</span>
</Link>
<Link to="/movies" className="link">
<span>Movies</span>
</Link>
<Link to="" className="link">
<span>New and Popular</span>
</Link>
<Link to="" className="link">
<span>My List</span>
</Link>
</div>
</div>
);
};
export default Navbar;
Featured.jsx
import "./featured.scss";
import { IoMdPlay } from "react-icons/io";
import { FiInfo } from "react-icons/fi";
const Featured = ({ type }) => {
return (
<div className="featured">
{type && (
<div className="category">
<span style={{ color: "white" }}>
{type === "movies" ? "Movies" : "TV Series"}
</span>
<select name="genre" id="genre">
<option>Genre</option>
<option value="adventure">Adventure</option>
<option value="comedy">Comedy</option>
<option value="crime">Crime</option>
<option value="fantasy">Fantasy</option>
<option value="historical">Historical</option>
<option value="horror">Horror</option>
<option value="romance">Romance</option>
<option value="sci-fi">Sci-fi</option>
<option value="thriller">Thriller</option>
<option value="western">Western</option>
<option value="animation">Animation</option>
<option value="drama">Drama</option>
<option value="documentary">Documentary</option>
</select>
</div>
)}
<img
src="https://m.media-amazon.com/images/M/MV5BNzM4OTkzMjcxOF5BMl5BanBnXkFtZTgwMTkxMjI1MTI#._V1_.jpg"
alt="featured"
/>
<div className="info">
<img
src="https://occ-0-1432-1433.1.nflxso.net/dnm/api/v6/LmEnxtiAuzezXBjYXPuDgfZ4zZQ/AAAABUZdeG1DrMstq-YKHZ-dA-cx2uQN_YbCYx7RABDk0y7F8ZK6nzgCz4bp5qJVgMizPbVpIvXrd4xMBQAuNe0xmuW2WjoeGMDn1cFO.webp?r=df1"
alt=""
/>
<span className="desc">
When a beautiful stranger leads computer hacker Neo to a forbidding
underworld, he discovers the shocking truth - the life he knows is the
elaborate deception of an evil cyber-intelligence.
</span>
<div className="buttons">
<button className="play">
<IoMdPlay className="button-logo" />
<span>Play</span>
</button>
<button className="more">
<FiInfo className="button-logo" />
<span>More Info</span>
</button>
</div>
</div>
</div>
);
};
export default Featured;

There's a compatibility issue between pre-5.3.3 versions of react-router-dom#5 and react#18.
Github Issue #7870
PR #8831 merged to address issue - Fix was merged on May 18th, 2022, react-router-dom v5.3.3.
Solutions
Bugfix was merged into v5.3.3. Update to react-router-dom#5.3.3 or higher.
From the project's root directory run:
npm uninstall -S react-router-dom
npm install -S react-router-dom#5.3.3 (or #latest)
Revert back to React 17 (or React 17 syntax) and fix up the index.js file.
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(
<StrictMode>
<App />
</StrictMode>,
document.getElementById("root")
);
Make the React.StrictMode component a child/descendent of the router component. Comment.
Replace:
<React.StrictMode>
...
<BrowserRouter>
...
</BrowserRouter>
</React.StrictMode>
with:
<BrowserRouter>
<React.StrictMode>
...
</React.StrictMode>
</BrowserRouter>
Upgrade to react-router-dom#6 and fix up the routes.
const App = () => {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/movies" element={<Home type="movies" />} />
<Route path="/series" element={<Home type="series" />} />
<Route path="/watch" element={<Watch />} />
</Routes>
</Router>
);
}

First Solution and Best Solution:
If you use are using React Router 5.3.x, check whether it is 5.3.3 in your package.json file.
If it is not 5.3.3 uninstall the last version then install the bug-free version which has been resolved by John and updated in version 5.3.3.
npm uninstall -S react-router-dom
npm install -S react-router-dom#5.3.3
Second Solution:
React has launched its StrictMode in its latest update.
you can see it in an index.js file
index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
So here your React Router is in the child component. And we have to make it a parent component.
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<React.StrictMode>
<App />
</React.StrictMode>
</BrowserRouter>
);
Third Solution:
Remove the Strict mode from the index.js file
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);

Related

nothing is visible in router react [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 months ago.
Improve this question
the following code is not showing any content on the web screen/page
import './App.css';
import Navbar from "./components/Navbar.jsx";
import Tef from './components/Tef';
import About from './components/About';
import Home from './components/Home';
import {useState} from 'react';
import { BrowserRouter as Router ,Routes as Switch , Route ,Link}from "react-router-dom";
function Main() {
const [mode, setMode] = useState("Dark")
const [NavbarIDUS , setNavbarID] = useState("Heading-Nav_D")
const [divIDUS , setDivID] = useState("Nav-bg_D")
const [PIDUS , setPID] = useState("title_D")
const [CIDUS , setCID] = useState("contents_D")
const lightTheme = () =>
{
setMode("Dark")
setCID("contents_D")
setDivID("Nav-bg_D")
setNavbarID("heading-Nav_D")
setPID("title_D")
document.body.style.background = "#1E1E1E"
document.body.style.color = "white"
}
const darkTheme = () =>
{
setMode("Light")
setCID("contents")
setDivID("Nav-bg")
setNavbarID("heading-Nav")
setPID("title")
document.body.style.background = "#EEE"
document.body.style.color = "black"
}
//mode handler
const modeHandler = (event) =>
{
if(mode === "Dark")
{
darkTheme();
}
else
{
lightTheme();
}
}
//renderer
return(<>
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
{/* A <Switch> looks through its children <Route>s and
renders the first one that matches the current URL. */}
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
</> );
}
export default Main;
so WHAT can i do to make it work like it should
i was expecting to see some content on the screen but i give me a blank screen
i followed a website https://v5.reactrouter.com/web/guides/quick-start
but it was not working for me so what should i do???
You said you are using version 6, but you have <switch> in your code. That is version 5 syntax. Here is a React Router V6 example.
<BrowserRouter>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/About">About</Link>
</li>
<li>
<Link to="/Users">Users</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/About" element={<About />} />
<Route path="/Users" element={<Users />} />
</Routes>
</BrowserRouter>
Edit: Hooks can only be called inside the body of a function component" occurs for multiple reasons If you are getting an invalid hook error then this is not related to the react router if you have followed the V6 examples correctly. There are a few things that can be causing that issue. Invalid Hook Call Warning
Change
import {useState} from 'react';
To
import React, {useState} from 'react';

page does not redirect after setting token with localstorage

I am following the tutorial below to create a token system for my login application.
https://www.digitalocean.com/community/tutorials/how-to-add-login-authentication-to-react-applications
Here is my code:
App.js:
import logo from './logo.svg';
import './App.css';
import "bootstrap/dist/css/bootstrap.min.css";
import useToken from './components/useToken';
import Navbar from './components/Navbar';
import AudioDropzone from './components/AudioDropzone';
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useLocation
} from "react-router-dom";
import Upload from './pages/Upload';
import Manage from './pages/Manage';
import Menu from './pages/Menu';
import Admin from './pages/Admin';
import Login from './pages/Login';
import { useEffect, useState } from 'react';
<script src="https://unpkg.com/boxicons#latest/dist/boxicons.js"></script>
function App() {
const { token, setToken } = useToken();
console.log(token)
if(!token) {
return(
<div className="App">
<div className="row">
<div class="col-2">
</div>
<div class="col-9">
<Login setToken={setToken} />
</div>
</div>
</div>
);
}
return (
<div className="App">
<Router>
<head>
<link rel="stylesheet" href="boxicons.min.css" />
</head>
<div className="row" >
<div class="col-2">
</div>
<div class="col-9">
<Switch>
<Route path="/upload">
<Upload customer_id={token}/>
</Route>
<Route path="/manage">
<Manage customer_id={token} />
</Route>
<Route path="/menu">
<Menu customer_id={token} />
</Route>
<Route path="/admin">
<Admin />
</Route>
<Route path="/admin/upload">
<Upload />
</Route>
<Route path="/admin/manage">
<Manage />
</Route>
<Route path="/admin/menu">
<Menu />
</Route>
</Switch>
</div>
</div>
</Router>
</div>
);
}
export default App;
useToken.js:
import { useState } from 'react';
export default function useToken() {
const getToken = () => {
const tokenString = localStorage.getItem('token');
const userToken = JSON.parse(tokenString);
return userToken?.token
};
const [token, setToken] = useState(getToken());
const saveToken = userToken => {
localStorage.setItem('token', JSON.stringify(userToken));
setToken(userToken.token);
};
return {
setToken: saveToken,
token
}
}
Currently, when login is successful, it just clears the fields and shows the same login page again without showing the second version of App with all of my content. The issue is that the token value is not being updated and populated. I have verified that upon logging in token is updated to an integer value like 13.
This is seen when I log the value of userToken in useToken.js:
const saveToken = userToken => {
console.log(userToken) //returns 13
localStorage.setItem('token', JSON.stringify(userToken));
setToken(userToken.token);
};
Let me know what I am doing wrong!
I believe the bug is in the saveToken function.
setToken(userToken.token); should be setToken(userToken);
You don't need the .token because userToken is not an object. It is just an integer value.

How to redirect page after login in react.js

I am new to reactjs and trying to redirect the page after a user registers. Here is my App.js, which has a register input.
import React, { useState } from "react";
import './App.css';
import axios from 'axios';
function App() {
const [registerUsername, setRegisterUsername] = useState("");
const [registerPassword, setRegisterPassword] = useState("");
const [registerPasswordAgain, setRegisterPasswordAgain] = useState("");
const [registerEmail, setRegisterEmail] = useState("");
const register = () => {
axios({
method: "post",
data: {
registerUsername,
registerPassword,
registerPasswordAgain,
registerEmail
},
withCredentials: true,
url: "http://localhost:4000/register"
}).then((res) => console.log(res));
}
return (
<div className="App">
<div class = "topnav">
<a class="active" href="/register.html">Register </a>
<a class="active" href="/play.html">Play</a>
</div>
<div>
<h1>Register</h1>
<input placeholder ="Enter your username" onChange={e => setRegisterUsername(e.target.value)} />
<input type="password" placeholder ="Enter your password" onChange={e => setRegisterPassword(e.target.value)}/>
<input type="password" placeholder ="Enter your password again" onChange={e => setRegisterPasswordAgain(e.target.value)} />
<input placeholder ="Enter your email" onChange={e => setRegisterEmail(e.target.value)} />
<button onClick={register}>Submit</button>
</div>
</div>
);
}
this sends the registration username/password to my backend which is written in node.js. Assuming I send back a 200 OK status, or something that indicates that the user has registered, how can I redirect this page to another, lets say a login page? Do I need to create a class that extends component?
Just wondering where to go from here.
Thanks
use React-Router-dom
and in react we don't use anchor tag because react is SPA (Single page application), so use LINK tag
simple Example
index.js
import {BrowserRouter} from 'react-route-dom'
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
app.js
import {Switch,Rout,Link} from 'React-router-dom'
<div>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users"> {/add your redirect path/}
<Users /> {/Users components will render after the URL changes }
</Route>
<Route path="/" exact>
<Home />
</Route>
</Switch>
<Link to="/user">
<button>
Login
</button>
</Link>
</div>
using react-router-dome Redirect component you can redirect your page to abother page.
in your case you can store a boolean state and make it true when user suucessfully logged in.
import { Redirect } from "react-router-dom";
....
const [logged,setLogged] = useState(false)
.....
url: "http://localhost:4000/register"
}).then((res) => if(res.Sucess){
setLogged(true)
};
in your main component. you can add a redirect component like.
<div className="App">
{logged && <Redirect to="redirect-url" />}

Not Able to render new Component on link change

Actually when ever a person click's on Sign in Button the link change but the component on that page does not renders
App.js
import { BrowserRouter as Switch, Route } from 'react-router-dom';
const App = () => (
<Switch>
<Route path="/" exact component={Join} />
<Route path="/call" exact component={Call} />
</Switch>
);
export default App;
Join.js
return (
<div className="container">
<div><input id="room" placeholder="room name" onChange={(event)=>setRoom(event.target.value)}></input></div>
<BrowserRouter>
<Link onClick={event => (!room) ? event.preventDefault() : null} to={`/call?room=${room}`}>
<button className="button mt-20" type="submit" onClick={run}>Sign In</button>
</Link>
</BrowserRouter>
</div>
);
}
export default Join;
Call.js
const Call = () => {
return (
<div>
<h1>jhjcjc</h1>
</div>
);
}
export default Call;
Please look over this error many developer's are facing this problem.
In your Join component, there is no need to wrap Link in a BrowserRouter. Check out the working demo here.

React-Router how to prevent from redirect

So I have a problem in my code that when I refresh my page it sends me a NotFound page, but when I don't refresh the page still works while changing the route (single page application)
My routes code:
import React, { Component } from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Navigation from './src/containers/Navigation/Navigation';
import PageProjects from './src/containers/PageProjects/PageProjects';
import NewPost from './src/components/pages/Projects/NewPost/NewPost'
import Home from './src/components/pages/Home/Home';
import Calendar from './src/components/pages/Calendar/Calendar';
import Team from './src/components/pages/Team/Team';
import Settings from './src/components/pages/Settings/Settings';
import NotFound from './src/components/pages/NotFound/NotFound';
class App extends Component {
render() {
return (
<div className="App" style={{ height: '100%' }}>
<BrowserRouter>
<div>
<Navigation />
<Switch>
<Route path="/profile" component={Home} exact />
<Route path="/projects" component={PageProjects} exact />
<Route path="/calendar" component={Calendar} exact />
<Route path="/team" component={Team} exact />
<Route path="/newpost" component={NewPost} exact />
<Route path="/settings" component={Settings} exact />
<Route path="*" component={NotFound} exact />
</Switch>
</div>
</BrowserRouter>
</div>
);
}
}
export default App;
Only my "/profile" page works because it's the page that I'm sending the index.html file from my route server
app.get('/profile', function(req, res){
res.sendFile(__basedir + "/react/index.html");
});
My Navigation Component:
import React, { Component } from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Toolbar from '../../components/Toolbar/Toolbar';
import SideBar from '../../components/SideBar/SideBar';
import Backdrop from '../../components/Backdrop/Backdrop';
import Home from '../../components/pages/Home/Home';
import Calendar from '../../components/pages/Calendar/Calendar';
import Team from '../../components/pages/Team/Team';
import Settings from '../../components/pages/Settings/Settings';
import NotFound from '../../components/pages/NotFound/NotFound';
class Navigation extends Component {
state = {
sideBarOpen: false,
}
barToggleClickHandler = () => {
this.setState((prevState) => {
return{sideBarOpen: !prevState.sideBarOpen};
});
};
backdropClickHandler = () => {
this.setState({sideBarOpen: false});
};
render() {
let backdrop;
if(this.state.sideBarOpen){
backdrop = <Backdrop click={this.backdropClickHandler}/>;
}
return (
<section className="Navigation">
<Toolbar barClickHandler={this.barToggleClickHandler} />
<SideBar show={this.state.sideBarOpen}/>
{backdrop}
<main style={{marginTop: '150px'}}>
</main>
</section>
);
}
}
export default Navigation;
What can I do?
Thanks
(I'm using Reactjs, Nodejs, Express..)
app.get('/', function(req, res){
res.sendFile(__basedir + "/react/index.html");
});
or use hashrouter
<HashRouter>
<div>
<Navigation />
<Switch>
<Route path="/profile" component={Home} exact />
<Route path="/projects" component={PageProjects} exact />
<Route path="/calendar" component={Calendar} exact />
<Route path="/team" component={Team} exact />
<Route path="/newpost" component={NewPost} exact />
<Route path="/settings" component={Settings} exact />
<Route path="*" component={NotFound} exact />
</Switch>
</div>
</HashRouter>
This should do the trick !
app.get('/', function(req, res){
res.sendFile(__basedir + "/react/index.html");
});

Resources