react函数式编程实现具名插槽

676 阅读1分钟

需求

最近在自己的react hooks项目中,需要封装一个公共组件;由于react没有像vue一样提供具名插槽的使用。所以,在自己react hooks项目中简单的封装了一个类似具名插槽的功能。

核心思想

利用props属性,在父组件传入对应名字的方法,子组件获取调用解析返回即可。

核心代码

以react + antd@5实现对Description组件的二次封装为例

// CDescription.jsx
// CDescription.jsx的二次封装
import React from 'react';
import { Descriptions } from 'antd';

export default function CDescription(props) {
  return (
    <Descriptions
      bordered={props.bordered}
    >
      {props.descItemList.map( (item, index) => (
        <Descriptions.Item key={index} label={item.label}>
          {/* 此处实现具名插槽,如果有该对应的方法就执行该方法,否则就直接获取后面的属性 */}
          {props[item.prop] && typeof props[item.prop] == 'function' ? props[item.prop](props.descData[item.prop]) : props.descData[item.prop]}
        </Descriptions.Item>
      ))}
    </Descriptions>
  )
}

CDescription.defaultProps = {
  bordered: true
};



// 使用
// 调用组件 UserDetail.jsx
import CDescription from '@/components/CDescription/CDescription';
import { Col, Row } from 'antd'
import React from 'react'

export default function UserDetail() {
  const DescriptConfig = [
    {
      label: '用户姓名',
      prop: 'name'
    },
    {
      label: '用户名',
      prop: 'username'
    },
    {
      label: '联系方式',
      prop: 'phone'
    },
    {
      label: '地址',
      prop: 'address'
    }
  ];
  const data = {
    name: 'testName',
    username: 'name',
    phone: '112233445566',
    address: '1234'
  }
  return (
    <Row>
      <Col span={24}>
        <CDescription descItemList={DescriptConfig} descData={data} address={(scope) => {
          return (<div>
            123456
          </div>)
        }}></CDescription>
      </Col>
    </Row>
  )
}