前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React Router入门指南(包括Router Hooks)

React Router入门指南(包括Router Hooks)

作者头像
前端知否
发布2020-03-23 18:02:37
11.9K0
发布2020-03-23 18:02:37
举报
文章被收录于专栏:前端知否前端知否

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

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

初始化项目

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

代码语言:javascript
复制
npx create-react-app react-router-guide

然后,将这些代码行添加到App.js文件中。

在App.js中,

代码语言:javascript
复制
代码语言:javascript
复制
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 = () => (
  <>
    <h1>Home</h1>
    <FakeText />
  </>
);

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

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

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>
)

然后,在继续之前,我们先回答一个重要问题:什么是路由?

什么是路由?

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

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

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

代码语言:javascript
复制
代码语言:javascript
复制
yarn add react-router-dom

or

npm install react-router-dom

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

设置路由

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

App.js

代码语言:javascript
复制
代码语言:javascript
复制
import React 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>
  );
}

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

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

只有router,还做不了很多事情,让我们在下一节中添加一条路由。

渲染路由

要渲染路由,我们必须从react-router-dom包中导入Route组件。

代码语言:javascript
复制
代码语言:javascript
复制
import React 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>
  );
}
代码语言:javascript
复制

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

  • path:这是route的路径。在这里,我们使用 / 定义主页的路径。
  • render:到达路由时将显示内容。在这里,我们将向用户呈现欢迎消息。

在某些情况下,提供这样的路由是完全可以的,但请想象一下,当我们需要处理真实组件时,使用render可能不是正确的解决方案。

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

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

App.js

代码语言:javascript
复制
代码语言:javascript
复制
import React 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 = () => (
  <>
    <h1>Home</h1>
    <FakeText />
  </>
);

现在,我们的路由将不再加载消息,而是加载Home组件。

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

使用链接切换页面

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

App.js

代码语言:javascript
复制
代码语言:javascript
复制
import React 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 = () => (
  <>
    <h1>Home</h1>
    <FakeText />
  </>
);

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

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

导入链接后,我们必须稍微更新导航栏。

现在,React Router不再使用标签和href,而是使用Link来进行切换,而无需重新加载页面。

然后,我们需要添加两条新路线:“关于”和“联系方式”,以便您也可以在页面或组件之间进行切换。

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

原因是React Router将检查定义的路径是否以/开头(如果是),它将呈现组件。

在这里,我们的第一个路径以/开头,因此Home组件每次都会呈现。

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

App.js

代码语言:javascript
复制
<Route path="/" exact component={Home} />

现在,对home组件的路由添加了exact属性,那么只有与完整路径匹配时才会呈现。

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

App.js

代码语言:javascript
复制
代码语言:javascript
复制
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>

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

传递路由参数

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

App.js

代码语言:javascript
复制
代码语言:javascript
复制
import React 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 = () => (
  <>
    <h1>Home</h1>
    <FakeText />
  </>
);

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

const Contact = () => (
  <>
    <h1>Contact</h1>
    <FakeText />
  </>
);
代码语言:javascript
复制

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

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

现在,参数将作为About组件中的props接收,我们现在唯一要做的就是对props进行结构分解并获取name属性。顺便说一下,{match:{params:{name}}}与props.match.params.name相同。

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

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

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

以编程方式导航

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

App.js

代码语言:javascript
复制
代码语言:javascript
复制
const Contact = ({history}) => (
  <>
    <h1>Contact</h1>
    <button onClick={() => history.push('/') } >Go to home</button>
    <FakeText />
  </>
);
代码语言:javascript
复制

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

现在,让我们处理重定向用户的情况。

重定向到另一个页面

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

代码语言:javascript
复制
代码语言:javascript
复制
import { BrowserRouter as Router, Route, Link, Switch, Redirect } from "react-router-dom";

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

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

您可能会争论为什么我不使用props.history.push('/')重定向用户?好吧,Redirect组件会替换页面,因此用户无法返回上一页,但是使用push方法,它可以。同样,您还可以使用props.history.replace('/')来模仿重定向行为。

现在,让我们继续处理用户遇到不存在的路由时的情况。

重定向到404页面

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

代码语言:javascript
复制
代码语言:javascript
复制
import React from "react";
import "./index.css"

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

export default function App() {
  const name = 'Foo'

  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>
  );
}
代码语言:javascript
复制

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

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

保护路由

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

代码语言:javascript
复制
代码语言:javascript
复制
import React from "react";
import "./index.css"

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

export default function App() {
  const name = 'Foo'
  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>
  );
}
代码语言:javascript
复制

如您所见,我声明了一个模仿身份验证的变量。然后,检查用户是否已通过身份验证。如果是这种情况,请渲染受保护的页面,否则将其重定向到主页。

到目前为止,我们已经介绍了很多内容,但是它仍然是一个有趣的部分:路由钩子Hooks。

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

路由hooks(useHistory,useParams,useLocation)

路由hooks使事情变得容易得多。现在,以简单而优雅的方式访问历史记录,位置或参数。

useHistory

useHistory钩子使我们可以访问history对象,而无需从props中将其提取。

代码语言:javascript
复制
代码语言:javascript
复制
import { useHistory } from "react-router-dom";

const Contact = () => {
  const { history } = useHistory();

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

useParams

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

代码语言:javascript
复制
代码语言:javascript
复制
import { BrowserRouter as Router, Route, Link, Switch, useParams } from "react-router-dom";

export default function App() {
  const name = 'Foo'
  
  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
    <>
      { name !== 'Foo' ? <Redirect to="/" /> : null }
      <h1>About {name}</h1>
      <Route component={Contact} />
    </>
  )
};

useLocation

它返回代表当前URL的位置对象。

代码语言:javascript
复制
代码语言:javascript
复制
import { useLocation } from "react-router-dom";

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

  return (
    <>
      <h1>Contact</h1>
      <p>当前 URL: {pathname}</p>
    </>
  )
};
最后

React Router是一个了不起的库,它可以帮助我们从一个页面转到一个多页面的应用程序(虽然它仍然是一个页面),并且具有很高的可用性。现在,借助路由hooks,您已经亲眼目睹了它们的简易性和优雅性,绝对是您下一个项目中需要考虑使用的。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端知否 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初始化项目
  • 什么是路由?
  • 设置路由
  • 渲染路由
  • 使用链接切换页面
  • 传递路由参数
  • 以编程方式导航
  • 重定向到另一个页面
  • 重定向到404页面
  • 保护路由
  • 路由hooks(useHistory,useParams,useLocation)
  • 最后
相关产品与服务
多因子身份认证
多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档