所謂天才,就是努力的力量。
React 元件由 DOM 結構,樣式和 Javascript 邏輯組成。
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()
類式元件是基於使用 class
定義的類,需要繼承自 React.Component
;另外,類式元件中必須實現 render
函數。
import React from "react";
class AppClassComponent extends React.Component {
render() {
return <div>hello {this.props.name}</div>
}
}
export default AppClassComponent
函數式元件是基於使用 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
函數式元件通常接受一個 props
引數,返回一個 JSX 元素或者 null
。當我們需要使用 TypeScript 去定義一個函數式元件時,除了基礎對函數式寫法外,我們還可以使用以下方式來實現。
由於 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'.
由於 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>
);
}
上面這種方法每次都要手動寫一個 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>
);
}
使用 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>
);
}
Ant Design 是一個致力於提升『使用者!和『設計者』使用體驗的設計語言;旨在統一中臺專案的前端 UI 設計,遮蔽不必要的設計差異和實現成本,解放設計和前端的研發資源;包含很多設計原則和配套的元件庫。
Ant Design(PC 端):https://ant.design/index-cn
Ant Design Mobile(行動端):https://mobile.ant.design/zh