根据条件显示反应组件

时间:2021-07-17 16:57:55

标签: reactjs react-router

在我的 React 应用程序中,我有一个导航栏组件,它显示在每条路线中。但我想根据应用程序显示的 URL 或当前组件显示不同的导航栏。例如,当路由器点击 /user URL 时,我想隐藏当前的 NavbarTop.js 组件并显示 NavbarUser.js。我将 <NavbarUser/> 放在 User 组件的顶部,但它同时显示了导航栏。我也尝试使用 useState 和 useEffect 但它不起作用。默认导航栏会在应用的任何地方呈现。

app.js

import "./App.css";
import { Button, Pagination } from "react-bootstrap";
import Gallery from "./Gallery";
import "bootstrap/dist/css/bootstrap.min.css";
import Artists from "./Artists";
import Auctions from "./Auctions";
import Footer from "./Footer";
import NavbarTop from "./NavbarTop";
import Wallet from "./Wallet";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Items from "./Items";
import User from "./User";

function App() {
  return (
    <Router>
      <div className="App">
        {/* Navbar */}
        <NavbarTop />
        {/* Router  */}
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/wallet" component={Wallet} />
          <Route path="/items" component={Items} />
          <Route path="/user" component={User} />
        </Switch>

        {/* Footer */}
        <Footer />
      </div>
    </Router>
  );
}

NavbarTop.js

import React, { useState, useEffect } from "react";
import { Nav, Navbar, Button, Modal, Form } from "react-bootstrap";
import { Link } from "react-router-dom";
import "./NavbarTop.css";

function NavbarTop() {
  const [showLogin, setShowLogin] = useState(false);
  const [showSignup, setShowSignup] = useState(false);

  //handler for login
  const handleCloseLogin = () => setShowLogin(false);
  const handleShowLogin = () => setShowLogin(true);

  //handler for signup
  const handleCloseSignup = () => setShowSignup(false);
  const handleShowSignup = () => setShowSignup(true);

  const walletUrl = "/wallet";
  let currentPath = window.location.pathname;
  const [hide, setHide] = useState(false);

  useEffect(() => {
    if (currentPath === walletUrl) {
      setHide(true);
    } else {
      setHide(false);
    }
  }, [currentPath]);

  return (
    <Navbar className="navBar" variant="dark" expand="lg" sticky="top">
      <Navbar.Brand>
        <Link to="/">
          <img src="images/logo.png" alt="playtoshi" className="logo" />
        </Link>
      </Navbar.Brand>
      <Navbar.Toggle aria-controls="basic-navbar-nav" />
      <Navbar.Collapse id="basic-navbar-nav">
        <Nav className="ml-auto mr-md-3">
          <Nav.Link href="#home">MARKETPLACE</Nav.Link>
          <Nav.Link href="#link">COMMUNITY</Nav.Link>
          <Nav.Link href="#link" className="mr-md-2">
            HELP
          </Nav.Link>
          {!hide ? (
            <Link to="/wallet">
              <Button variant="outline-warning"> Connect your wallet </Button>
            </Link>
          ) : null}
        </Nav>
        <Button
          variant="outline-primary"
          className="mr-sm-2"
          onClick={handleShowLogin}
        >
          Login
        </Button>{" "}
        <Button variant="outline-success" onClick={handleShowSignup}>
          Sign Up
        </Button>{" "}
      </Navbar.Collapse>

      {/* Login Modal */}
      <Modal show={showLogin} onHide={handleCloseLogin} animation={false}>
        <Modal.Header closeButton>
          <Modal.Title>Login</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          <Form>
            <Form.Group controlId="formBasicEmail">
              <Form.Label>Email address</Form.Label>
              <Form.Control type="email" placeholder="Enter email" required />
              <Form.Text className="text-muted">
                We'll never share your email with anyone else.
              </Form.Text>
            </Form.Group>

            <Form.Group controlId="formBasicPassword">
              <Form.Label>Password</Form.Label>
              <Form.Control type="password" placeholder="Password" required />
            </Form.Group>
            <Form.Group controlId="formBasicCheckbox">
              <Form.Check type="checkbox" label="Check me out" />
            </Form.Group>
            <Link to="/user">
              <Button
                variant="primary"
                type="submit"
                onClick={handleCloseLogin}
              >
                Login
              </Button>
            </Link>
          </Form>
        </Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={handleCloseLogin}>
            Close
          </Button>
        </Modal.Footer>
      </Modal>

      {/* Signup modal */}
      <Modal show={showSignup} onHide={handleCloseSignup} animation={false}>
        <Modal.Header closeButton>
          <Modal.Title>Signup</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          <Form>
            <Form.Group>
              <Form.Label>Enter Your Name</Form.Label>
              <Form.Control
                type="text"
                placeholder="First Name"
                required
                className="mb-sm-2"
              />
              <Form.Control type="text" placeholder="Last Name" required />
            </Form.Group>

            <Form.Group controlId="formBasicEmail">
              <Form.Label>Email address</Form.Label>
              <Form.Control type="email" placeholder="Enter email" required />
              <Form.Text className="text-muted">
                We'll never share your email with anyone else.
              </Form.Text>
            </Form.Group>

            <Form.Group controlId="formBasicPassword">
              <Form.Label>Password</Form.Label>
              <Form.Control type="password" placeholder="Password" required />
            </Form.Group>

            <Form.Group controlId="formBasicPassword">
              <Form.Label>Password</Form.Label>
              <Form.Control
                type="password"
                placeholder="Retype Password"
                required
              />
            </Form.Group>

            <Form.Group controlId="formBasicCheckbox">
              <Form.Check
                type="checkbox"
                label="I Agree the terms and conditions"
              />
            </Form.Group>
            <Button variant="primary" type="submit">
              Submit
            </Button>
          </Form>
        </Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={handleCloseSignup}>
            Close
          </Button>
        </Modal.Footer>
      </Modal>
    </Navbar>
  );
}

