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