简体   繁体   中英

Is there some way I can convert href tag to Link on React.js?

Thank you for opening this page in advance. I am a self-taught coder. And now I am making my personal page with Bootstrap.

What I want to do now is; SPA feature of React.js. All I understand this feature is;

  1. install "react-router-dom",
  2. import { Link, NavLink } from "react-router-dom";
  3. And replace those anchor and href tag to Link to=

The following code is in 'src' folder.

Navbar.js

import React from "react";
import logoImage from "../components/logo.png";
// React fontawesome imports
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBars } from "@fortawesome/free-solid-svg-icons";
import { Link, NavLink } from "react-router-dom";



const Navbar = () => {
    return (
        <nav className="navbar navbar-expand-lg navbar-light bg-white">
        <div className="container-fluid">

            <a className="navbar-brand mr-auto" href="#"><img className="logo" src={logoImage} alt="logoImage"/></a
            <button 
            className="navbar-toggler" 
            type="button" 
            data-bs-toggle="collapse" 
            data-bs-target="#navbarSupportedContent" 
            aria-controls="navbarSupportedContent" 
            aria-expanded="false" 
            aria-label="Toggle navigation"
            >
                <FontAwesomeIcon icon={faBars} style={{ color: "#2ff1f2" }}/>
            </button>

            <div className="collapse navbar-collapse" id="navbarSupportedContent">
                <ul className="navbar-nav ml-auto">
                    <li className="nav-item">
                        <a className="nav-link active" aria-current="page" href="../components/About">About me</a>
                    </li>
                    <li className="nav-item">
                        <a className="nav-link" href="#">Thoughts</a>
                    </li>
                    <li className="nav-item">
                        <a className="nav-link" href="#">Portfolio</a>
                    </li>
                    <li className="nav-item">
                        <a className="nav-link" href="#">Contacts</a>
                    </li>

                </ul>
                </div>
            </div>
            </nav>
                )
            }

export default Navbar;

App.js

import './App.css';
import "bootstrap/dist/css/bootstrap.min.css";
import Button from "react-bootstrap/Button";
import Particles from "react-particles-js";
import Navbar from "./components/Navbar";
import Header from "./components/Header";
import About from "./components/About";

function App() {
  return (
    <>
      <Particles
        className="particles-canvas"
          params={{
            particles: {
            number: {
            value: 30,
            density: {
            enable: true,
            value_area: 900
            }},
            shape: {
            type: "star",
            stroke: {
            width: 6,
            color: "#f9ab00"
            }}}}}
      />
      <Navbar />
      <Header />
      <About />
    </>
  );
}

export default App;

Header.js

import React from "react";
import Typed from "react-typed";
import { Link } from "react-router-dom";

const Header = () => {
    return (
        <div className="header-wraper">
            <div className="main-info">
                <h1>Welcome, this is my own personal page</h1>
                <Typed
                    className="typed-text"
                    strings={["text message to display in the centre of the page"]}
                    typeSpeed={80}
                />
                <a href="#" className="btn-main-offer">Details</a>



        </div>
    </div>
    )
}

export default Header;

And soon as I replace

<a className="nav-link" href="#">Thoughts</a> 

to

<Link to="../components/About">Thoughts</Link>

It stops working with this following error message.

