react ts 父组件调用子组件方法,父子通信

发布时间 2023-07-28 16:01:19作者: DL·Coder

子组件

GlobalTableWapper:css 盒子
IProps, ChildMethods:字段类型

import React, { forwardRef, memo, useEffect, useImperativeHandle, useState } from 'react'
import type { FC } from 'react'

import { GlobalTableWapper } from './style'
import { Pagination, Table } from 'antd'
import { IProps, ChildMethods } from './type'

const GlobalBox: FC<IProps> = forwardRef<ChildMethods, IProps>((props, ref) => {
  console.log(props, 'props');
  const { columns, height = 'calc(100vh - 210px)', initData, form = {} } = props
  const [tableConfig, setTableConfig] = useState<any>({
    total: 0,
    list: []
  });

  useEffect(() => {
    if (!tableConfig?.list.length) {
      initTable(form)
    }
  }, [])

  const initTable = async (form: object = {}) => {
    try {
      const { code, data } = await initData(form)
      if (code === 1) {
        setTableConfig(data)
      }
    } catch (error) {
      console.log('watch-table-error', error);
    }
  }

  // 将要暴露给父组件调用的方法,通过 useImperativeHandle 进行封装
  useImperativeHandle(ref, (): any => ({
    initTable: (form: object) => initTable(form)
  }));

  return (
    <GlobalTableWapper style={{ height: height }}>
      <Table columns={columns} dataSource={tableConfig.list.map((item: any) => ({ ...item, key: item.id }))} className="mt-20 table-height-pagination table-container" pagination={false} />
      <Pagination
        className='pagination-container flex-center'
        total={tableConfig?.total ?? 0}
        showSizeChanger
        showQuickJumper
        showTotal={(total) => `共 ${total} 条`}
      />
    </GlobalTableWapper>
  )
});

GlobalBox.displayName = 'GlobalBox'
export default memo(GlobalBox)

父组件使用

// 类型
import { ChildMethods } from '@/components/GlobalTableUi/type';

const tableRef = createRef<ChildMethods>()
// 方法使用
const getTableData = (data: object) => {
  tableRef.current?.initTable(data)
}
// 样式
<GlobalTableUi ref={tableRef} columns={columns} initData={postLiveRoomScriptPageList} />

type.ts

import type { ReactNode } from 'react'

export interface IProps {
  readonly ref?: any;
  readonly columns: Array<any>,
  readonly height?: number,
  form?: object,
  initData?: Function,
  children?: ReactNode,
}

export interface ChildMethods {
  initTable: (form: object) => void;
}