React 组件抽离
组件抽离的目的
提高代码开发效率,减少重复代码输出
原则
1、数据驱动
组件提取,必须是由数据来控制组件的表现形式,否则就失去了组件的通用性。
2、可扩展
一个成功的组件,首先需要满足基础的使用,其次需要接受自定义样式和内容。
当你理解到抽离组件的两大原则,此时,你已经可以独立进行组件抽离。
接下来,以key-value基础展示为例子,抽离组件。
import React, { useEffect, useState, useRef } from 'react';
import { isEmpty as _isEmpty } from 'lodash';
import { Empty, Tooltip } from 'antd';
import { formatDataToNameMap } from '@/utils/utils';
import classnames from 'classnames';
import { DEFAULT_VALUE } from '@/common/constants';
import styles from './styles.less';
interface Props {
data: { [key: string]: any };
nameMap: { [key: string]: any };
customFormat?: { [key: string]: (value: any) => any };
className?: string;
title?: string;
limitWidth?: number;
defaultShowPro?: boolean;
}
export default function BaseInfo(props: Props) {
const {
data,
nameMap,
customFormat,
className = '',
title = '',
limitWidth = 400,
defaultShowPro = true,
} = props;
const curRef = useRef() as React.MutableRefObject<any>;
const [showPro, setShowPro] = useState(false);
const cls = classnames(styles.record, className);
const renderContent = () => {
if (_isEmpty(data)) {
return <Empty />;
}
const tmp = formatDataToNameMap(nameMap, data, DEFAULT_VALUE, customFormat);
const info = Object.entries(tmp);
return info.map((x: any) => {
const [key, value] = x;
return (
<div className={cls} key={`kv-${x.toString()}`}>
<span className={styles.label}>{key}:</span>
<div className={styles.content} ref={curRef}>
<div>
{/* 渲染气泡卡片 */}
{defaultShowPro && showPro ? (
<Tooltip title={value} placement="topLeft">
<span>{value}</span>
</Tooltip>
) : (
<span>{value}</span>
)}
</div>
</div>
</div>
);
});
};
useEffect(() => {
const width = curRef.current ? curRef.current.offsetWidth : 0;
if (width > limitWidth) {
setShowPro(true);
}
}, [curRef.current]);
return (
<div className={styles.container}>
{!_isEmpty(data) && title && <h3 className={styles.title}>{title}</h3>}
{renderContent()}
</div>
);
}
组件的使用
import React from 'react';
export default function Index(props: Props) {
const data = {
device: ['switch','fsfs','tewiyrv'],
product: 'Dropbear sshd',
service: 'http',
version: '7.6.7',
timestamp: '2021-07-11T22:04:17.504440697+08:00',
};
const nameMap = {
timestamp: '更新时间',
product: '组件',
version: '版本',
service: '服务',
device: '设备类型',
};
return (
<BaseInfo
data={data}
nameMap={nameMap}
customFormat={{ timestamp: timeFormat, device: tags }}
/>
);
}