I got this error while i trying to route some link:
Uncaught Error: [HotAccessories] is not a Route component. All component children of Routes must be a Route or <React.Fragment>
import './App.css';
import PreNavbar from './Components/PreNavbar';
import Navbar from "./Components/Navbar.js"
import { BrowserRouter as Router,Route} from "react-router-dom"
import Slider from "./Components/Slider.js"
import Offers from "./Components/Offers.js"
import data from "./data/data.json";
import Heading from "./Components/Heading.js"
import StarProduct from "./Components/StarProduct.js"
import HotAccessoriesManu from "./Components/HotAccessoriesManu.js"
import HotAccessories from "./components/HotAccessories.js"
function App( ) {
return (
<Router>
<PreNavbar />
<Navbar />
<Slider start = {data.banner.start} />
<Offers offer={data.offer} />
<Heading text = "STAR PRODUCTS"/>
<StarProduct starProduct={data.starProduct}/>
<Heading text = "HOT ACCESSORIES" />
<HotAccessoriesManu />
<Route exact path="/music">
<HotAccessories music={data.hotAccessories.music} musicCover={data.hotAccessories.music} />
</Route>
</Router>
);
}
export default App;
Here is the HotAccessories component:
import HotItem from "./HotItemCard.js"
const HotAccessories = ({music, musicCover}) => {
return (
<div className='HotAccessories'>
<div>
<img src= {musicCover} alt="Cover" />
</div>
{/* ........2nd part */}
<div>
{music.map((item, index)=>(
<HotItem key={item.image} name={item.name} price={item.price} image={item.image} index={item.index} />
))}
</div>
</div>
)
}
export default HotAccessories;
here is HotItem component:
import React from 'react'
const HotItemCard = ({image,index,name,price}) => {
return (
<div className="HotItemCard">
<img src={image} alt={`${index} product`} />
<p>{name}</p>
<span>{price}</span>
</div>
)
}
export default HotItemCard
But in the terminal it's show me ....
webpack 5.68.0 compiled successfully in 244 ms
But i did't seen any output
Instead of
<Route exact path="/music">
<HotAccessories music={data.hotAccessories.music} musicCover={data.hotAccessories.music} />
</Route>
Try this
<Route exact path="/music" element={
<HotAccessories music={data.hotAccessories.music} musicCover={data.hotAccessories.music} />}
/>
read this section of the react router docs.
Keep in mind that all of your <Route /> elements should be children of the <Routes> component.
Related
i am trying to create a simple react project. it has a navbar, sidebar and the main content area.
first a home component is displayed.
home.js
import { useState } from "react";
import Navbar from "../navbar/navbar";
import Sidebar from "../sidebar/sidebar";
import "./style.css";
import { useSelector, useDispatch } from 'react-redux'
function Home() {
const sidebarOpen = useSelector((state) => state.sidebarOpenState);
return (
<>
<Navbar />
<div className="home-box d-flex">
{sidebarOpen && <div className="p-2 flex-fill"><Sidebar /></div>}
</div>
</>
);
}
export default Home;
my navbar has a button which will change state sidebarOpen.
my sidebar looks like this->
sidebar.js
import "./style.css";
import { Link } from "react-router-dom";
function Sidebar() {
return (
<div className="divSidebar">
<ul>
<li>
<Link to="/chess">
<img className="sidebar-img" src="images/sidebar/chess.png"></img>
<span className="sidebar-text">Chess</span>
</Link>
</li>
<li>
<Link to="/volleyball">
<img
className="sidebar-img"
src="images/sidebar/volleyball.png"
></img>
<span className="sidebar-text">Volleyball</span>
</Link>
</li>
<li>
<Link to="/football">
<img
className="sidebar-img"
src="images/sidebar/football.png"
></img>
<span className="sidebar-text">Football</span>
</Link>
</li>
<li>
<Link to="/tabletennis">
<img
className="sidebar-img"
src="images/sidebar/table-tennis.png"
></img>
<span className="sidebar-text">TableTennis</span>
</Link>
</li>
<li>
<Link to="/rugby">
<img className="sidebar-img" src="images/sidebar/rugby.png"></img>
<span className="sidebar-text">Rugby</span>
</Link>
</li>
</ul>
</div>
);
}
export default Sidebar;
when i click on chess, the respective component should be loaded.
chess.js
function Chess() {
return (
<>
<h1>chess</h1>
</>
);
}
export default Chess;
but the problem is my sidebar disappears. i only want the main content area to be changed nothing else. can someone help? let me know if u want to some more code.
---------edit
i have added console.log in two places. one is in the navbar where the toggle method is defined and another is in redux store where toggle state is defined. both the places onclick is working. i am able to see message but the sidebar is not getting rendered.
---------edit 2
App.js
import "./App.css";
import Navbar from "./components/navbar/navbar";
import { Route, Routes } from "react-router-dom";
import Chess from "./components/chess/chess";
import Volleyball from "./components/volleyball/volleyball";
import Football from "./components/football/football";
import TableTennis from "./components/tabletennis/tabletennis";
import Rugby from "./components/rugby/rugby";
import Home from "./components/home/home";
function App() {
return (
<div className="App">
<Routes>
<Route exact path="/" element={<Home />} />
<Route
path="/chess"
element={
<>
<Navbar />
<Chess />
</>
}
/>
<Route
path="/volleyball"
element={
<>
<Navbar />
<Volleyball />
</>
}
/>
<Route
path="/tabletennis"
element={
<>
<Navbar />
<TableTennis />
</>
}
/>
<Route
path="/football"
element={
<>
<Navbar />
<Football />
</>
}
/>
<Route
path="/rugby"
element={
<>
<Navbar />
<Rugby />
</>
}
/>
</Routes>
</div>
);
}
export default App;
When you click on Chess you navigate to "/chess"
So if u can't see your Navbar there, is because you have to render it there too.
Or, render the Navbar outside de Routes from BrowsterRouter.
We need to see the components rendering on "/chess" and the react-router-dom config on app.js (or on the top lvl you declare it)
----- edit ------
Ok, look this:
function App() {
return (
<BrowserRouter>
<NavBar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/test" element={<Test />} />
</Routes>
</BrowserRouter>
);
}
If you refactor your brower like this is gona be more clean to understand the code and even easy to escale.
As u see, the navBar is outside the Routes, so its gona be visible in all routes.
then you can have this:
-> one path -> one element
your Links on navbar (or sidebar or whatelse) are gona work good.
i found a way. i rendered <Sidebar /> again in all my child components.
like this->
chess.js
function Chess() {
const sidebarOpen = useSelector((state) => state.sidebarOpenState);
return (
{sidebarOpen && (
<div className="p-2 flex-fill">
<Sidebar />
</div>
)}
)
}
this way when i click on button the state is updated and sidebar is rendered automatically.
Here is the code:
import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Navbar from "./components/navbar/navbar";
import Intro from "./components/intro/intro";
import Services from "./components/services/services";
import Experience from "./components/experience/experience";
import TrelloClone from "./pages/TrelloClone/TrelloClone";
import './App.css'
function App() {
return (
<div className="App">
<BrowserRouter>
<Navbar />
<Routes>
{/* <Route path="/vanillajs" element={SpotifyClone} />
<Route path="/djangoapi" element={InstagramClone} /> */}
<Route path="/reactjs" element={<TrelloClone />} />
</Routes>
</BrowserRouter>
<Intro />
<Services />
<Experience />
</div>
);
}
export default App;
So basically I need to hide(or remove) <Intro />, <Services /> and <Experience /> by clicking the link that leads to '/reactjs' path but leave the <Navbar /> on the page.
edit: grammar and clarifications
install this history from this link, when your package is installed successfully, create a file history.js and put the below code in this file.
import {createBrowserHistory} from 'history';
export default createBrowserHistory();
import the history file in this file like import history from './history', then you will get the history props and you can console the history props and check which props are coming and you will find pathname in the history props and make a condition and as you can see in the code below.
import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import history from './history'
import Navbar from "./components/navbar/navbar";
import Intro from "./components/intro/intro";
import Services from "./components/services/services";
import Experience from "./components/experience/experience";
import TrelloClone from "./pages/TrelloClone/TrelloClone";
import './App.css'
function App() {
return (
<div className="App">
<BrowserRouter>
<Navbar />
<Routes>
{/* <Route path="/vanillajs" element={SpotifyClone} />
<Route path="/djangoapi" element={InstagramClone} /> */}
<Route path="/reactjs" element={<TrelloClone />} />
</Routes>
</BrowserRouter>
{history?.location?.pathname !== '/reactjs' &&
<>
<Intro />
<Services />
<Experience />
</>
}
</div>
);
}
export default App;
My App.js
import React from "react";
import { BrowserRouter, Route } from "react-router-dom";
import Home from "./Components/screens/Home";
import Signup from "./Components/screens/Signup";
import Signin from "./Components/screens/Login";
import Profile from "./Components/screens/Profile";
import CreatePost from "./Components/screens/createPost";
import Navbar from "./Components/Navbar";
function App() {
return (
<BrowserRouter>
<Navbar />
<Route path="/">
<Home />
</Route>
<Route path="/Signin">
<Signin />
</Route>
<Route path="/Signup">
<Signup />
</Route>
<Route path="/Profile">
<Profile />
</Route>
<Route path="/create">
<CreatePost />
</Route>
</BrowserRouter>
);
}
export default App;
my navbar is containing links of all pages and is using react-router-dom but my home page is always rendering above every page , it is containing 4 other page links including home, i have just shown home and signup as error is same with other pages as well
My Navbar.js
import React from "react";
import PeopleIcon from "#material-ui/icons/People";
import IconButton from "#material-ui/core/IconButton";
import { Link } from "react-router-dom";
import "../ComponentsCss/Navbar.css";
function Navbar() {
return (
<div>
<nav>
<div className="nav-wrapper white">
<Link to="/" className="brand-logo">
Instagram
</Link>
<ul id="nav-mobile" className="right hide-on-med-and-down">
<li>
<Link to="/Signin">Signin</Link>
</li>
<li>
<Link to="/Signup">Signup</Link>
</li>
<li>
<Link to="/Profile">Profile</Link>
</li>
<li>
<Link to="/create">create</Link>
</li>
</ul>
</div>
</nav>
</div>
);
}
export default Navbar;
Home.js
import React from "react";
import "../../ComponentsCss/Home.css";
function Home() {
return (
<div className="home">
<div className="card home-card">
<h5>Ramesh</h5>
<div className="card-image">
<img src="https://images.unsplash.com/photo-1542103749-8ef59b94f47e?ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8cGVyc29ufGVufDB8fDB8fA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60" />
</div>
<div className="card-content">
<i className="material-icons" style={{ color: "red" }}>
favorite
</i>
<h6>TItle</h6>
<p>this is amazing post</p>
<input type="text" placeholder="add a comment" />
</div>
</div>
</div>
);
}
export default Home;
Signup.js
import React from "react";
import { Link } from "react-router-dom";
import "../../ComponentsCss/Login.css";
function Signup() {
return (
<div className="my-card">
<div className="card auth-card input-field">
<h2>Instagram</h2>
<input type="text" placeholder="name" />
<input type="email" placeholder="email" />
<input type="password" placeholder="password" />
<button
className="btn waves-effect waves-light "
type="submit"
name="action"
>
Signup
</button>
<h5>
<Link to="/signin">Already have account?</Link>
</h5>
</div>
</div>
);
}
export default Signup;
complete github code -: https://github.com/dhruv354/instagram-frontend.git
You need to make your Home route only match when is that exact route, change your App with this:
import React from "react";
import { BrowserRouter, Route } from "react-router-dom";
import Home from "./Components/screens/Home";
import Signup from "./Components/screens/Signup";
import Signin from "./Components/screens/Login";
import Profile from "./Components/screens/Profile";
import CreatePost from "./Components/screens/createPost";
import Navbar from "./Components/Navbar";
function App() {
return (
<BrowserRouter>
<Navbar />
<Route exact path="/">
<Home />
</Route>
<Route path="/Signin">
<Signin />
</Route>
<Route path="/Signup">
<Signup />
</Route>
<Route path="/Profile">
<Profile />
</Route>
<Route path="/create">
<CreatePost />
</Route>
</BrowserRouter>
);
}
export default App;
Issue
By default, Routers inclusively match routes. In other words, all routes with a matching path will be matched and rendered. Think of the path prop as a path prefix, path="/" is a prefix for every path, so it will always be matched and rendered.
Solution
Use the Switch component to exclusively render only a single matching Route component, and order the routes so the more specific paths ("/profile") can be matched before less specific paths ("/"). Your home path "/" will typically be the last route since it is the least specific.
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
function App() {
return (
<Router>
<Navbar />
<Switch>
<Route path="/Signin">
<Signin />
</Route>
<Route path="/Signup">
<Signup />
</Route>
<Route path="/Profile">
<Profile />
</Route>
<Route path="/create">
<CreatePost />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Router>
);
}
Path order and specificity matter
In the Switch, path order and specificity matter.
If for a url "/foo/bar" and example paths:
"/foo"
"/foo/:id"
"/foo/bar"
"/foo" is a prefix for the other routes and less specific, but because of the order it will be matched and rendered since the url will match. If "/foo" wasn't there, then similarly "/foo/:id" would match and render when instead you really wanted that last "/foo/bar" path to be matched.
Update the order:
"/foo/bar"
"/foo/:id"
"/foo"
"bar" is more specific than placeholder ":id", and both are more specific than "/foo".
I am just stuck on this router concept. I am pretty new to react. SO I think we also have a better way of doing so. Correct me if I am doing these things wrong or if we have a better option.
This is my App.js
import React from 'react';
import './App.css';
import Header from './Header';
import Profile from './Profile';
import {BrowserRouter as Router, Switch, Route} from "react-router-dom";
import PullRequests from './PullRequests';
import Overview from "./Overview";
import Repo from './Repo';
function App() {
return (
<Router>
<div className="App">
<Header />
<Switch>
<Route path="/">
<Profile template= {<Overview/>} />
</Route>
<Route path="/tagname=Repo">
<Profile template= {<Repo/>} />
</Route>
<Route path="/Pullrequests">
<PullRequests />
</Route>
</Switch>
</div>
</Router>
);
}
export default App;
This is my profile.js
import React from 'react'
import "./Profile.css"
import { Avatar} from '#material-ui/core';
import PeopleAltIcon from '#material-ui/icons/PeopleAlt';
import StarBorderIcon from '#material-ui/icons/StarBorder';
import LocationOnIcon from '#material-ui/icons/LocationOn';
import Underlinenav from './Underlinenav';
function Profile({template}) {
return (
<div className="profile">
<div className="profile__left">
<Avatar src="https://avatars0.githubusercontent.com/u/68982304?s=460&u=6b37f00eb36173e0f5f5bc04db9e63066d408d80&v=4" className="profile__avatar"/>
<div className="profile__name">
<span><h4>Shivansh Sharma</h4></span>
<span><p>shivkaansh</p></span>
</div>
<button>Edit profile</button>
<div className="profile_leftFollow">
<div className="profile__options">
<span>< PeopleAltIcon fontSize="small" /></span>
<span>1 follower</span>
</div>
<p>4 following</p>
<div className="profile__options">
<span>< StarBorderIcon fontSize="small"/></span>
<span>3</span>
</div>
</div>
<div className="profile_leftLoc">
<span>< LocationOnIcon fontSize="small" /></span>
<span>India</span>
</div>
</div>
<div className="profile__right">
<div className="profile__rightupper">
<Underlinenav/>
</div>
{template}
</div>
</div>
)
}
export default Profile
I used the prop named template for routing the component in profile.js to toggle between components inside the body. But I think, It is not working as expected,
I want the component of Overview.js on path http://localhost:3000/ and Repo.js on http://localhost:3000/tagname=Repo
Use render attribute and a middleware function to return correct component
<Route
path="/"
render={({location}) => {
const template = checkYourRoute(location) ? Overview : Repo;
return <Profile template={template} />
}
}
>
I'm trying to properly render my different components with the HTML/CSS sidebar with React Routes and Apollo.
I have a sidebar that correctly renders to the left of the screen and a little navbar on top of it, the space for the component is not being blocked by any css property.
The expected output is:
The actual output:
I've tried to place all the Routes inside the sidebar but every time I click on them, they don't load at all, the URL changes but the content doesn't and I need to reload the webpage for it take some effect. The help would be very much appreciated.
App.js
import React from 'react';
import ApolloClient from 'apollo-boost';
import {ApolloProvider} from '#apollo/react-hooks';
import { render } from 'react-dom';
import {BrowserRouter as Router, Route, Link,Switch} from 'react-router-dom';
import 'bootswatch/dist/flatly/bootstrap.min.css';
import Nav from './components/Nav'
import Home from './components/pages/Home'
import About from './components/pages/About'
import Articles from './components/article/Articles'
import Article from './components/article/Article'
const client = new ApolloClient({
uri: 'url in here'
});
const App = () => {
return (
<ApolloProvider client={client}>
<Router>
<div className="App">
<Nav/>
<Route exact path='/' component={Home} />
<Route exact path='/Articles' component={Articles} />
<Route exact path='/Articles/:id' component={Article} />
<Route exact path='/About' component={About} />
</div>
</Router>
</ApolloProvider>
);
}
render(<App />, document.getElementById('root'));
export default App;
Nav.js component
import React from 'react';
import {BrowserRouter as Link} from 'react-router-dom';
export default function Nav() {
return (
<div className="wrapper">
<nav id="sidebar">
<Link className="nav-link" to="/">
<h3>Home</h3>
</Link>
.
.
.
</nav>
<div id="content">
<nav className="navBar" >
</nav>
<div className ="ComponentRender">
Here's where the component should be rendered
</div>
</div>
</div>
)
}
I don't know about Apollo but I think you should move your routes from the App component to the Nav component, so the code would be:
App component:
const App = () => {
return (
<ApolloProvider client={client}>
<Router>
<div className="App">
<Nav/>
</div>
</Router>
</ApolloProvider>
);
}
And the Nav component:
export default function Nav() {
return (
<div className="wrapper">
<nav id="sidebar">
<Link className="nav-link" to="/">
<h3>Home</h3>
</Link>
.
.
.
</nav>
<div id="content">
<nav className="navBar" >
</nav>
<div className ="ComponentRender">
<Route exact path='/' component={Home} />
<Route exact path='/Articles' component={Articles} />
<Route exact path='/Articles/:id' component={Article} />
<Route exact path='/About' component={About} />
</div>
</div>
</div>
)
}
Don't forget to move imports from App to Nav as well.