I am creating a project using React and ant design. I have created the navbar but it is not getting rendered properly. I am able to select an option but I cannot deselect it (like shown in the image, the project is in the initial stage so everything is a little misaligned). You can view the site here: http://192.168.56.1:3000/ .I am providing the code for app.js and navbar.jsx
App.js:
const App = () => {
return (
<div className="app">
<div className="navbar">
<Navbar />
</div>
<div className="main">
<Layout>
<div className="routes">
<Switch>
<Route exact path="/">
<Homepage />
</Route>
<Route exact path="/cryptocurrencies">
<Cryptocurrencies />
</Route>
<Route exact path="/exchanges">
<Exchanges />
</Route>
<Route exact path="/news">
<News />
</Route>
<Route exact path="/crypto/:coinId">
<CryptoDetails />
</Route>
</Switch>
</div>
</Layout>
<div className="footer">
<Typography.Title level={5} style={{ color: 'white', textAlign: 'center' }}>
Krypton <br />
All rights reserved
</Typography.Title>
<Space>
<Link to="/">Home</Link>
<Link to="/exchanges">Exchanges</Link>
<Link to="/news">News</Link>
</Space>
</div>
</div>
</div>
);
}
Navbar.jsx:
const Navbar = () => {
return (
<div className="nav-container">
<div className="logo-container">
<Avatar src={icon} size="large" />
<Typography.Title level={2} className="logo">
<Link to="/">Krypton</Link>
</Typography.Title>
{/* <Button className="menu-control-container">
</Button> */}
</div>
<Menu theme="dark">
<Menu.Item icon={<HomeOutlined />}>
<Link to="/">Home</Link>
</Menu.Item>
</Menu>
<Menu theme="dark">
<Menu.Item icon={<FundOutlined />}>
<Link to="/cryptocurrencies">Cryptocurrencies</Link>
</Menu.Item>
</Menu>
<Menu theme="dark">
<Menu.Item icon={<MoneyCollectOutlined />}>
<Link to="/exchanges">Exchanges</Link>
</Menu.Item>
</Menu>
<Menu theme="dark">
<Menu.Item icon={<BulbOutlined />}>
<Link to="/news">News</Link>
</Menu.Item>
</Menu>
</div>
);
}
Related
I'm working on react website and I have a problem while navigating to any page
that when I scroll to a certain point in a home page for example then I try to navigate to another page I find the other page is rendered from the the bottom of the page not the top
routes.tsx file
const App: React.FC = () => (
<BrowserRouter>
<Layout className="layout">
<div style={{ marginBottom: "64px" }}>
<Header>
<AppHeader />
</Header>
</div>
<Content>
<div className="site-layout-content">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/offers" element={<Login />} />
<Route path="/aboutUs" element={<AboutUs />} />
<Route path="/contactUs" element={<ContactUs />} />
<Route path="/placeDetails/:id" element={<PlaceDetails />} />
<Route path="/advantages" element={<Advantages />} />
</Routes>
</div>
</Content>
<Footer style={{ textAlign: "center" }}>
<AppFooter />
</Footer>
</Layout>
</BrowserRouter>
);
export default App;
header.tsx
const Index = () => {
const navigate = useNavigate();
return (
<Row className="header">
<Col span={12} className="header__logo">
<div className="header__logo--imgContainer" onClick={() => navigate("/")}>
<img src={logoImg} alt="logo" />
</div>
</Col>
<Col span={12} className="header__menu">
<ul className="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light ant-menu-rtl">
<li className="ant-menu-item">
<span onClick={() => navigate("/offers")}>{strings.header.offers}</span>
</li>
<li className="ant-menu-item">
<span onClick={() => navigate("/advantages")}>{strings.header.services}</span>
</li>
</ul>
</Col>
</Row>
);
};
export default Index;
you can simply use this helper component for this use case:
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
export default function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
// "document.documentElement.scrollTo" is the magic for React Router Dom v6
document.documentElement.scrollTo({
top: 0,
left: 0,
behavior: "instant", // Optional if you want to skip the scrolling animation
});
}, [pathname]);
return null;
}
and then you can change above code like this:
const App: React.FC = () => (
<BrowserRouter>
<ScrollToTop/> // this is new helper component
<Layout className="layout">
<div style={{ marginBottom: "64px" }}>
<Header>
<AppHeader />
</Header>
</div>
<Content>
<div className="site-layout-content">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/offers" element={<Login />} />
<Route path="/aboutUs" element={<AboutUs />} />
<Route path="/contactUs" element={<ContactUs />} />
<Route path="/placeDetails/:id" element={<PlaceDetails />} />
<Route path="/advantages" element={<Advantages />} />
</Routes>
</div>
</Content>
<Footer style={{ textAlign: "center" }}>
<AppFooter />
</Footer>
</Layout>
</BrowserRouter>
);
export default App;
This will reset the scroll position on top whenever route changes.
I have a homepage where I need the links for the different pages.
<li>
The tabs are located here - <Link to="/demo">Demo</Link>
</li>
<li>
<Link to="/page1">Page1</Link>
</li>
<li>
<Link to="/page2">Pge2</Link>
</li>
<li>
<Link to="/page3">Pge3</Link>
</li>
Under the Demo page are the tabs as well. I manage to keep the page on the current tab even though it was refreshed. However, my problem now is that on my homepage, if I'll click on the link for the Pge2 or for the other pages, it shows nothing. It does not load the Page 2. I wanted to show just the page when I click on it, without the tabs.
codesandbox: https://codesandbox.io/s/basictabs-demo-useparamas-7ockf0?file=/Homepage.js:342-402
Routes
<Routes>
<Route path="/" element={<Homepage />} />
<Route path="demo" element={<Demo />}>
<Route path=":page1" element={<Page1 />} />
<Route path=":page2" element={<Page2 />} />
<Route path=":page3" element={<Page3 />} />
</Route>
{/* <Route path="/page2" element={<Page2 />} />
<Route path="/page3" element={<Page3 />} /> */}
</Routes>
Demo.js
export default function BasicTabs() {
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
useEffect(() => {
let path = window.location.pathname;
console.log(path);
if (path === "/demo/page1" && value !== 0) setValue(0);
else if (path === "/demo/page2" && value !== 1) setValue(1);
else if (path === "/demo/page3" && value !== 2) setValue(2);
}, [value]);
return (
<Box sx={{ width: "100%" }}>
<li>
<Link to="/">Homepage</Link>
</li>
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
<h1>Some text here</h1>
<Tabs
value={value}
onChange={handleChange}
aria-label="basic tabs example"
>
<Tab
label="Item One"
{...a11yProps(0)}
to="/demo/page1"
component={Link}
/>
<Tab
label="Item Two"
{...a11yProps(1)}
to="/demo/page2"
component={Link}
/>
<Tab
label="Item Three"
{...a11yProps(2)}
to="/demo/page3"
component={Link}
/>
</Tabs>
</Box>
{value === 0 && (
<TabPanel value={value} index={0}>
<Page1 />
</TabPanel>
)}
{value === 1 && (
<TabPanel value={value} index={1}>
<Page2 />
</TabPanel>
)}
{value === 2 && (
<TabPanel value={value} index={2}>
<Page3 />
</TabPanel>
)}
</Box>
);
}
I'd updated your sandbox. The problem is in the route definition. I will rewrite here (this will produce routes like example.com/demo example.com/page1 as you are using in your tabs):
<Routes>
<Route path="/">
<Route index element={<Homepage />}/>
<Route path="demo" element={<Demo />}/>
<Route path=":page1" element={<Page1 />} />
<Route path=":page2" element={<Page2 />} />
<Route path=":page3" element={<Page3 />} />
</Route>
</Routes>
Explanation: you defined your route as descendants of 'demo', so your path will look like: example.com/demo/page1 while you wanted to be example.com/page1
If you are intending to use your routes as example.com/demo/page1 then leave your path definition unmodified and instead update your App component and add to your tabs: demo/page1 and so on
<Link to="/demo/page1">Page1</Link>
If you want the user to navigate from your Homepage component to other Pages then you need to add new routes to your app.js
<Routes>
<Route path="/" element={<Homepage />} />
<Route path="demo" element={<Demo />}>
<Route path=":page1" element={<Page1 />} />
<Route path=":page2" element={<Page2 />} />
<Route path=":page3" element={<Page3 />} />
</Route>
<Route path="/page1" element={<Page1 />} />
<Route path="/page2" element={<Page2 />} />
<Route path="/page3" element={<Page3 />} />
</Routes>
This won't break the routes inside Demo page and if you want different content to be displayed then you can create new components and provide them as a value for element prop
Here I'm fetching the data from the API and storing it into state to show it on screen. Here is details.js
<div className="h2 mt-4">More Like This</div>
<div class="container-fluid overflow-auto">
<div class="row flex-row flex-nowrap">
{SimilarMovies && SimilarMovies.map((similarmovie, index) => (
<React.Fragment key={index}>
<GridCard
image={similarmovie.poster_path && `${IMAGE_URL}w500${similarmovie.poster_path}`}
similarMovieId={similarmovie.id} movieTitle={similarmovie.title} name={similarmovie.original_title}
/> {/*this will go to else part of gridcard */}
</React.Fragment>
))}
</div>
</div>
{/* actor button */}
<div className="text-center mt-2">
<button className="btn btn-primary" onClick={handleClick}> View Actors</button>
</div>
{/* actors grid */}
{ActorToggle &&
<Row>
{Crews && Crews.map((crew, index) => (
<React.Fragment key={index}>
{crew.profile_path &&
<GridCard
actor={crew.name} character={crew.character} image={`${IMAGE_URL}original${crew.profile_path}`}
/>}
</React.Fragment>
))}
</Row>}
in this code <Gridcard> which appears first is having problem, data displayed Link is not working but it changes in url so if I refresh the page, I'll go to that page. The another <Gridcard> below is working fine.
here is Gridcard.js
import React from 'react';
import { Link } from 'react-router-dom';
import { Col } from 'reactstrap';
function GridCard(props) {
if(props.actor) {
return(
<Col lg={3} md={4} sm={6} xs={6} className="mb-3 mt-3">
<div>
<img className="card card-img border-0" style={{ width: '100%', height: '300px' }} alt="img" src={props.image} />
<div className="text-center text-dark font-weight-bold card-footer">
<div>{props.actor} as {props.character}</div>
</div>
</div>
</Col>
)
}
else if(props.movieId) {
return(
<Col lg={3} md={4} sm={6} xs={6} className="mb-3">
<div>
<Link to={`/movie/${props.movieId}`} className="text-decoration-none">
<img className="card border-0" style={{ width: '100%', height: '330px' }} alt="img" src={props.image} />
</Link>
</div>
</Col>
)
}
else {
return(
<Col lg={3} md={4} sm={6} xs={6} className="mb-3">
<div>
<Link to={`/movie/${props.similarMovieId}`} className="text-decoration-none">
<img className="card border-0" style={{ width: '100%', height: '330px' }} alt="img" src={props.image} />
</Link> {/*this one is not working*/}
</div>
</Col>
)
}
}
export default GridCard;
here is my Main.js in case you need it
const LoginContainer = () => (
<div>
<Route path="/login" component={Signin} />
</div>
);
const SignupContainer = () => (
<div>
<Route path="/signup" component={Signup} />
</div>
);
const DefaultContainer = () => (
<div>
<Header />
<Switch>
<Route exact path='/' component={Home} />
<SecuredRoute path='/profile' component={Profile} />
<SecuredRoute exact path='/movie/:Id' component={MovieDetail} />
<SecuredRoute path='/movies' component={LandingPage} />
<Route path='/search' component={SearchBox} />
<SecuredRoute path='/tv/:Id' component={TvDetail} />
<SecuredRoute path='/tv' component={TvLandingPage} />
<Redirect to={Home} />
</Switch>
</div>
);
class Main extends Component {
render() {
return(
<div>
<Switch>
<Route exact path="/login" component={LoginContainer}/>
<Route exact path="/signup" component={SignupContainer}/>
<Route component={DefaultContainer}/>
</Switch>
<Footer />
</div>
);
}
}
export default Main;
Not really sure I'm doing wrong here. I have a header component which I am then using in my main app component where my "page" components are conditionally rendered based on the app. Manually going to the routes works, however React Router's Link component is not rendering the links as clickable buttons thus I can't click on anything...
Here is my header component:
function Header(props) {
const links = props.links.map(link => {
return (
<Link to={{pathname: link.path}} key={link.title}>{link.title}</Link>
);
});
return(
<Navbar className="border-bottom" bg="transparent" expand="lg">
<Navbar.Brand href="#home">Garrett Love</Navbar.Brand>
<Navbar.Toggle className="border-0" aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="ml-auto">
{links}
</Nav>
</Navbar.Collapse>
</Navbar>
);
}
I did try setting the to prop as both to={link.path} and to="/about" but neither worked.
I'm just putting this component in my main app component like so:
render() {
return(
<Router>
<Container className="p-0" fluid={true}>
<Header links={this.state.headerLinks} />
<Route path="/" exact render={() => <Home title={this.state.home.title} subTitle={this.state.home.subTitle} />} />
<Route path="/about" render={() => <About title={this.state.about.title} />} />
<Footer />
</Container>
</Router>
);
}
I see you has header component and some app component
But in your app component you show <Gbar /> and dont show <Header />
The best way to fix this:
In Header
const Header = props =>
<Navbar className="border-bottom" bg="transparent" expand="lg">
<Navbar.Brand href="#home">Garrett Love</Navbar.Brand>
<Navbar.Toggle className="border-0" aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="ml-auto">
{props.links.map(link => <Link to={link.path} key={link.title}>{link.title}</Link>)}
</Nav>
</Navbar.Collapse>
</Navbar>
And in App:
render() {
return(
<Router>
<Container className="p-0" fluid={true}>
<Header links={this.state.headerLinks} />
<Route path="/" exact render={() => <Home title={this.state.home.title} subTitle={this.state.home.subTitle} />} />
<Route path="/about" render={() => <About title={this.state.about.title} />} />
<Footer />
</Container>
</Router>
);
}
I am new to ReactJS and have an issue with using "Menu.Item" (from Semantic UI React) and React Router.
My imports etc will be left out of the below code but they are all working fine.
My "App.jsx" constructor is as follows:
constructor(props) {
super(props);
this.state = {
activeItem: 'home',
loading: true,
messages: [],
};
}
The "App.jsx" render return is this:
<Router>
<Container className="main">
<Navbar
onItemClick={selected => this.setState({ activeItem: selected })}
isActive={this.state.activeItem}
/>
<Container className="main-content">
<Switch>
<Route exact path="/" component={Home} />
<Route path="/dashboard" component={Dashboard} />
<Route path="/user" component={User} />
</Switch>
</Container>
</Container>
</Router>
For clarification, the Home, User, and Dashboard components are just simple Div's that has their respective names in them.
My Navbar is as follows:
class Navbar extends Component {
onItemChange = (e, { name }) => this.props.onItemClick(name);
render() {
return (
<div>
<Container>
<Menu secondary stackable widths={4}>
<Menu.Item>
<img src={Logo} alt="header" />
</Menu.Item>
<Menu.Item
as={NavLink}
to="/"
name="home"
active={this.props.isActive === 'home'}
onClick={(event, name) => this.handleClick(name.name, name.to)}
>
<Icon name="home" size="large" />
<p>Home</p>
</Menu.Item>
<Menu.Item
as={NavLink}
to="/dashboard"
name="Data"
active={this.props.isActive === 'Data'}
onClick={this.onItemChange}
>
<Icon name="dashboard" size="large" />
<p>Dashboard</p>
</Menu.Item>
<Menu.Item
as={NavLink}
to="/user"
name="user"
active={this.props.isActive === 'user'}
onClick={this.onItemChange}
>
<Icon name="user" size="large" />
<p>User</p>
</Menu.Item>
</Menu>
</Container>
</div>
);
}
}
As you can see from the above Navbar, I am using NavLink within the Menu.Item.
Here is where the issue arises. When I start my application it works fine, 'home' is displayed, however when I click on a link in the Menu, the application crashes.
Any ideas on how to fix this? I also want to have it that the 'isActive' will update with the current route in the menu.
Any input would be greatly appreciated.
I fixed it for anyone looking into it by simplifying the code, here is the Navbar component:
const Navbar = () => (
<div>
<Container>
<Menu secondary stackable widths={4}>
<Menu.Item>
<img src={Logo} alt="header" />
</Menu.Item>
<Menu.Item as={NavLink} to="/" name="home">
<Icon name="home" size="large" />
<p>Home</p>
</Menu.Item>
<Menu.Item as={NavLink} to="/data" name="data">
<Icon name="dashboard" size="large" />
<p>Dashboard</p>
</Menu.Item>
<Menu.Item as={NavLink} to="/user" name="user">
<Icon name="user" size="large" />
<p>User</p>
</Menu.Item>
</Menu>
</Container>
</div>
);
Less does more, it seems. Hope this helps anyone.