export default NavbarTop;

NavbarUser.js

import React from "react";
import { Nav, Navbar, Button } from "react-bootstrap";
import { Link } from "react-router-dom";

function NavbarUser() {
  return (
    <div>
      <Navbar className="navBar" variant="dark" expand="lg" sticky="top">
        <Navbar.Brand>
          <Link to="/">
            <img src="images/logo.png" alt="playtoshi" className="logo" />
          </Link>
        </Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
          <Nav className="ml-auto mr-md-3">
            <Nav.Link href="#home">Explore</Nav.Link>
            <Nav.Link href="#link">My Items</Nav.Link>
            <Nav.Link href="#link">Following</Nav.Link>
            <Nav.Link href="#link">Activity</Nav.Link>
            <Button variant="outline-primary" className="mr-sm-2">
              Create NFT
            </Button>
            <div className="balance">
              <img src="" alt="coin" />
              <p>13,412 BNB</p>
            </div>
          </Nav>
        </Navbar.Collapse>
      </Navbar>
    </div>
  );
}

export default NavbarUser;

User.js

import React from "react";
import { Button, Tab, Tabs, Badge } from "react-bootstrap";
import "./User.css";
import Auctions from "./Auctions";
// import NavbarUser from "./NavbarUser";

function User() {
  return (
    <div>
      {/* <NavbarUser /> */}
      <div className="user-parent">
        <div className="user-header">
          <div className="user-info">
            <img src="./images/user2.jpg" alt="user" />
            <h3>Jerome Bell</h3>
            <div className="account-number">
              <p>0xf423442442114...1231</p>
              <Button>
                <img
                  src="https://img.icons8.com/dusk/64/000000/copy.png"
                  alt="copy"
                />
              </Button>
            </div>
            <div className="user-desc">
              <p>
                Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro,
                expedita hic repellendus, laborum doloribus voluptas
                perspiciatis recusandae nemo quod incidunt, sapiente debitis
                dignissimos amet unde.
              </p>
            </div>

            <div className="socials">
              <div className="twitter">
                <img
                  src="https://img.icons8.com/bubbles/100/000000/twitter.png"
                  alt="twitter"
                />
                <p>@jeromebell</p>
              </div>
              <div className="facebook">
                <img
                  src="https://img.icons8.com/bubbles/100/000000/facebook.png"
                  alt="facebook"
                />
                <p>facebook.com/jerome</p>
              </div>
            </div>
            <div className="buttons">
              <Button className="edit-profile">Edit Profile</Button>
              <Button className="upload-button">
                <img
                  src="https://img.icons8.com/fluent-systems-filled/48/000000/upload.png"
                  alt="upload"
                />
              </Button>
            </div>
          </div>
          <div className="user-productImg">
            <img src="./images/art11.jpg" alt="arts" />
          </div>
        </div>
        <div className="owned">
          <Tabs defaultActiveKey="onsale" className="mb-3">
            <Tab
              eventKey="onsale"
              title={
                <React.Fragment>
                  On sale
                  <Badge variant="light" className="ml-1">
                    8
                  </Badge>
                </React.Fragment>
              }
            >
              <Owned />
            </Tab>
            <Tab
              eventKey="owned"
              title={
                <React.Fragment>
                  Owned
                  <Badge variant="light" className="ml-1">
                    15
                  </Badge>
                </React.Fragment>
              }
            >
              <Owned />
            </Tab>
            <Tab
              eventKey="created"
              title={
                <React.Fragment>
                  Created
                  <Badge variant="light" className="ml-1">
                    19
                  </Badge>
                </React.Fragment>
              }
            >
              <Owned />
            </Tab>
            <Tab
              eventKey="liked"
              title={
                <React.Fragment>
                  Liked
                  <Badge variant="light" className="ml-1">
                    59
                  </Badge>
                </React.Fragment>
              }
            >
              <Owned />
            </Tab>
            <Tab
              eventKey="follower"
              title={
                <React.Fragment>
                  Follower
                  <Badge variant="light" className="ml-1">
                    8k
                  </Badge>
                </React.Fragment>
              }
            >
              <Owned />
            </Tab>
            <Tab
              eventKey="following"
              title={
                <React.Fragment>
                  Followingg
                  <Badge variant="light" className="ml-1">
                    7.9k
                  </Badge>
                </React.Fragment>
              }
            >
              <owned />
            </Tab>
          </Tabs>
        </div>
      </div>
    </div>
  );
}

