「React TS3專題」親自動手建立一個類組件

上一章節 《「 React TS3 專題」從建立第一個 React TypeScript3 項目開始》 ,咱們一塊兒學習瞭如何建立一個 React TS3 項目。本章節與你們一塊兒聊聊如何使用 TS3 的方式建立組件。聲明 React組件的方式共有兩種:使用類的方式聲明組件(class component)和使用函數的方式聲明組件(function component)。今天筆者給你們聊聊使用類的方式聲明組件。

今天咱們將要建立一個 Confirm 的對話框組件,相似alert對話框,有標題,內容,確認和取消按鈕。組件完成後的效果以下圖所示:javascript

本篇文章主要包含如下內容:css

  • 使用 create-react-app 方式建立項目
  • 建立第一個類組件
  • JSX介紹
  • 用 TS3 的方式定義組件屬性
  • 定義可選屬性
  • 初始化屬性默認值

使用 create-react-app 方式建立項目

本示例咱們將使用 create-react-app 建立項目,這篇文章《「 React TS3 專題」從建立第一個 React TypeScript3 項目開始》有介紹過,這裏咱們快速熟悉下。html

一、建立項目前端

打開控制檯,經過如下命令建立咱們的 React TS3 項目:java

npx create-react-app my-components --typescript
複製代碼

二、安裝tslint依賴node

接下來,爲了保證項目代碼質量,咱們安裝 tslint 的相關依賴:react

cd my-components
npm install tslint tslint-react tslint-config-prettier --save-dev
複製代碼

三、而後添加 tslint.json 文件,配置相關規則typescript

{
 "extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
 "rules": {
 "ordered-imports": false,
 "object-literal-sort-keys": false,
 "no-debugger": false,
 "no-console": false,
 },
 "linterOptions": {
 "exclude": [
 "config/**/*.js",
 "node_modules/**/*.ts",
 "coverage/lcov-report/*.js"
 ]
 }
}
複製代碼

四、運行項目npm

接下來安裝相關依賴,並啓動項目:json

npm install
npm start
複製代碼

五、修改樣式

打開 app.css 文件,咱們進行一些樣式調整其頭部的高度,修改部分以下:

...
.App-logo {
 animation: App-logo-spin infinite 20s linear;
 height: 20vmin;
}
.App-header {
 background-color: #282c34;
 min-height: 40vh;
 display: flex;
 flex-direction: column;
 align-items: center;
 justify-content: center;
 font-size: calc(10px + 2vmin);
 color: white;
}
...
複製代碼

建立第一個類組件

一、建立 Confirm.tsx 文件

咱們會在 src 目錄下看到 App.tsx 文件,這是項目中爲咱們默認建立的組件,使用的是函數的方式建立組件,這裏先不作介紹,接下來的文章會有介紹。咱們先用類的聲明方式建立一個單獨的組件,在 src 目錄建立一個 Confirm.tsx 文件。初始化的內容結構以下:

import * as React from "react";
class Confirm extends React.Component {
}
export default Confirm;
複製代碼

二、添加 render 方法

接下來咱們添加 render 方法

...
class Confirm extends React.Component {
public render() {
 return (
 );
 }
}
...
複製代碼

三、實現 render 方法:

接下來咱們實現上述的 render 方法,這裏主要定義了組件的樣式佈局:

import * as React from "react";
class Confirm extends React.Component {
 public render() {
 return (
 <div className="confirm-wrapper confirm-visible">
 <div className="confirm-container">
 <div className="confirm-title-container">
 <span>This is where our title should go</span>
 </div>
 <div className="confirm-content-container">
 <p>This is where our content should go</p>
 </div>
 <div className="confirm-buttons-container">
 <button className="confirm-cancel">Cancel</button>
 <button className="confirm-ok">Okay</button>
 </div>
 </div>
 </div>
 );
 }
}
複製代碼

是否是以爲內容部分很像html, 在React裏稱JSX。做你會發現樣式屬性是 className 並非咱們熟悉的 class ,這是 JSX 語法所特有的。

四、 在 App.tsx 引入 Confirm 組件

import Confirm from "./Confirm";
...
<div className="App">
 <header className="App-header">
 ...
 </header>
<Confirm />
</div>
...
複製代碼

五、定義 Confirm.css 的樣式

因爲組件沒有樣式,還過於醜陋,接下來在 src 目錄新建 Confirm.css 文件,咱們來美化下咱們的組件,代碼以下:

