如何在 Typescript 中使用 React Router
如何在 Typescript 中使用 React Router
React Router 是 React 生态系统中最流行的路由库之一。它是一个经过深思熟虑的库,拥有广泛的测试套件,并支持浏览器、React-Native 和服务器端渲染。在继续阅读本指南之前,我强烈建议您先阅读官方的React Router 指南,以熟悉相关术语。该文档提供了 React Router 可以帮助您完成的所有任务的详尽示例,但不包括有关将其与 Typescript 一起使用的信息,因此我们将在本教程中讨论这一点。
介绍
为了更好地理解 Typescript 与 React Router 一起使用时可以带来的好处,我们首先回顾一个用纯 Javascript 编写的简单示例。
我们首先使用Create React App创建一个空应用程序,运行以下命令:
npm install -g create-react-app
create-react-app demo-app
cd demo-app
正如我之前提到的,React Router 支持多个后端(dom、server、native),因此你需要选择合适的 NPM 包进行安装。我们将开发一个 Web 应用程序,因此首先我们需要安装react-router-dom:
npm install -S react-router-dom
我们将通过修改src/App.js文件并将其内容替换为以下内容来添加一个简单的双页导航系统:
1 import React from "react";
2 import { BrowserRouter as Router, Route, Link } from "react-router-dom";
3
4 function Index() {
5 return <h2>Home</h2>;
6 }
7
8 function Product({ match }) {
9 return <h2>This is a page for product with ID: {match.params.id} </h2>;
10 }
11
12 function AppRouter() {
13 return (
14 <Router>
15 <div>
16 <nav>
17 <ul>
18 <li>
19 <Link to="/">Home</Link>
20 </li>
21 <li>
22 <Link to="/products/1">First Product</Link>
23 </li>
24 <li>
25 <Link to="/products/2">Second Product</Link>
26 </li>
27 </ul>
28 </nav>
29
30 <Route path="/" exact component={Index} />
31 <Route path="/products/:id" component={Product} />
32 </div>
33 </Router>
34 );
35 }
36
37 export default AppRouter;
让我们启动应用服务器:
npm start
当你访问 https://localhost:3000 时,你会看到:
如果你访问 https://localhost:3000/product/2 或点击其中一个产品链接,你将获得:
审查
让我们回顾一下这里发生的事情:
在第 30 行,我们定义了一个 Home 路由,该路由响应根 URL“/”,并使用 Index 组件进行呈现。
在第 31 行,我们定义了一个 Product 路由,该路由响应以“/product/”开头且路径中包含产品 ID 的任何 URL。它使用 Product 组件进行呈现。
上述路由由路由器组件(第 14 行)包装,它将根据当前位置(URL 路径、参数和查询参数)决定应呈现什么。
主页路线是一个简单的无状态组件(第 4 行),它返回页面标题。
产品路由接收一个“id”参数,因此为了使用它,我们展开组件 props 并采用match prop,这将使我们能够访问所有路由参数(第 8 行)。然后我们使用该参数呈现页面标题。
那么,这里可能是什么原因导致的问题呢?让我们在代码中添加一个小拼写错误,将第 8 行和第 9 行的match更改为matches。
代码仍能正常编译,但运行时会产生以下错误:
通过在代码中引入类型并在运行之前执行静态代码分析,可以避免这个相当令人困惑的错误消息。这就是 Typescript 的用武之地。
打字稿
介绍
引用维基百科:
TypeScript是微软开发和维护的一种开源 编程语言。它是JavaScript的严格语法超集,并为该语言添加了可选的静态类型。
它允许我们准确地指定对象的形状以及我们期望在函数中接收的参数类型,从而为我们编写的代码增加一层安全性。
要将TypeScript添加到 Create React App 项目,首先安装它:
npm install --save-dev typescript @types/node @types/react @types/react-dom @types/jest @types/react-router-dom
接下来,将任何文件重命名为 TypeScript 文件(例如将src/index.js重命名为src/index.tsx)并重新启动开发服务器!
开发服务器启动后你会立即收到一个错误:
Failed to compile.
C:/temp/demo-app/src/App.tsx
Type error: Binding element 'matches' implicitly has an 'any' type. TS7031
6 | }
7 |
> 8 | function Product({ matches }) {
| ^
9 | return <h2>This is a page for product with ID: {matches.params.id} </h2>;
10 | }
11 |
太棒了!我们的拼写错误被发现了。现在,让我们看看如何解决这个问题。
添加类型
在开始之前,我想提请您注意我们之前运行过的npm install命令。除了添加 Typescript 编译器之外,我们还安装了几个@types包。它们是什么?每个@types包内都包含几个.d.ts文件,这些文件为从 NPM 安装的库提供实际的类型信息。
例如,当您在代码中使用流行的查询字符串库时:
const queryString = require('query-string');
console.log(location.search);
//=> '?foo=bar'
const parsed = queryString.parse(location.search);
console.log(parsed);
//=> {foo: 'bar'}
Typescript 编译器无法知道传递给queryString.parse方法的参数是否是正确的类型。您可以调用queryString.parse(123),这将是一个有效的代码,但在运行时会崩溃,因为该函数需要获取一个字符串进行解析。
为了缓解这个问题,存在一个包含类型定义的单独包,可以与主包一起安装以增强它:
npm install --save-dev @types/query-string
该包中包含一个index.d.ts文件,其代码如下:
export function parse(str: string, options?: ParseOptions): OutputParams;
它告诉编译器:我有一个解析函数,最多接受两个参数。第一个是字符串类型的必需参数,第二个可选参数称为options。现在,使用除字符串以外的任何参数调用queryString.parse都会出现语法错误!
现在我们已经熟悉了使用类型包的基础知识,让我们注释我们的代码以描述我们期望的参数以及我们如何处理它们。我们首先仔细看看 Product 无状态组件:
function Product({ match }) {
return <h2>This is a page for product with ID: {match.params.id} </h2>;
}
React 中的每个无状态组件都定义为一个函数,该函数接收其props并返回一个 React 元素。在我们的例子中,我们使用 JSX 生成该元素并使用扩展语法来获取match prop。我们如何知道 props 包含match对象?好吧,我们已经阅读了文档。在 Typescript 世界中,我们有更好的方法。我们可以检查@types包并了解 React Router 期望看到的参数的实际类型。
让我们打开node_modules/@types/react-router/index.d.ts<font style="ve
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~