const Owned = () => (
  <div>
    <div className="img-gallery">
      <Auctions
        image="./images/art5.jpg"
        time="3hr 47min left"
        user="Bored Elon"
        product="Digital Art"
        avatar="./images/user2.jpg"
        price="1.07 BNB"
        hide="true"
      />
      <Auctions
        image="./images/art8.jpg"
        time="3hr 47min left"
        user="Bored Elon"
        product="Digital Art"
        avatar="./images/user4.jpg"
        price="2.07 BNB"
        hide="true"
      />
      <Auctions
        image="./images/art5.jpg"
        time="3hr 47min left"
        user="Bored Elon"
        product="Digital Art"
        avatar="./images/user3.jpg"
        price="3.07 BNB"
        hide="true"
      />
      <Auctions
        image="./images/art8.jpg"
        time="3hr 47min left"
        user="Bored Elon"
        product="Digital Art"
        avatar="./images/user7.jpg"
        price="4.07 BNB"
        hide="true"
      />
      <Auctions
        image="./images/art5.jpg"
        time="3hr 47min left"
        user="Bored Elon"
        product="Digital Art"
        avatar="./images/user2.jpg"
        price="1.07 BNB"
        hide="true"
      />
      <Auctions
        image="./images/art8.jpg"
        time="3hr 47min left"
        user="Bored Elon"
        product="Digital Art"
        avatar="./images/user4.jpg"
        price="2.07 BNB"
        hide="true"
      />
      <Auctions
        image="./images/art5.jpg"
        time="3hr 47min left"
        user="Bored Elon"
        product="Digital Art"
        avatar="./images/user3.jpg"
        price="3.07 BNB"
        hide="true"
      />
      <Auctions
        image="./images/art8.jpg"
        time="3hr 47min left"
        user="Bored Elon"
        product="Digital Art"
        avatar="./images/user7.jpg"
        price="4.07 BNB"
        hide="true"
      />
    </div>
  </div>
);

export default User;

1 个答案:

答案 0 :(得分:1)

一个更简单、更干净的解决方案是从 NavBarTop.js 中删除基于路径名显示/隐藏的 useEffect 钩子。

并在您的 app.js 或路由器组件中添加以下逻辑。

import { useLocation } from 'react-router-dom';
import { useEffect, useState } from 'react';

function App() { 
const [activeUrl, setActiveUrl] = useState<string>('');
const appLocation = useLocation();

useEffect(() => {
    setActiveUrl(window.location.pathname);
  }, [appLocation]);

return (
    <Router>
      <div className="App">
        {/* Navbar */}
        {activeUrl === '/wallet' ? <NavbarTop /> : <NavbarUser />}
        {/* Router  */}

      </div>
    </Router>
  );
}