Home > OS >  How to create a new page with a component in React?
How to create a new page with a component in React?

Time:11-24

I currently have a single page in my React app that renders all the components on one page. I would like to have a button open a new component that takes up the whole page, almost like opening a new site.

Is there a way I could do this? Below is my code.

App.js:

import { Route, Routes } from 'react-router-dom';
import './App.css';
import Navbar from './components/Navbar';
import Homepage from './components/Homepage';
import About from './components/About';
import Skills from './components/Skills';
import Projects from './components/Projects';
import ContactMe from './components/ContactMe';
import Contact from './components/Contact';

function App() {

  return (
    <>
    <Navbar />
      <div className='homepage-container-web'>
          <Homepage />
          <About />
          <Skills />
          <Projects />
          <ContactMe />
      </div>
    <div className='homepage-container-devices'>
      <Routes>
        <Route path='/' element={<Homepage />} />
        <Route path='/about' element={<About />}/>
        <Route path='/projects' element={<Projects />}/>
        <Route path='/contact' element={<ContactMe />}/>
      </Routes>
    </div>
    </>
  );
}

export default App;

ContactMe.jsx:

import '../App.css';
import { ReactComponent as LinkedInLogo } from '../images/linkedin.svg';

function ContactMe() {
    
    return(
        <>
        <div className='contact-container' id='contactMe'>
            <div className='contact-box'>
                <h1>Want to connect?</h1>
                <button id='contact-me-btn'>Contact Me </button>
                <a>
                    <LinkedInLogo title='LinkedIn Profile' id='linkedinprofile-svg'/>
                </a>
            </div>
            <div className='contact-container-footer'>
                <h7>Designed and built by <a href='https://github.com/BlazingIsFire' target='_blank' title='Github'>Andrew Schweitzer</a>.</h7>
            </div>
        </div>
        </>
    )   
}

export default ContactMe;

I would like the <button>Contact me!</button in ContactMe.jsx to open a new component / page that's named <Contact />. I want the Contact page to take up the entire page.

Any help is appreciated!!

CodePudding user response:

To render a page component, you need to use a Router from the react-router-dom library.

Your App component should be like this:

function App() {

  return (
    // Add an import for this
    <BrowserRouter>
      <Navbar />
      <div className='homepage-container-web'>
        <Routes>
          <Route path='/' element={<Homepage />} />
          <Route path='/about' element={<About />}/>
          <Route path='/projects' element={<Projects />}/>
          <Route path='/contact-me' element={<ContactMe />}/>
          // This was missing
          <Route path='/contact' element={<Contact />}/>
        </Routes>
      </div>
    </BrowserRouter>
  );
}

This will make the entire content of your page be one of the components assigned to the element props for the Route components. That is, when the URL is /about, you will see the About component, when it is /projects, you will see the Projects component etc.

To navigate to the Contact component on the button click, you need this:

function ContactMe() {
  // Use useNavigate hook
  const navigate = useNavigate();

  return (
    <div className="contact-container" id="contactMe">
      <div className="contact-box">
        <h1>Want to connect?</h1>
        // Navigate to /contact-me on click
        <button id="contact-me-btn" onClick={() => navigate("/contact-me")}>
          Contact Me{" "}
        </button>
        <a>
          <LinkedInLogo title="LinkedIn Profile" id="linkedinprofile-svg" />
        </a>
      </div>
      <div className="contact-container-footer">
        <h7>
          Designed and built by{" "}
          <a
            href="https://github.com/BlazingIsFire"
            target="_blank"
            title="Github"
          >
            Andrew Schweitzer
          </a>
          .
        </h7>
      </div>
    </div>
  );
}

CodePudding user response:

Yes, as shown below, you can have nested routes or individual routes. Error and connect are separate routes, whereas the other routes are layered.

index.js


    import ReactDOM from "react-dom/client";
    import { BrowserRouter, Routes, Route } from "react-router-dom";
    import Layout from "./Layout";
    import Home from "./Home";
    import About from "./About";
    import Contact from "./Contact";
    import Connect from "./Connect";
    import Error from "./Error";
    
    export default function App() {
      return (
        <BrowserRouter>
          <Routes>
            <Route path="/" element={<Layout />}>
              <Route index element={<Home />} />
              <Route path="about" element={<About />} />
              <Route path="contact" element={<Contact />} />
            </Route>
            <Route path="/connect" element={<Connect />} />
            <Route path="*" element={<Error />} />
          </Routes>
        </BrowserRouter>
      );
    }
    
    const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(<App />);

Layout.js


    import { Outlet, Link } from "react-router-dom";
    
    const Layout = () => {
      return (
        <>
          <nav>
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
              <li>
                <Link to="/about">About</Link>
              </li>
              <li>
                <Link to="/contact">Contact</Link>
              </li>
            </ul>
          </nav>
          <Outlet />
        </>
      );
    };
    
    export default Layout;

Home.js


    const Home = () => {
      return <h1>Home</h1>;
    };
    
    export default Home;

About.js


    const About = () => {
      return <h1>About Page</h1>;
    };
    
    export default About;

Contact.js


    import { Link } from "react-router-dom";
    
    const Contact = () => {
      return (
        <div>
          <h1>Contact Me</h1>
          <Link to="/connect">Try & Reach Me!</Link>
        </div>
      );
    };
    
    export default Contact;

Connect.js


    const Connect = () => {
      return <h1>Connected to me!</h1>;
    };
    
    export default Connect;

Error.js


    import { Link } from "react-router-dom";
    
    const NoPage = () => {
      return (
        <div>
          <h1>404 No Page Found!</h1>
          <Link to="/">Go Home</Link>
        </div>
      );
    };
    
    export default NoPage;

Hope this helps.

CodePudding user response:

There are several methods you can achieve that. I would use the Link Tag from react-router-dom, but I will list three examples here anyway. Starting with the first one, the simplest one, without using a library like react-router-dom.

  1. Embed the Button code in an anchor tag and pass the URL you want to redirect as a prop to the ContactMe component.

Example:

    function ContactMe({contact}) {
    
    return(
    ................
    
    <a href={`/${contact}`}>
    <button id='contact-me-btn'>
    Click to redirect to {contact === '' ? "home" : contact}
    </button>
    </a>
    )
    }
  1. You can use useNavigate() hook from react-router-dom
const navigate = useNavigate();
navigate("/nameofpage");

Example:

import { useNavigate } from "react-router-dom";

function ContactMe({contact}) {

const navigate = useNavigate();
    
    return(
    ................
    
    
    <button className="my-button" onClick={() => { navigate(`/${contact}`) }}>
        Click to redirect to {contact === '' ? "home" : contact}
     </button>
    
    )
    }
  1. You can use the Link Tag from react-router-dom, which I mentioned since at the beginning.

Example:

<Link to="nameofpage"> Element </Link>
import { Link } from "react-router-dom";

function ContactMe({contact}) {
    
    return(
    ................
    
    <Link to={`/${contact}`}>
    <button id='contact-me-btn'>
    Click to redirect to {contact === '' ? "home" : contact}
    </button>
     </Link>
    )
    }

I hope it helps.

  • Related