.confirm-wrapper {
 position: fixed;
 left: 0;
 top: 0;
 width: 100%;
 height: 100%;
 background-color: gray;
 opacity: 0;
 visibility: hidden;
 transform: scale(1.1);
 transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s;
 z-index: 1;
}
.confirm-visible {
 opacity: 1;
 visibility: visible;
 transform: scale(1);
 transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
}
.confirm-container {
 background-color: #fff;
 position: absolute;
 top: 50%;
 left: 50%;
 transform: translate(-50%, -50%);
 border-radius: 0.2em;
 min-width: 300px;
}
.confirm-title-container {
 font-size: 1.3em;
 padding: 10px;
 border-top-left-radius: 0.2em;
 border-top-right-radius: 0.2em;
}
.confirm-content-container {
 padding: 0px 10px 15px 10px;
}
.confirm-buttons-container {
 padding: 5px 15px 10px 15px;
 text-align: right;
}
.confirm-buttons-container button {
 margin-left: 10px;
 min-width: 80px;
 line-height: 20px;
 border-style: solid;
 border-radius: 0.2em;
 padding: 3px 6px;
 cursor: pointer;
}
.confirm-cancel {
 background-color: #fff;
 border-color: #848e97;
}
.confirm-cancel:hover {
 border-color: #6c757d;
}
.confirm-ok {
 background-color: #848e97;
 border-color: #848e97;
 color: #fff;
}
.confirm-ok:hover {
 background-color: #6c757d;
 border-color: #6c757d;
}
複製代碼

而後在 Confirm.tsx 中引入 Confirm.css :

import"./Confirm.css";
複製代碼

六、啓動應用

咱們經過 npm start 啓動咱們的應用程序,效果以下:

JSX

上一小節,咱們知道了JSX有點像HTML,容許咱們在JavaScript代碼(或TS3)中相似HTML同樣進行使用,其實 React 使用 JSX 來替代常規的 JavaScript。

JSX 是一個看起來很像 XML 的 JavaScript 語法擴展。接下來咱們來了解下在解釋器的編譯下最終會轉換成什麼。

一、使用 https://babeljs.io/repl 在線工具

使用這款在線工具,咱們將相似的 相似 HTML 的 JSX 內容轉換成 JavaScript 的語法結構,示例以下:

如上圖所示咱們能夠看出,咱們代碼最終會轉換成 React.createElement 方法進行聲明,這個方法包含了三個參數標籤屬性(例如span,div等),第二就是標籤相關的屬性,好比能夠是className,第三個參數就是子元素屬性,用來進行標籤嵌套的。

二、接下來在外層添加div

爲了讓結構更加複雜,咱們在外層添加div, 代碼以下:

<div className="confirm-title-container">
 <span>This is where our title should go</span>
</div>
複製代碼

使用在線工具進行轉換,代碼以下:

React.createElement(
 "div",
 { className: "confirm-title-container" },
 React.createElement(
 "span",
 null,
 "This is where our title should go"
 )
);
複製代碼

三、接下來定義屬性

好比爲組件自定義屬性,結構以下:

const props = {
 title: "React and TypeScript"
};
<div className="confirm-title-container">
 <span>{props.title}</span>
</div>
複製代碼

使用在線工具進行轉換,代碼以下:

var props = {
 title: "React and TypeScript"
};
React.createElement(
 "div",
 { className: "confirm-title-container" },
 React.createElement(
 "span",
 null,
 props.title
 )
);
複製代碼

四、使用三元運算符,定義默認屬性

const props = {};
<div className="confirm-title-container">
 <span>{props.title ? props.title : "React and TypeScript"}</span>
</div>
複製代碼

使用在線工具轉換,代碼以下:

var props = {};
React.createElement(
 "span",
 null,
 props.title ? props.title : "React and TypeScript"
)
複製代碼

JSX 就介紹到這裏,咱們清楚了相似HTML結構的JSX都會轉換成javascript的原生結構,爲何不能使用class而使用className,筆者介紹到這裏,你應該明白了吧,由於 class 是 javascript 的關鍵詞 ES6的類聲明部分。

用 TS3 的方式定義組件屬性

組件的意義就是可以複用,上一小節,咱們把組件的標題,內容固定寫死了,接下來咱們來看看在 TS3 項目裏咱們是如何使用組件屬性的。

一、定義 TS3 類型屬性接口

咱們先來用 TS3 的方式定義接口類型,咱們在 Confirm.tsx 文件裏實現以下定義:

interface IProps {
 title: string;
 content: string;
}
複製代碼

二、接着將接口類型在類組件實現

經過添加到類的實現中,實現代碼以下:

class Confirm extends React.Component<IProps>
複製代碼

有過TS基礎的人,一眼就能看出 React.Component 是泛型類。泛型類規定了咱們傳入的接口的數據類型,能夠靈活進行定義。

