- A+
所谓天才,就是努力的力量。
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