×
Error: Invariant failed: You should not use <Link> outside a <Router>
invariant
C:/Users/Administrator/my-portfolio/node_modules/tiny-invariant/dist/tiny-invariant.esm.js:10
(anonymous function)
C:/Users/Administrator/modules/Link.js:88
  85 | return (
  86 |   <RouterContext.Consumer>
  87 |     {context => {
> 88 |       invariant(context, "You should not use <Link> outside a <Router>");
     | ^  89 | 
  90 |       const { history } = context;
  91 | 

My understanding to this error is:

  1. I should make Router.js file in src folder.
  2. I should just start again without Bootstrap first. Once SPA feature is done, then I can start work on this CSS feature as CSS in JS (eg const something = div.styled ``;)

I know this sounds ridiculous, but this is the best option I could think for now.

Question is, Where should I begin investigating this error message?

I am currently relying on this document page to remove the error message. 1st Example: Basic Routing - https://reactrouter.com/web/guides/quick-start

I would appreciate your opinion. Thank you. If I found a solution, I will update it with mine here.

Yes, you can do that, this error happen since you are missing to wrap <Link> component via <Router> ...

If you like to put it for all project, you can simply do this:

    <Router>
  <App />
</Router>

Example:

   <Router>
  <div>
    <nav>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
        <li>
          <Link to="/users">Users</Link>
        </li>
      </ul>
    </nav>

    {/* A <Switch> looks through its children <Route>s and
        renders the first one that matches the current URL. */}
    <Switch>
      <Route path="/about">
        <About />
      </Route>
      <Route path="/users">
        <Users />
      </Route>
      <Route path="/">
        <Home />
      </Route>
    </Switch>
  </div>
</Router>

Router is a component provided by react-router-dom As the error says, Link can be used inside Router .

Also, path for Link should actual browser url and not the path of the component. Ideal way is to add routes for each component.

For Example your App can be like this: ( Only for reference )

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/about">
          <About />
        </Route>
        <Route path="/">
          <Navbar />
        </Route>
      </Switch>
    </Router>
  );
}

This is a good question, but, in order to answer it the best way, you will need to work with several files, as I'm sure you're already aware of.

To start, assuming you used create-react-app , go to the index.js file, and wrap everything from the first parameter with react-router-dom 's BrowserRouter component. It should look like the following:

index.js

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

ReactDOM.render(
  <BrowserRouter>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </BrowserRouter>,
  document.getElementById("root")
);

Next, you will want to use react-router-dom 's Switch component to wrap all the application's routes.

App.js

import { Route, Switch } from "react-router";

import Navbar from "./components/Navbar";
import Header from "./components/Header";
import About from "./components/About";

// Particles component removed for explanation
function App() {
  return (
   <Navbar />
   <Header />

   // When a link is clicked, the component will appear within the following div,
   // so if you want certain elements to stay where they are on the page, wrap
   // and place the Switch component accordingly.
   <div className='pages'>
     <Switch>
       <Route path='/about' component={About} />
       <Route path='/profile' component={profile} />
       <Route path='/thoughts' component={Thoughts} />   
       <Route path='/contacts' component={Contacts} />
     </Switch>
   </div>

  );
}

export default App;

Now, within any child component of App , you can use react-router-dom Links (I personally prefer using NavLink due to its ease of styling). This could be done by the following:

Navbar.js

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

const Navbar = (props) => {
 return (
  <nav className="navbar navbar-expand-lg navbar-light bg-white">
   <div className="container-fluid">

     <NavLink className="navbar-brand mr-auto" to='/home'>
        <img className="logo" src={logoImage} alt="logoImage"/>
     </NavLink
      <button 
        className="navbar-toggler" 
        type="button" 
        data-bs-toggle="collapse" 
        data-bs-target="#navbarSupportedContent" 
        aria-controls="navbarSupportedContent" 
        aria-expanded="false" 
        aria-label="Toggle navigation"
       >
          <FontAwesomeIcon icon={faBars} style={{ color: "#2ff1f2" }}/>
       </button>

   <div className="collapse navbar-collapse" id="navbarSupportedContent">
      <ul className="navbar-nav ml-auto">
         <li className="nav-item">
           <NavLink className="nav-link active" to='/about'>About me</NavLink>
         </li>
          <li className="nav-item">
            <NavLink className="nav-link" to='/thoughts'>Thoughts</NavLink>
          </li>
          <li className="nav-item">
            <NavLink className="nav-link" to='/portfolio'>Portfolio</NavLink>
          </li>
          <li className="nav-item">
            <NavLink className="nav-link" to='/contacts'>Contacts</NavLink>
          </li>
       </ul>
    </div>
   </div>
  </nav>
 )
};

export default Navbar;

After doing what is shown below, you will be able to navigate throughout your page using react-router-dom .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM