完整的React Router初学者指南(包括Router Hooks)

React is a JavaScript library for building user interfaces. We can also extend it to build multi-page applications with the help of React Router. This is a third-party library that enables routing in our React apps.

React是一个用于构建用户界面JavaScript库。 我们还可以借助React Router将其扩展为构建多页应用程序。 这是一个第三方库,可在我们的React应用程序中进行路由。

In this tutorial, we are going to cover everything you need to know to get started with React Router.

在本教程中,我们将介绍使用React Router入门所需的一切。

设置项目 (Setting up the project)

To be able to follow along, you will need to create a new React app by running the following command in your terminal:

为了能够继续学习,您需要通过在终端中运行以下命令来创建新的React应用程序:

npx create-react-app react-router-guide

Then, add these lines of code to the App.js file:

然后,将以下代码行添加到App.js文件中:

import React from "react";
import "./index.css"

export default function App() {
  return (
    <main>
      <nav>
        <ul>
          <li><a href="/">Home</a></li>
          <li><a href="/about">About</a></li>
          <li><a href="/contact">Contact</a></li>
        </ul>
        </nav>
     </main>
  );
}
// Home Page
const Home = () => (
  <Fragment>
    <h1>Home</h1>
    <FakeText />
  </Fragment>
  );
// About Page
const About = () => (
  <Fragment>
    <h1>About</h1>
    <FakeText />
  </Fragment>
  );
// Contact Page
const Contact = () => (
  <Fragment>
    <h1>Contact</h1>
    <FakeText />
  </Fragment>
  );

const FakeText = () => (
  <p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
  )

Then, if you're ready to go, let's start by answering an important question: what is routing?

然后,如果您准备好出发,我们首先回答一个重要问题:什么是路由?

什么是路由? (What is routing?)

Routing is the capacity to show different pages to the user. That means the user can move between different parts of an application by entering a URL or clicking on an element.

路由是向用户显示不同页面的能力。 这意味着用户可以通过输入URL或单击元素来在应用程序的不同部分之间移动。

As you may already know, by default, React comes without routing. And to enable it in our project, we need to add a library named react-router.

您可能已经知道,默认情况下,React不带路由。 为了在我们的项目中启用它,我们需要添加一个名为react-router的库。

To install it, you will have to run the following command in your terminal:

要安装它,您将必须在终端中运行以下命令:

yarn add react-router-dom

Or

要么

npm install react-router-dom

Now, we've successfully installed our router, let's start using it in the next section.

现在,我们已经成功安装了路由器,让我们在下一部分开始使用它。

设置路由器 (Setting up the router)

To enable routing in our React app, we first need to import BrowserRouter from react-router-dom.

要在React应用中启用路由,我们首先需要从react-router-dom导入BrowserRouter

In the App.js file, enter the following:

App.js文件中,输入以下内容:

import React, { Fragment } from "react";
import "./index.css"

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

export default function App() {
  return (
  <Router>
    <main>
      <nav>
        <ul>
          <li><a href="/">Home</a></li>
          <li><a href="/about">About</a></li>
          <li><a href="/contact">Contact</a></li>
        </ul>
      </nav>
    </main>
</Router>
  );
}

This should hold everything in our app where routing is needed. That means, if we need routing in our entire app, we must wrap our higher component with BrowserRouter.

这应该在我们需要路由的应用程序中保存所有内容。 这意味着,如果需要在整个应用程序中进行路由,则必须使用BrowserRouter包装更高的组件。

By the way, you don't have to rename BrowserRouter as Router as I do here, I just want to keep things readable.

顺便说一句,您不必像我在这里那样将BrowserRouter as Router重命名BrowserRouter as Router ,我只是想保持可读性。

A router alone doesn't do much. So let's add a route in the next section.

路由器本身并不能做很多事情。 因此,让我们在下一部分中添加一条路线。

渲染路线 (Rendering routes)

To render routes, we have to import the Route component from the router package.

要渲染路由,我们必须从路由器包中导入Route组件。

In your App.js file, add the following code:

在您的App.js文件中,添加以下代码:

import React, { Fragment } from "react";
import "./index.css"

import { BrowserRouter as Router, Route } from "react-router-dom";

export default function App() {
  return (
  <Router>
    <main>
      <nav>
        <ul>
          <li><a href="/">Home</a></li>
          <li><a href="/about">About</a></li>
          <li><a href="/contact">Contact</a></li>
        </ul>
      </nav>
  <Route path="/" render={() => <h1>Welcome!</h1>} />
    </main>
</Router>
  );
}

Then, add it where we want to render the content. The Route component has several properties. But here, we just need path and render.

然后,将其添加到我们要呈现内容的位置。 Route组件具有多个属性。 但是在这里,我们只需要pathrender

path: the path of the route. Here, we use / to define the path of the home page.

path :路线的路径。 在这里,我们使用/定义主页的路径。

render: will display the content whenever the route is reached. Here, we'll render a welcome message to the user.

render :在到达路线时将显示内容。 在这里,我们将向用户呈现欢迎消息。

In some cases serving routes like that is perfectly fine. But imagine a case when we have to deal with a real component – using render may not be the right solution.

在某些情况下,提供这样的路线非常好。 但是想象一下当我们不得不处理一个真实组件的情况–使用render可能不是正确的解决方案。

So, how can we display a real component? Well, the Route component has another property named component.

那么,我们如何显示真实的组件? 好吧, Route组件还有另一个名为component属性。

Let's update our example a bit to see it in action.

让我们对示例进行一些更新以了解其实际效果。

In your App.js file, add the following code:

在您的App.js文件中,添加以下代码:

import React, { Fragment } from "react";
import "./index.css"

import { BrowserRouter as Router, Route } from "react-router-dom";

export default function App() {
  return (
   <Router>
    <main>
      <nav>
        <ul>
          <li><a href="/">Home</a></li>
          <li><a href="/about">About</a></li>
          <li><a href="/contact">Contact</a></li>
        </ul>
      </nav>

    <Route path="/" component={Home} />
    </main>
</Router>
  );
}

const Home = () => (
  <Fragment>
    <h1>Home</h1>
    <FakeText />
  </Fragment>
  );

Now, instead of rendering a message, our route will load the Home component.

现在,无需渲染消息,我们的路线将加载Home组件。

To get the full power of React Router, we need to have multiple pages and links to play with. We already have pages (components if you want, too), so now let's add some links so we can switch between pages.

要获得React Router的全部功能,我们需要有多个页面和链接可供使用。 我们已经有页面(如果需要,也可以包含组件),所以现在让我们添加一些链接,以便我们可以在页面之间进行切换。

To add links to our project, we will use the React Router again.

要添加到我们项目的链接,我们将再次使用React Router。

In your App.js file, add the following code:

在您的App.js文件中,添加以下代码:

import React, { Fragment } from "react";
import "./index.css"

import { BrowserRouter as Router, Route, Link } from "react-router-dom";

export default function App() {
  return (
   <Router>
    <main>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/contact">Contact</Link></li>
        </ul>
      </nav>

    <Route path="/" exact component={Home} />
    <Route path="/about"  component={About} />
    <Route path="/contact"  component={Contact} />

    </main>
</Router>
  );
}

const Home = () => (
  <Fragment>
    <h1>Home</h1>
    <FakeText />
  </Fragment>
  );

const About = () => (
  <Fragment>
    <h1>About</h1>
    <FakeText />
  </Fragment>
  );

const Contact = () => (
  <Fragment>
    <h1>Contact</h1>
    <FakeText />
  </Fragment>
  );

After importing Link, we have to update our navigation bar a bit. Now, instead of using a tag and href, React Router uses Link and to to, well, be able to switch between pages without reloading it.

导入Link ,我们必须稍微更新导航栏。 现在,而不是使用a标签和href ,阵营路由器使用Link ,并to对,很好,能够在不重新加载页面它之间进行切换。

Then, we need to add two new routes, About and Contact, to be able to switch between pages or components.

然后,我们需要添加两个新的路线, AboutContact ,以便能够在页面或组件之间进行切换。

Now, we can go to different parts of our app through links. But there is an issue with our router: the Home component is always displayed even if we switch to other pages.

现在,我们可以通过链接转到应用程序的不同部分。 但是我们的路由器存在一个问题:即使我们切换到其他页面,也会始终显示Home组件。

This is because React Router will check if the path defined starts with /. If that's the case, it will render the component. And here, our first route starts with /, so the Home component will be rendered each time.

这是因为React Router将检查定义的path是否以/开头。 如果是这样,它将渲染组件。 在这里,我们的第一条路线以/开头,因此每次都会渲染Home组件。

However, we can still change the default behavior by adding the exact property to Route.

但是,我们仍然可以通过将exact属性添加到Route来更改默认行为。

In App.js, add:

App.js ,添加:

<Route path="/" exact component={Home} />

By updating the Home route with exact, now it will be rendered only if it matches the full path.

通过使用exact更新Home路线,现在仅当它与完整路径匹配时才会呈现。

We can still enhance it by wrapping our routes with Switch to tell to React Router to load only one route at a time.

我们仍然可以通过使用Switch包装路由来告诉React Router一次只加载一条路由来增强它。

In App.js, add:

App.js ,添加:

import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";

  <Switch>
    <Route path="/" exact component={Home} />
    <Route path="/about"  component={About} />
    <Route path="/contact"  component={Contact} />
  </Switch>

Now that we have new links, let's use them to pass parameters.

现在我们有了新的链接,让我们使用它们来传递参数。

传递路线参数 (Passing route parameters)

To pass data between pages, we have to update our example.

要在页面之间传递数据,我们必须更新示例。

In your App.js file, add the following code:

在您的App.js文件中,添加以下代码:

import React, { Fragment } from "react";
import "./index.css"

import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";

export default function App() {
  const name = 'John Doe'
  return (
   <Router>
    <main>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to={`/about/${name}`}>About</Link></li>
          <li><Link to="/contact">Contact</Link></li>
        </ul>
      </nav>
    <Switch>
      <Route path="/" exact component={Home} />
      <Route path="/about/:name"  component={About} />
      <Route path="/contact"  component={Contact} />
    </Switch>
    </main>
</Router>
  );
}

const Home = () => (
  <Fragment>
    <h1>Home</h1>
    <FakeText />
  </Fragment>
  );

const About = ({match:{params:{name}}}) => (
  // props.match.params.name
  <Fragment>
    <h1>About {name}</h1>
    <FakeText />
  </Fragment>
);

const Contact = () => (
  <Fragment>
    <h1>Contact</h1>
    <FakeText />
  </Fragment>
  );

As you can see here, we start by declaring a new constant name which will be passed as a parameter to the About page. And we append name to the corresponding link.

如您在此处看到的,我们首先声明一个新的常量name ,该常量name将作为参数传递给“ About页面。 然后,将name附加到相应的链接。

With that, we now have to update the About route by adjusting its path to receive name as a parameter path="/about/:name".

这样,我们现在必须通过调整其路径以将name接收为参数path="/about/:name"来更新About路线。

Now, the parameter will be received as props from the About component. The only thing we have to do now is destructure the props and get back the name property. By the way, {match:{params:{name}}} is the same as props.match.params.name.

现在,参数将从About组件作为道具接收。 现在我们唯一要做的就是销毁道具并取回name属性。 顺便说一下, {match:{params:{name}}}props.match.params.name相同。

We've done a lot up to this point. But in some cases we don't want to use links to navigate between pages.

到目前为止,我们已经做了很多工作。 但是在某些情况下,我们不想使用链接在页面之间导航。

Sometimes, we have to wait for an operation to finish before navigating to the next page.

有时,我们必须等待操作完成才能导航到下一页。

So, let's handle that case in the next section.

因此,让我们在下一部分中处理这种情况。

The props we receive have some convenient methods we can use to navigate between pages.

我们收到的道具有一些便捷的方法可用于在页面之间导航。

In App.js, add:

App.js ,添加:

const Contact = ({history}) => (
  <Fragment>
    <h1>Contact</h1>
    <button onClick={() => history.push('/') } >Go to home</button>
    <FakeText />
  </Fragment>
  );

Here, we pull the history object from the props we receive. It has some handy methods like goBack, goForward, and so on. But here, we will use the push method to be able to go to the Home page.

在这里,我们从收到的道具中提取history对象。 它具有一些方便的方法,如goBackgoForward等。 但是在这里,我们将使用push方法来转到主页。

Now, let's handle the case when we want to redirect our user after an action.

现在,让我们处理在操作后想要重定向用户的情况。

重定向到另一个页面 (Redirecting to another page)

The React Router has another component named Redirect. As you guessed, it helps us redirect the user to another page

React Router具有另一个名为Redirect组件。 您猜到了,它可以帮助我们将用户重定向到另一个页面

In App.js, add:

App.js ,添加:

import { BrowserRouter as Router, Route, Link, Switch, Redirect } from "react-router-dom";

const About = ({match:{params:{name}}}) => (
  // props.match.params.name
  <Fragment>
    { name !== 'John Doe' ? <Redirect to="/" /> : null }
    <h1>About {name}</h1>
    <FakeText />
  </Fragment>
);

Now, if the name passed as a parameter is not equal to John Doe, the user will be redirected to the home page.

现在,如果作为参数传递的name不等于John Doe ,则用户将被重定向到主页。

You could argue that you should redirect the user with props.history.push('/). Well, the Redirect component replaces the page and therefore the user can't go back to the previous page. But, with the push method they can. However, you can use props.history.replace('/) to mimic the Redirect behavior.

您可能会争辩说应该使用props.history.push('/)重定向用户。 好吧, Redirect组件将替换页面,因此用户无法返回上一页。 但是,使用push方法可以。 但是,您可以使用props.history.replace('/)来模仿Redirect行为。

Now let's move on and handle the case when the user hits a route that doesn't exist.

现在让我们继续处理当用户点击一条不存在的路线时的情况。

重定向到404页面 (Redirecting to a 404 page)

To redirect the user to a 404 page, you can create a component to show it. But here, to keep things simple, I will just display a message with render.

要将用户重定向到404页面,您可以创建一个组件来显示它。 但是在这里,为了简单起见,我将只显示一条带有render的消息。

import React, { Fragment } from "react";
import "./index.css"

import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";

export default function App() {
  const name = 'John Doe'
  
  return (
   <Router>
    <main>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to={`/about/${name}`}>About</Link></li>
          <li><Link to="/contact">Contact</Link></li>
        </ul>
      </nav>
    <Switch>
      <Route path="/" exact component={Home} />
      <Route path="/about/:name"  component={About} />
      <Route path="/contact"  component={Contact} />
      <Route render={() => <h1>404: page not found</h1>} />
      
    </Switch>
    </main>
</Router>
  );
}

The new route we've added will catch every path that doesn't exist and redirect the user to the 404 page.

我们添加的新路由将捕获所有不存在的路径,并将用户重定向到404页面。

Now, let's move on and learn how to protect our routes in the next section.

现在,让我们继续前进,并在下一部分中学习如何保护我们的路线。

护路 (Guarding routes)

There are many ways to protect routes to React. But here I will just check if the user is authenticated and redirect them to the appropriate page.

有很多方法可以保护通往React的路由。 但是在这里,我将仅检查用户是否已通过身份验证并将他们重定向到适当的页面。

import React, { Fragment } from "react";
import "./index.css"

import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";

export default function App() {
  const name = 'John Doe'
  const isAuthenticated = false
  return (
   <Router>
    <main>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to={`/about/${name}`}>About</Link></li>
          <li><Link to="/contact">Contact</Link></li>
        </ul>
      </nav>
    <Switch>
      <Route path="/" exact component={Home} />
      {
      isAuthenticated ? 
      <>
      <Route path="/about/:name"  component={About} />
      <Route path="/contact"  component={Contact} />
      </> : <Redirect to="/" />
      }
      
    </Switch>
    </main>
</Router>
  );
}

As you can see here, I declared a variable to mimic authentication. Then, check if the user is authenticated or not. If they are, render protected pages. Otherwise redirect them to the home page.

如您在这里看到的,我声明了一个模仿身份验证的变量。 然后,检查用户是否已通过身份验证。 如果是这样,请呈现受保护的页面。 否则,将它们重定向到主页。

We've covered a lot up to this point, but an interesting part remains: router hooks.

到目前为止,我们已经介绍了很多内容,但是有趣的部分仍然存在:路由器挂钩。

Let's move to the final section and introduce Hooks.

让我们进入最后一部分,介绍Hooks。

路由器挂钩 (Router Hooks)

Router hooks make things much easier. Now you can access the history, location, or parameters in an easy and elegant way.

路由器挂钩使事情变得容易得多。 现在,您可以轻松,优雅地访问历史记录,位置或参数。

使用历史 (useHistory)

The useHistory hook gives us access to the history instance without pulling it from props.

useHistory挂钩使我们可以访问历史实例,而无需从道具中将其提取。

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

const Contact = () => {
const history = useHistory();
return (
  <Fragment>
    <h1>Contact</h1>
    <button onClick={() => history.push('/') } >Go to home</button>
  </Fragment>
  )
  };

useParams (useParams)

This hook helps us get the parameter passed on the URL without using the props object.

这个钩子帮助我们无需使用props对象就可以在URL上传递参数。

import { BrowserRouter as Router, Route, Link, Switch, useParams } from "react-router-dom";

export default function App() {
  const name = 'John Doe'
  return (
   <Router>
    <main>
      <nav>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to={`/about/${name}`}>About</Link></li>
        </ul>
      </nav>
    <Switch>
      <Route path="/" exact component={Home} />
      <Route path="/about/:name"  component={About} />
    </Switch>
    </main>
</Router>
  );
}

const About = () => {
  const { name } = useParams()
  return (
  // props.match.params.name
  <Fragment>
    { name !== 'John Doe' ? <Redirect to="/" /> : null }
    <h1>About {name}</h1>
    <Route component={Contact} />
  </Fragment>
)
};

useLocation (useLocation)

This hook returns the location object that represents the current URL.

该挂钩返回代表当前URL的位置对象。

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

const Contact = () => {
const { pathname } = useLocation();

return (
  <Fragment>
    <h1>Contact</h1>
    <p>Current URL: {pathname}</p>
  </Fragment>
  )
  };

最后的想法 (Final Thoughts)

React Router is an amazing library that helps us go from a single page to a multi-page application feeling with great usability. (Just keep in mind – at the end of the day, it's still a single page app).

React Router是一个了不起的库,它可以帮助我们从一个页面转到一个多页面的应用程序,并具有很高的可用性。 (请记住-归根结底,它仍然是单页应用程序)。

And now with router hooks, you can see how easy and elegant they are. They're definitely something to consider in your next project.

现在有了路由器挂钩,您可以看到它们多么简单和优雅。 它们绝对是您下一个项目中要考虑的东西。

You can read more of my articles on my blog.

您可以在我的博客上阅读更多我的文章。

下一步 (Next Steps)

React Router Documentation

React Router文档

Photo by Joshua Sortino on Unsplash

Joshua SortinoUnsplash拍摄的照片

翻译自: https://www.freecodecamp.org/news/a-complete-beginners-guide-to-react-router-include-router-hooks/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值