元件和元件庫框架

2023-11-22 18:00:22

所謂天才,就是努力的力量。

React 元件由 DOM 結構,樣式和 Javascript 邏輯組成。

1. ES6 中的類

class People {
  constructor() {
    this.name = "hubert"
    this.age = 29
  }

  printName() {
    console.log(this.name)
  }

  printAge() {
    console.log(this.age)
  }
}

var people = new People()
people.printName()
people.printAge()

2. 類式元件

類式元件是基於使用 class 定義的類,需要繼承自 React.Component;另外,類式元件中必須實現 render 函數。

import React from "react";

class AppClassComponent extends React.Component {
  render() {
    return <div>hello {this.props.name}</div>
  }
}

export default AppClassComponent

3. 函數式元件

函數式元件是基於使用 function 定義的函數,通常接受一個 props 引數,返回一個 JSX 元素或者 null。函數式元件和普通函數最主要的區別在呼叫的時候,函數式元件在渲染的時候沒有被人為顯式呼叫,而是由 React 內部去呼叫。

// React 16.8 之前函數式元件是無狀態的
// React 16.8 之後引入 react hooks,我們可以讓函數式元件有狀態了。hooks 讓函數式元件有狀態了。
function AppFuncConponent(props) {
  return (
    <div>hello function conponent</div>
  )
}

// ES6 箭頭函數
const AppfuncComponent1 = (props)=>{
  return <div>箭頭函陣列件</div>
}

export default AppFuncConponent

4. TypeScript 函數式元件

函數式元件通常接受一個 props 引數,返回一個 JSX 元素或者 null。當我們需要使用 TypeScript 去定義一個函數式元件時,除了基礎對函數式寫法外,我們還可以使用以下方式來實現。

4.1)使用 React.FC

由於 React 不是使用 TypeScript 開發的,使用的是社群開發的 @type/react 包提供的型別,裡面有一個通用型別 FC ,允許我們為函陣列件新增引數型別

type FCProps = { text: string };
// 這裡的 React.FC 是 React.FunctionComponent 的簡寫
const FCComponent: React.FC<FCProps> = ({ text = "" })=> <div>{text}</div>;

當元件包含子元素,TypeScript 會提示警告,現在已經不推薦使用這種方式了

type FCProps = { text: string };
const FCComponent: React.FC<FCProps> = ({ text = "" }) => <div>{text}</div>;

function App() {
  return (
    <div className="App">
        <FCComponent text="Hello Chris1993.">
            <span>children</span>
        </FCComponent>
    </div>
  );
}

提示警告內容:

Type '{ children: string; text: string; }' is not assignable to type 'IntrinsicAttributes & FCProps'.
  Property 'children' does not exist on type 'IntrinsicAttributes & FCProps'.

4.2)直接定義完整型別

由於 React 元件包含子元素時,會隱式傳遞一個 children 屬性,導致定義的引數型別出錯,因此我們可以直接定義一個完整的引數介面,包含了 children 屬性的型別:

type FCProps = { text: string; children?: any };
const FCComponent: React.FC<FCProps> = ({ text = "" }) => <div>{text}</div>;

function App() {
  return (
    <div className="App">
        <FCComponent text="Hello Chris1993.">
            <span>children</span>
        </FCComponent>
    </div>
  );
}

4.3)使用 React.PropsWithChildren

上面這種方法每次都要手動寫一個 children 屬性型別比較麻煩,這時候我們就可以使用 React.PropsWithChildren 型別,它本身封裝了 children 的型別宣告:

// react/index.d.ts
type PropsWithChildren<P> = P & { children?: ReactNode };

因此,使用 React.PropsWithChildren 型別定義函數式元件,就不用去處理 children 的型別了:

type IProps = React.PropsWithChildren<{ text: string }>;
// 形式1
const PropsComponent = ({ text }: IProps) => <div>{text}</div>;
// 形式2
const PropsComponent:React.FC<IProps> = ({ text }) => <div>{text}</div>;

function App() {
  return (
    <div className="App">
        <PropsComponent text="Hello Chris1993.">
            <span>children</span>
        </PropsComponent>
    </div>
  );
}

4.4)使用 JSX.Element

使用 JSX.Element 型別作為函數式元件的返回值型別,當元件的返回值不是 JSX.Element 型別時,TypeScript 就會提示錯誤。

type FCProps = { text: string };
const ElementComponent = ({ text }: FCProps): JSX.Element => <div>{text}</div>;
function App() {
  return (
    <div className="App">
        <ElementComponent text="Hello Chris1993."></ElementComponent>
    </div>
  );
}

5. 元件巢狀使用

6. React UI 元件庫

Ant Design 是一個致力於提升『使用者!和『設計者』使用體驗的設計語言;旨在統一中臺專案的前端 UI 設計,遮蔽不必要的設計差異和實現成本,解放設計和前端的研發資源;包含很多設計原則和配套的元件庫。

Ant Design(PC 端):https://ant.design/index-cn

Ant Design Mobile(行動端):https://mobile.ant.design/zh