Hi i am trying to change the route of my website to go to Contact, when the menu is clicked.
Whenever i press the button for the homepage which is "Forside", the routing works perfectly.
But as soon as i press the button for the contact which is "Kontakt", the url changes and no component renders. But if i refresh the page, it shows up..
Any ideas what is wrong with my code, or any way to fix it?
All help will be appreciated thanks.
My App.js
import React from 'react';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import Forside from './forside';
import Kontakt from './Kontakt';
import Header from './Header'
const App = () => {
return(
<Router>
<div>
<Header/>
<Switch>
<Route exact path="/" component={Forside}/>
<Route path="/kontakt" component={Kontakt}/>
</Switch>
</div>
</Router>
)
}
export default App
And this is where i link to the different routes.
import React, { useState } from 'react';
import './header.css'
import { makeStyles } from '#material-ui/core/styles';
import BottomNavigation from '#material-ui/core/BottomNavigation';
import BottomNavigationAction from '#material-ui/core/BottomNavigationAction';
import ContactMailIcon from '#material-ui/icons/ContactMail';
import LocationOnIcon from '#material-ui/icons/LocationOn';
import {Link} from 'react-router-dom';
const useStyles = makeStyles({
root: {
width: 500,
},
});
const Header = () => {
const classes = useStyles();
const [value, setValue] = React.useState(0);
return(
<div className="hed">
<h1 className="logo"><span>IT</span> ARBEJDE.DK</h1>
<BottomNavigation
value={value}
className="nav"
onChange={(event, newValue) => {
setValue(newValue);
}}
showLabels
className={classes.root}
>
<Link to="/">
<BottomNavigationAction label="Søg job" icon={<LocationOnIcon />} />
</Link>
<Link to="/kontakt">
<BottomNavigationAction label="Kontakt" icon={<ContactMailIcon/>} />
</Link>
</BottomNavigation>
</div>
)
}
export default Header
add exact to it to your route
<Route exact path="/kontakt" component={Kontakt}/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Since i didn't get a answer, i have figured it out on my own. So i would just like to share the solution, for other people who maybe are expecting the same bug.
I fixed the problem, by restructuring my code.
I placed my router inside the index.js component like this:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {BrowserRouter as Router} from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Router>
<App/>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
Then placed the Header code inside my App.js, instead of having the Component rendering.
So i refactored the code like this:
import React from 'react';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import Kontakt from './Kontakt';
import Forside from './forside';
import { makeStyles } from '#material-ui/core/styles';
import BottomNavigation from '#material-ui/core/BottomNavigation';
import BottomNavigationAction from '#material-ui/core/BottomNavigationAction';
import ContactMailIcon from '#material-ui/icons/ContactMail';
import LocationOnIcon from '#material-ui/icons/LocationOn';
import {Link} from 'react-router-dom';
import './header.css'
const useStyles = makeStyles({
root: {
width: 500,
},
});
const App = () => {
const classes = useStyles();
const [value, setValue] = React.useState(0);
return(
<div>
<div className="header-container">
<h1 className="logo"><span>IT</span> ARBEJDE.DK</h1>
<BottomNavigation
value={value}
className="nav"
onChange={(event, newValue) => {
setValue(newValue);
}}
showLabels
className={classes.root}
>
<BottomNavigationAction label="Søg job" component={Link} to="/" icon={<LocationOnIcon />} />
<BottomNavigationAction label="Kontakt" component={Link} to="/kontakt" icon={<ContactMailIcon/>} />
</BottomNavigation>
</div>
<Switch>
<Route exact path="/" component={Forside}/>
<Route exact path="/kontakt" component={Kontakt}/>
</Switch>
</div>
)
}
export default App
Related
i am trying to use the useContext hook for the first time and i am not getting the name displayed on screen, i have never used useContext ever before, so pls a little bit of explination of my mistake will be appreciated. Here is the code:
(edit: added App.js)
AuthContext.js
const AuthContext = createContext()
export default AuthContext;
export const AuthProvider = ({children}) => {
return (
<AuthContext.Provider value={{'name':"Dennis"}}>
{children}
</AuthContext.Provider>
)
}
Header.js
import React, { createContext, useContext } from 'react'
import { Link } from 'react-router-dom'
import AuthContext from '../context/AuthContext'
const Header = () => {
let { name } = useContext(AuthContext)
return (
<div>
<Link to="/">Home</Link>
<span> </span>
<Link to="/login">Login</Link>
<h1>Hello {name}</h1>
</div>
)
}
export default Header
App.js
import './App.css';
import {
BrowserRouter,
Routes,
Route,
} from "react-router-dom";
import HomePage from './pages/HomePage';
import LoginPage from './pages/LoginPage';
import Header from './components/Header';
import PrivateRoute from './utils/PrivateRoute'
import AuthProvider from './context/AuthContext';
function App() {
return (
<div className="App">
<BrowserRouter>
<AuthProvider>
<Header />
<Routes>
<Route path="/" element={ <PrivateRoute> <HomePage /> </PrivateRoute>} />
<Route path="/login" element={<LoginPage />} />
</Routes>
</AuthProvider>
</BrowserRouter>
</div>
);
}
export default App;
i have added the error screenshot
import AuthProvider from './context/AuthContext';
Instead of the above, you have to import the AuthProvider like below since you have used named export for AuthProvider in the AuthContext.js file.
import { AuthProvider } from './context/AuthContext';
App.js code-
import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { Container } from "react-bootstrap";
import Header from "./components/Header";
import Footer from "./components/Footer";
import HomeScreen from "./screens/HomeScreen";
const App = () => {
return (
<Router>
<Header />
<main className='py-3'>
<Container>
<HomeScreen />
</Container>
</main>
<Footer />
</Router>
);
};
export default App;
My app.js was like this and everything was working fine. But after that I added Route tag and the code become like this
import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { Container } from "react-bootstrap";
import Header from "./components/Header";
import Footer from "./components/Footer";
import HomeScreen from "./screens/HomeScreen";
const App = () => {
return (
<Router>
<Header />
<main className='py-3'>
<Container>
<Route exact path='/' component={HomeScreen} />
</Container>
</main>
<Footer />
</Router>
);
};
export default App;
But after adding Route, HomeScreen is not rendering?
Can anybody tell me why this is happening?
In react-router-dom v6 the Route component must be rendered into a Routes component, and the routed components are rendered on the element prop as a ReactElement (a.k.a. JSX) since the component, and render and children function props no longer exist.
import React from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import { Container } from "react-bootstrap";
import Header from "./components/Header";
import Footer from "./components/Footer";
import HomeScreen from "./screens/HomeScreen";
const App = () => {
return (
<Router>
<Header />
<main className='py-3'>
<Container>
<Routes>
<Route path='/' element={<HomeScreen />} />
</Routes>
</Container>
</main>
<Footer />
</Router>
);
};
after installing react-router-dom version 6 I tried to run npm start but I get a blank page with no error in my console. Below the first code is the code for the screen I want to display. Please can someone help me and show me what I am not doing correctly here.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import reportWebVitals from './reportWebVitals';
import MovieList from './component/movieList';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Router>
<Routes>
<Route exact path = "/welcome" element = {MovieList}/>
</Routes>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
import { useState } from "react";
function MovieList() {
const [searchTerm, setSearchTerm] = useState("")
const [movies, setMovie] = useState([])
const handleMovieSearchChange = (e) => {
setSearchTerm(e.target.value);
};
const fetchMovie = (movieName) => {
const searchUrl = `https://www.omdbapi.com/?s=${movieName}&page=2&apikey=2c2c85ae`;
fetch(searchUrl)
.then((response) => response.json())
.then((result) => {
setMovie(result.Search);
});
};
const movieItems = movies.map((movie, index) => {
return (
<div key={index}>
<img src={movie.Poster} alt="" />
<h3>{movie.Title}</h3>
</div>
)
})
return (
<div>
<h1>Movie List Page</h1>Search
<input type={"text"} onChange={handleMovieSearchChange} />
<button onClick={() => fetchMovie(searchTerm)}>Search</button>
{movieItems}
</div>
);
}
export default MovieList;
I guess it is a componet: <Route exact path = "/welcome" element = {MovieList}/>
instead <Route exact path = "/welcome" element = {<MovieList/>}/>
You are getting a blank white screen because you are not rendering any component/page for the home route /. When the react application render initially renders the page which has path="/". there are two ways to fix it you can either render your welcome page at path / or you can redirect the user to the welcome screen if the user hits the home or / path.
First Method
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import reportWebVitals from './reportWebVitals';
import MovieList from './component/movieList';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Router>
<Routes>
<Route exact path = "/" element = {MovieList}/>
</Routes>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
Second Method
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import reportWebVitals from './reportWebVitals';
import MovieList from './component/movieList';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Router>
<Routes>
<Route exact path = "/welcome" element = {MovieList}/>
<Route path="/" element={<Navigate replace to="/welcome" />} />
</Routes>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
i've been following an online course about react but it's a bit dated and i've been struggling through all the lessons to understand the concepts explained while applying the new syntax instead of the the one shown in the videos. i've always more or less managed but now i'm stuck because, after adding the react router dom web app, my pages don't render anymore. no errors nor warnings are shown and no matter how much i look, i can't seem to find the mistake. my main right now looks like this:
import React from 'react';
import Header from './header';
import MyPlacesList from './myplaceslist.js';
import Footer from './footer';
import CreatePlace from './createPlace.js';
import * as attAPI from '../utils/attractionsAPI';
import { Router, Route } from 'react-router-dom';
class Main extends React.Component{
state = {
attractions: [],
}
componentDidMount(){
attAPI.getAll().then((attractions) => {
this.setState({attractions})
})
}
removePlace = (attraction) => {
this.setState((state) => ({
attractions: state.attractions.filter((attr) => attr.id !== attraction.id)
}))
attAPI.remove(attraction);
}
render(){
return (
<Router>
<Fragment>
<Header titolo = 'My Places' sottotitolo = 'I miei posti preferiti'/>
<Route exact path = '/' render = {() => (
<MyPlacesList attractions = {this.state.attractions}
onRemovePlace = {this.removePlace} />
)}/>
<Route path = '/create' render = {() => (
<CreatePlace />
)}/>
<Footer />
</Fragment>
</Router>
)
}
}
export default Main;
and this is the header:
import React from 'react';
import AppBar from '#mui/material/AppBar';
import Box from '#mui/material/Box';
import Toolbar from '#mui/material/Toolbar';
import Typography from '#mui/material/Typography';
import IconButton from '#mui/material/IconButton';
import Icon from '#mui/material/Icon';
import AddCircleIcon from '#mui/icons-material/AddCircle';
import { Link } from 'react-router-dom';
class Header extends React.Component{
render(){
// return <nav>
// <div className = "nav-wrapper">
// {this.props.titolo}
// </div>
// </nav>
return <Box sx={{ flexGrow: 1 }}>
<AppBar position="static">
<Toolbar>
<Typography
variant="h6"
noWrap
component="div"
sx={{ flexGrow: 1, display: { xs: 'none', sm: 'block' } }}
>
{this.props.titolo}
</Typography>
<Link to = '/create'>
<IconButton>
<AddCircleIcon />
</IconButton>
</Link>
</Toolbar>
</AppBar>
</Box>
}
}
export default Header;
before adding react router dom i was using the state to call the components MyPlacesList/CreatePlace (createPlace only gets shown when i click on a button) and it worked just fine, the problem appeared after i tried to use <Route>. any ideas in how could i fix this? thank you in advance!
EDIT - here's my index page too:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import Main from './components/main';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<Main/>
</BrowserRouter>, document.getElementById('root'));
Things to correct
Use React.Fragment instead of just Fragment or import from react.
Add All Routes between Routes component.
You have already add Router or BrowserRouter in index.js so don't need to add again.
There is a change in nesting in version 5.
So ultimately the nesting should be in version 6
<BrowserRouter>
<Routes>
<Route>
<Route>
</Routes>
</BrowserRouter>
import MyPlacesList from "./myPlacesList.js";
import CreatePlace from "./createPlace.js";
import { Route, Routes } from "react-router-dom";
class App extends React.Component {
render() {
return (
<React.Fragment>
<div>Some Header component</div>
<Routes>
<Route
exact
path="/"
render={() => (
<MyPlacesList
attractions={this.state.attractions}
onRemovePlace={this.removePlace}
/>
)}
/>
<Route path="/create" render={() => <CreatePlace />} />
</Routes>
</React.Fragment>
);
}
}
export default App;
I have an App.js, that looks like this:
import React, { Component } from 'react';
import './App.css';
import PdfViewer from './components/PdfViewer';
import {BrowserRouter as Router, Link, Switch, Route} from 'react-router-dom'
import history from './history';
import Homepage from './components/Homepage'
class App extends Component {
render() {
return (
<Router history={history}>
<Switch>
<Route exact path="/" component={Homepage} />
<Route path="/pdfviewer" component={PdfViewer} />
</Switch>
</Router>
);
}
}
inside a nested component i have a <Link> like this:
import React from 'react';
import ListItem from '#material-ui/core/ListItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
import DashboardIcon from '#material-ui/icons/Dashboard';
import { BrowserRouter as Router, Link } from "react-router-dom";
export const MainListItems = () => {
return(
<Link to="/">
<div>
<ListItem button>
<ListItemIcon>
<DashboardIcon />
</ListItemIcon>
<ListItemText primary="Dashboard" />
</ListItem>
</div>
</Link>
)}
here is my component, that renders a Link.
When it is clicked, the Url changes, but it does not render a new component... how come?