軟件工程中,咱們不只要建立一致的定義良好的API,同時也要考慮可重用性。 組件不只可以支持當前的數據類型,同時也能支持將來的數據類型,這在建立大型系統時爲你提供了十分靈活的功能。 在像C#和Java這樣的語言中,可使用泛型來建立可重用的組件,一個組件能夠支持多種類型的數據。 這樣用戶就能夠以本身的數據類型來使用組件。

三、接下來定義組件的動態類型屬性

咱們將使用 this.props.propName 定義組件的動態屬性,按照以下代碼進行修改 Confirm.tsx 文件:

...
<div className="confirm-title-container">
 <span>{this.props.title}</span>
</div>
<div className="confirm-content-container">
 <p>{this.props.content}</p>
</div>
...
複製代碼

四、 Confirm.tsx 文件的最終代碼

import * as React from "react";
import './Confirm.css';
interface IProps {
 title: string;
 content: string;
}
class Confirm extends React.Component<IProps> {
 public render() {
 return (
 <div className="confirm-wrapper confirm-visible">
 <div className="confirm-container">
 <div className="confirm-title-container">
 <span>{this.props.title}</span>
 </div>
 <div className="confirm-content-container">
 <p>{this.props.content}</p>
 </div>
 <div className="confirm-buttons-container">
 <button className="confirm-cancel">Cancel</button>
 <button className="confirm-ok">Okay</button>
 </div>
 </div>
 </div>
 );
 }
}
export default Confirm;
複製代碼

五、 接下來修改 App.tsx 文件

因爲咱們修改了 Confirm.tsx 文件,讓屬性接受動態傳值,咱們須要在 App.tsx 文件中定義屬性內容,示例代碼以下:

<Confirm 
 title="React and TypeScript" 
 content="Are you sure you want to learn React and TypeScript?"
/>
export default Confirm;
複製代碼

咱們保存文件,你就會看到

定義可選屬性

一、咱們調用相關API時,有必傳參數和可選參數。咱們定義組件屬性時,也能夠這樣,有些屬性是必須填寫,有的可沒必要。接着咱們來定義確認按鈕文字和否認按鈕文字這些屬性是可選的,咱們來修改 Confirm.tsx 中的接口定義,示例以下:

interface IProps {
 title: string;
 content: string;
 cancelCaption?: string;
 okCaption?: string;
}
複製代碼
?: 的意思就是可選屬性參數的意思,咱們能夠能夠在調用組件時不用包含此屬性

二、將可選屬性在 Confirm.tsx 進行定義

<div className="confirm-buttons-container">
 <button className="confirm-cancel">
{this.props.cancelCaption}
 </button>
 <button className="confirm-ok">
{this.props.okCaption}
 </button>
</div>
複製代碼

三、保存文件

接下來爲了驗證可選屬性會不會形成錯誤,暫時不在 App.tsx 文件中的 Confirm 組件調用中添加新屬性,咱們來保存 Confirm.tsx 文件,瀏覽器的效果以下:

沒有報錯,能正常運行,因爲沒有給按鈕默認文字參數定義值,咱們的按鈕很難看,由於沒有高度。接下來咱們來給可選屬性定義值。

初始化屬性默認值

初始化組件時,咱們能夠給組件的屬性定義默認值,這裏就使用到了 defaultProps 靜態對象屬性。

一、聲明靜態對象屬性

經過靜態對象屬性的方式,咱們進行初始化可選參數的默認值,修改後的 Confirm.tsx 示例以下:

class Confirm extends React.Component<IProps> {
 public static defaultProps = {
 cancelCaption: "Cancel",
 okCaption: "Okay"
 };
 public render() { ... }
}
複製代碼

保存 Confirm.tsx 文件,咱們就會看到瀏覽器的變化:

二、修改默認屬性的值

若是你想修改默認屬性的值,咱們能夠修改 App.tsx 文件,添加可選屬性便可:

<Confirm
 title="React and TypeScript"
 content="Are you sure you want to learn React and TypeScript?"
 cancelCaption="No way"
 okCaption="Yes please!"
/>
複製代碼

保存 App.tsx 文件,你就會看到瀏覽器會刷新變化,效果以下圖:

具備默認值的可選屬性的組件更易於使用,讓咱們的組件更加靈活。

小節

今天的章節就分享到這裏,咱們一塊兒學習瞭如何使用 TS3 的方式建立組件,定義屬性和其屬性的默認值,接下來的文章裏,筆者將給你們介紹如何用 TS3 的方式定義組件事件。

更多精彩內容,請微信關注「前端達人」公衆號

相關文章
相關標籤/搜索