I have created a navbar component in my react app using tailwindcss for styling. I have imported react-router-dom#6.6.1 and tried to set up routes but can't get my pages/routes to show up.
Index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
App.js
import React from "react";
import "./App.css";
import { Route, Routes } from "react-router-dom";
import Home from "./routes/Home.js";
import About from "./routes/About.js";
import Navbar from "./components/Navbar";
import Footer from "./components/Footer";
function App() {
return (
<>
<Navbar />
<Routes>
<Route path="/" exact element={<Home />}></Route>
<Route path="/About" element={<About />}></Route>
</Routes>
<Footer />
</>
);
}
export default App;
Home page
import React from "react";
const Home = () => {
return (
<div>
<h1 className="text-black text-3xl">Home</h1>
</div>
);
};
export default Home;
I would expect to see Home appear on the "/" route when I click on the home link on the navbar and the same for About. However, I don't seem to be returning any routes.
About page:
const About = () => {
return <h1>About Wick House</h1>;
};
export default About;
Navbar
import React, { useState } from "react";
import { Link } from "react-router-dom";
const Navbar = () => {
let [open, setOpen] = useState(false);
return (
<header className="w-full fixed top-0 left-0 bg-slate-400 h-14">
<nav className="md:flex items-center justify-between px-[8%] ">
<div
className=" text-base cursor-pointer flex items-center
text-white gap-4 pt-2"
>
<img
src="/wickhouse-logo-192x192.png"
className="w-10 rounded"
alt="Wick House Publishing Logo"
/>
<h1>WICK HOUSE PUBLISHING</h1>
</div>
<div
onClick={() => setOpen(!open)}
className="text-3xl text-white absolute right-[8%] top-3 cursor-pointer md:hidden"
>
<ion-icon name={open ? "close" : "menu"}></ion-icon>
</div>
<ul
className={`md:flex md:items-center md:pt-2 absolute md:static md:bg-slate-400 bg-slate-600 md:z-auto z-[10] left-0 w-full md:w-auto md:pl-0 pl-[8%] md:transition-none transition-all duration-500 ease-in ${
open ? "top-14 " : "top-[-490px]"
}`}
>
<li className=" md:ml-8 text-base md:my-0 my-4">
<Link
to="/"
className="text-white hover:text-gray-300 duration-500"
>
HOME
</Link>
</li>
<li className=" md:ml-8 text-base md:my-0 my-4">
<Link
to="/About"
className="text-white hover:text-gray-300 duration-500 md:ml-8 text-base md:my-0"
>
ABOUT
</Link>
</li>
<li className=" md:ml-8 text-base md:my-0 my-4">
<Link
to="/Authors"
className="text-white hover:text-gray-300 duration-500 md:ml-8 text-base md:my-0"
>
AUTHORS
</Link>
</li>
<li className=" md:ml-8 text-base md:my-0 my-4">
<Link
to="/Contact"
className="text-white hover:text-gray-300 duration-500 md:ml-8 text-base md:my-0"
>
CONTACT
</Link>
</li>
</ul>
</nav>
</header>
);
};
export default Navbar;
I have tried the documentation, guides, youtube and can't figure it out.
Related
App.jsx
import { useState } from 'react';
import './App.css';
import NewsContainer from './Components/NewsContainer';
import { Router, Routes, Route } from "react-router-dom"
function App() {
const [mode, setMode] = useState("light")
const changeMode = () => {
if (mode === "light") {
setMode("dark")
document.body.style.backgroundColor = "rgb(30 41 59)"
} else {
setMode("light")
document.body.style.backgroundColor = "white"
}
}
return (
<Router>
<div className='justify-evenly'>
<Routes>
<Route exact path="/" element={<NewsContainer key="general" mode={mode} changeMode={changeMode} category="general" />} />
<Route exact path='/sports' element={<NewsContainer key="sports" mode={mode} changeMode={changeMode} category="sports" />} />
<Route exact path='/buisness' element={<NewsContainer key="buisness" mode={mode} changeMode={changeMode} category="buisness" />} />
<Route exact path='/entertainment' element={<NewsContainer key="entertainment" mode={mode} changeMode={changeMode} category="entertainment" />} />
<Route exact path='/health' element={<NewsContainer key="health" mode={mode} changeMode={changeMode} category="health" />} />
</Routes>
</div>
</Router>
);
}
export default App;
Navbar.jsx
import { Link } from "react-router-dom";
function Navbar({ mode, changeMode }) {
return (
<div
className={`${mode === "light" ? "bg-gray-100" : "dark : bg-slate-900"} `}
>
<header className="text-gray-600 body-font">
<div className="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center">
<li
className={`flex title-font font-medium list-none items-center text-${
mode === "light " ? "gray-900" : "white"
} mb-4 md:mb-0 cursor-pointer`}
>
<span
className={`ml-3 text-xl text-${
mode === "light" ? "black" : "white"
}`}
>
<Link to="/">Hind News</Link>
</span>
</li>
<nav className="md:mr-auto md:ml-4 md:py-1 md:pl-4 md:border-l md:border-gray-400 flex flex-wrap items-center text-base justify-center list-none cursor-pointer">
<li
className={`mr-5 hover:text-${
mode === "light" ? "dark : gray-900" : "white"
}`}
>
<Link to="/sport"> Sports </Link>
</li>
<li
className={`mr-5 hover:text-${
mode === "light" ? "dark : gray-900" : "white"
}`}
>
<Link to="/buisness">Buisness </Link>
</li>
<li
className={`mr-5 hover:text-${
mode === "light" ? " dark:gray-900" : "white"
}`}
>
<Link to="/entertainment">Entertainment </Link>
</li>
<li
className={`mr-5 hover:text-${
mode === "light" ? "dark : gray-900" : "white"
}`}
>
<Link to="/health">Health </Link>
</li>
</nav>
<input
type="text"
className="inline-flex items-center bg-gray-200 border-0 py-1 px-3 focus:outline-none hover:bg-gray-300 rounded text-base mt-4 md:mt-0"
/>
<button className="inline-flex items-center bg-gray-100 border-0 py-1 px-3 focus:outline-none hover:bg-gray-200 rounded text-base mt-4 md:mt-0">
Search
<svg
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
className="w-4 h-4 ml-1"
viewBox="0 0 24 24"
>
<path d="M5 12h14M12 5l7 7-7 7"></path>
</svg>
</button>
<div className="flex justify-center">
<div className="flex justify-center">
<div className="form-check form-switch">
<input
className="form-check-input appearance-none w-9 -ml-10 rounded-full float-left h-5 align-top bg-white bg-no-repeat bg-contain bg-gray-300 focus:outline-none cursor-pointer shadow-sm ml-60"
type="checkbox"
role="switch"
id="flexSwitchCheckDefault"
onClick={changeMode}
/>
<label
className={`form-check-label inline-block text-${
mode === "light" ? "gray-900" : "white"
} `}
htmlFor="flexSwitchCheckDefault"
>
{" "}
Switch Mode
</label>
</div>
</div>
</div>
</div>
</header>
</div>
);
}
export default Navbar;
Error on console
Uncaught TypeError: Cannot read properties of undefined (reading
'pathname')
The above error occurred in the <Router> component:
at Router (http://localhost:3000/static/js/bundle.js:39615:15)
at App (http://localhost:3000/static/js/bundle.js:33:74)
Consider adding an error boundary to your tree to customize error
handling behavior. Visit https://reactjs.org/link/error-boundaries to
learn more about error boundaries.
You probably want to use the BrowserRouter instead of Router, which is a wrapper around Router.
you got a typo in there.
<Link to="/sport"> Sports </Link>
when in the Route it spells sports
<Route exact path='/sports' element={<NewsContainer key="sports" mode={mode} changeMode={changeMode} category="sports" />} />
Hope it solves it
Issue
You are importing and rendering the low-level Router component and not passing any of the required props.
import { Router, Routes, Route } from "react-router-dom"
Router
declare function Router(
props: RouterProps
): React.ReactElement | null;
interface RouterProps {
basename?: string;
children?: React.ReactNode;
location: Partial<Location> | string; // <-- missing
navigationType?: NavigationType;
navigator: Navigator; // <-- missing
static?: boolean;
}
Missing are the location and navigator props. The error is specifically due to the missing location prop, it's undefined, so the code can't access pathname of `undefined.
Solution
You almost never need to render Router yourself manually. You should instead render one of the high-level routers (e.g. BrowserRouter, HashRouter, etc) that instantiates and maintains a history reference and passes these required props to the low-level Router component.
Example:
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import React from 'react';
import { Link,Router } from 'react-router-dom';
const Navbar = () => {
return (
<div className='p-5 pb-0 flex flex-wrap sm:justify-between justify-center item-center border-b dark:border-gray-700 border-gray-200'>
<div className="w-screen flex justify-between items-center space-x-5">
<Link to="/">
<p className='text-2xl '>Not Google</p>
</Link>
</div>
</div>
)
}
export default Navbar
Your Navbar component should be a child (any nesting depth) of Router component. Please check where is your Router component (BrowserRouter, etc...)
I am trying to create a boostrap react navbar, I am following a guide and this code SHOULD be working but it isn't. Instead it only displays the "database" text and not the navbar. Please do keep in mind that I know there are different ways of creating ne but I want to fix this code. Any help would be greatly appreciated!
App.js:
import './App.css';
import {Home} from './Home';
import {Student} from './Student';
import {Professor} from './Professor';
import {Course} from './Course';
import {Navigation} from './Navigation';
import {BrowserRouter as Router, Routes, Route} from 'react-router-dom';
function App() {
return (
<Router>
<div className="container">
<h3 className="m-3 d-flex justify-content-center">
Database
</h3>
<Navigation/>
<Routes>
<Route path='/' component={Home} />
<Route path='/student' component={Student}/>
<Route path='/professor' component={Professor}/>
<Route path='/course' component={Course}/>
</Routes>
</div>
</Router>
);
}
export default App;
Navigation.js:
import React,{Component} from 'react';
import {NavLink} from 'react-router-dom';
import {Navbar, Nav} from 'react-bootstrap';
export class Navigation extends Component
{
render()
{
return
{
<Navbar bg="dark" expand="lg">
<Navbar.Toggle aria-controls="basic-navbar-nav"/>
<Navbar.Collapse id="basic-navbar-nav">
<Nav>
<NavLink className="d-inline p-2 bg-dark text-white" to="/">
Home
</NavLink>
<NavLink className="d-inline p-2 bg-dark text-white" to="/student">
Students
</NavLink>
<NavLink className="d-inline p-2 bg-dark text-white" to="/professor">
Professors
</NavLink>
<NavLink className="d-inline p-2 bg-dark text-white" to="/course">
Courses
</NavLink>
</Nav>
</Navbar.Collapse>
</Navbar>
}
}
}
return method inside class should have parenthesis instead of curly brackets.
I fixed and added the answer. Replace Navigation.js code by following.
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import { Navbar, Nav } from 'react-bootstrap';
export class Navigation extends Component {
render() {
return (
<Navbar bg="dark" expand="lg">
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav>
<NavLink className="d-inline p-2 bg-dark text-white" to="/">
Home
</NavLink>
<NavLink className="d-inline p-2 bg-dark text-white" to="/student">
Students
</NavLink>
<NavLink className="d-inline p-2 bg-dark text-white" to="/professor">
Professors
</NavLink>
<NavLink className="d-inline p-2 bg-dark text-white" to="/course">
Courses
</NavLink>
</Nav>
</Navbar.Collapse>
</Navbar>
);
}
}
I am having trouble with React while trying to set a token for user to log into the application. I followed the steps here to create a login process but it gives out the Unhandled Rejection (TypeError): setToken is not a function error and I am not able to correct it.
Here are the associated codes starting with from app.js
import React from 'react';
import { useState } from 'react';
import Login from './Pages/Login.js';
import Signup from './Pages/Signup';
import Dashboard from './Pages/Dashboard.js';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import useToken from './Pages/useToken'
function App() {
const { token, setToken } = useToken();
if (!token) {
return <Login setToken={setToken} />
};
return (
<div className="">
<BrowserRouter>
<Switch>
<Route exact path="/">
<Login />
</Route>
<Route exact path="/dashboard">
<Dashboard />
</Route>
<Route exact path="/signup">
<Signup />
</Route>
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
Login.js
import React from 'react';
import { useState } from 'react';
import PropTypes from 'prop-types';
async function loginUser(credentials) {
return fetch('http://localhost:8080/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(credentials)
})
.then(data => data.json())
}
const Login = ({setToken}) => {
// username is email address
const [username, setUsername] = useState();
const [password, setPassword] = useState();
const handleSubmit = async(e) => {
e.preventDefault();
const token = await loginUser({
username,
password
});
setToken(token);
};
return (<>
<section>
<div className="flex items-center justify-center flex-col">
<div className="w-11/15 mt-24 rounded-lg flex flex-col items-center justify-center relative">
<span className="flex flex-col lg:flex-row">
<header className="text-5xl pr-4">Welcome to </header>
<header className="font-LoveloLine text-6xl font-bold text-center"> Mused</header>
</span>
</div>
</div>
</section>
<section>
<div className="flex items-center justify-center flex-col">
<div className=" lg:w-2/4 px-4 rounded-lg flex flex-col items-center justify-center relative" >
<div className="py-12">
<form action="" className="flex flex-col gap-2" onSubmit={handleSubmit}>
{/* Email address */}
<label htmlFor=""></label>
<input className="w-96 text-brand-Black bg-white border-brand-Blue rounded-lg py-3 focus:outline-none focus:ring-2 focus:ring-brand-Red focus:border-transparent" type="email" name="" placeholder="Email address" id="" onChange={(e) => { setUsername(e.target.value)}} />
<label htmlFor=""></label>
{/* Password */}
<input className="w-96 bg-white text-brand-Black border-brand-Blue rounded-lg py-3 focus:outline-none focus:ring-2 focus:ring-brand-Red focus:border-transparent" type="password" name="" placeholder="Password" id="" onChange={(e) => { setPassword(e.target.value)}} />
<div class="max-w-sm mx-auto py-4">
<label class="inline-flex items-center">
<input class="text-brand-Blue w-6 h-6 mr-2 focus:ring-indigo-400 focus:ring-opacity-25 border border-gray-300 rounded" type="checkbox" />
Remember me
</label>
</div>
{/* Login button */}
<div>
<button type="submit" className="bg-brand-Blue rounded-full w-full py-2 active:bg-brand-Blue-dark hover:bg-brand-Blue-dark">Login</button>
</div>
</form>
{/* Checkbox */}
{/* Signup button */}
<div className="flex flex-col items-center justify-center ">
<p className="py-6">or</p>
<button type="submit" className="bg-brand-Red rounded-full w-full py-2 active:bg-brand-Red-dark hover:bg-brand-Red-dark">Signup
</button>
</div>
</div>
</div>
</div>
</section>
</>
)
};
Login.propTypes = {
setToken: PropTypes.func.isRequired,
}
export default Login
Error is thrown for Login.js file "setToken(token)" function. It is not supposed to be a function
import { useState } from 'react';
const 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
}
}
export default useToken
In my own case i discovered that I was passing the setToken function inside login route like this:
<Route path='/login setToken={setToken} />
instead of
<Route path='/login' exact element={<Login
setToken={setToken}
/>}
/>
You have to pass it to the component itself, not the route!
Your posting this as within only the component, as soon as you go to the route it disregards it. So from localhost:3000 it'll work fine, but because you've not passed it through the route setToken={token} it'll disregard it. Scratched my head at this for hours.
So I am having a problem with payment Component. Basically I want when I press on the link it pushes (ClassG imageG and PriceG) into the Payment Component where I can style them again I have tried something but it is giving me the straight information(Arayys) when I click on the Link. That is not exactly what I want. I would like some help if possible. Thanks in Advance
import React from "react";
import data from "../data.json";
import { Link } from "react-router-dom";
function G() {
return (
<div className='bg-black '>
{data.filter(d =>
d.classG &&
d.imageG &&
d.priceG)
.map((postData) => {
return (
<div className='bg-black' key={postData.id} >
<div className='bg-black '>
<img
alt=""
className="w-full object-contain "
src={postData.imageG}
></img>
<h1 className=" ml-24 mlg:ml-6 mlg:mt-2 mlg:static text-5xl mlg:text-2xl text-blue-400
absolute top-48">
{postData.classG}
</h1>
<h1 className="text-lg mlg:mb-2 mlg:ml-6 mlg:mt-2 mlg:static font-bold text-green-800
font-mono ml-24 top-64 absolute" >
{postData.priceG}
</h1>
<Link
to={`/payment/${postData.id}`}
className="py-1 px-2 mlg:ml-6 mlg:mt-14 mlg:static text-black-600 h-8 ml-24 top-72 bg-
white w-32 text-center text-gray-red
rounded-full focus:outline-none focus:ring-2 focus:ring-gray-600 absolute"
>
Buy Now
</Link>
<div id='New' className="flex flex-col mt-40 justify-center border-white text-center items-
center bg-black" >
<h1 className='tracking-tighter mb-20 text-white text-base md:text-6xl'>What's new in
2021</h1>
<h1 className=' md:p-4 md:w-2/4 font-sans mb-16 text-white '>{postData.newG} </h1>
</div>
</div>
</div>
)
}
export default G
json file
[
{
"id":1,
"classG":"G-Class",
"imageG":"./ModImages/Gclass.jpg",
"priceG":"Starting at $154,900"
"newE": "some text"
},
]
Payment Component
import React from "react";
import data from "./Models/data.json";
function Payment(props) {
console.log(props);
const {
match: {
params: { dataId }
}
} = props;
const item = data.find(({ id }) => id === Number(dataId));
return (
<div className="ml-20">
<pre>{JSON.stringify(item, null, 2)}</pre>
</div>
);
}
export default Payment;
App Component
import React,{useState, useEffect} from 'react'
import './assets/main.css'
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
function App() {
return (
<div className='' >
<div>
<Router>
<Header />
<Switch>
<Route path="/a">
<A />
</Route>
<Route path="/payment/:dataId" component={Payment}>
</Route>
</Switch>
</Router>
</div>
</div>
);
}
export default App;
In order to send the specific product data you can use the route state of the routing transition.
Link - to: object
<Link
to={{
pathname: `/payment/${postData.id}`,
state: {
postData,
},
}}
className="..."
>
The route state can be accessed on the receiving route's component on the location object. Components rendered by a Route's render, component, or children prop receive all the route props.
function Payment(props) {
const {
location: {
state: {
postData, // <-- access route state from location.state
},
},
match: {
params: { dataId }
},
} = props;
const {
classG,
imageG,
priceG,
// ... any other postData object properties
} = postData;
return (
<div className="ml-20">
<pre>{JSON.stringify(postData, null, 2)}</pre>
</div>
);
}