React 中高阶组件,什么是高阶组件,高阶组件本身是一个函数,接受一个组件作为参数,并返回一个新的组件,在 React中 高阶组件可以用来实现 Vue 中 mixins ,将数据和方法封装在高阶组件中。
创建一个高阶组件pagination.tsx文件
import React, { useState, ReactElement } from 'react'
export interface PageInfo {
current: number
pageSize: number
total: number
pageSizeOptions: number[]
}
/* 本身就是一个函数接受 WrappedComponent 就是传入的需要使用 PaginationHoc 公共数据方法的组件 */
const PaginationHoc = (WrappedComponent: React.ComponentType<any>) => {
return function() {
const [pageInfo, setPageInfo] = useState<PageInfo>({
current: 1,
pageSize: 10,
total: 0,
pageSizeOptions: [10, 20, 50, 100]
})
const com = { pageInfo, setPageInfo }
/* return 出这个新的WrappedComponent 通过...复制 pageInfo, setPageInfo 传值给使用方 */
return (
<WrappedComponent {...com} />
)
}
}
export default PaginationHoc
使用PaginationHoc高阶(组件创建一个AppCenter.tsx文件)
import React, { ReactElement } from 'react'
import type { PaginationProps } from 'antd'
/* 导入高阶组件 */
import PaginationHoc, { PageInfo } from './pagination'
interface Props {
pageInfo: PageInfo
setPageInfo: (val: PageInfo) => void
}
const AppCenter: React.FC<Props> = function AppCenter(props: Props): ReactElement {
/* 在 props 中拿到高阶组件中传递公共数据方法 */
/* 前提是 const AppCenterHOC = PaginationHoc(AppCenter) */
const { pageInfo, setPageInfo } = props
const onChange: PaginationProps['onChange'] = (current, pageSize) => {
setPageInfo({ ...pageInfo, current, pageSize })
console.log('Page: ', current, pageSize)
}
return (
<Pagination
defaultCurrent={1}
style={{ textAlign: 'right', margin: '20px 0 20px 0' }}
onChange={onChange}
current={pageInfo.current}
total={pageInfo.total}
showTotal={() => `共 ${pageInfo.total} 条`}
pageSize={pageInfo.pageSize}
showSizeChanger={true}
pageSizeOptions={pageInfo.pageSizeOptions}
/>
)
}
/* 将需要使用 PaginationHoc 高阶组件的 AppCenter 组件作为参数传递给 PaginationHoc */
const AppCenterHOC = PaginationHoc(AppCenter)
export default AppCenterHOC