终于在实际项目中用到了泛型
里程碑式的纪录,终于不是anyScript了,代码写完只有一个any
应用
项目中组件化了这么一个东西
功能描述:
- 传进去一个数组,有个名,有个key,渲染成上图的div样式
- 点击之后,回调函数吐出点击的是哪一项
看下代码⬇️
import { useState } from 'react';
import styles from './index.less';
type Data = {
key: string;
name: string;
};
interface ButtonsGroupProps {
data: Data[];
defaultActive?: number;
clickButtonCallback: (data: Data) => void;
}
const Index = (props: ButtonsGroupProps) => {
const { data, defaultActive = 0, clickButtonCallback } = props;
const [activeButton, setActiveButton] = useState(defaultActive);
return (
<div className={styles.buttonGroupWrapper}>
{data.map((i, index) => (
<div
className={`${
activeButton === index ? styles.buttonItemActive : ''
} ${styles.buttonItem}`}
key={i.key}
onClick={(e) => {
e.stopPropagation();
setActiveButton(index);
clickButtonCallback(i);
}}
>
{i.name}
</div>
))}
</div>
);
};
export default Index;
再看下外面怎么用:
type TypeKey = 'zj' | 'zh';
const buttonGroup = useMemo<{ key: TypeKey; name: string }[]>(
() => [
{
key: 'zj',
name: '资金',
},
{
key: 'zh',
name: '账户',
},
],
[],
);
<ButtonGroup
data={buttonGroup}
clickButtonCallback={(data) => {
setCurrentType(data.key as TypeKey);
}}
/>
问题出现了
setCurrentType(data.key as TypeKey);
原因:
返回的key在是string,而用的时候定义了TypeKey
为啥要定义TypeKey而不直接string呢?
外面的key定义了文字字符串类型,因为不多,所以定死感觉比较好。
然后又来一个type TypeKey = 'ys' | 'yf';
虽然as也没有问题,肯定会是TypeKey。但是强迫症感觉有点难受
这时候就想到了泛型
组件内进行改造⬇️
首先Key的类型
type Data<T> = {
key: T;
name: string;
};
然后props的类型
interface ButtonsGroupProps<T> {
data: Data<T>[];
defaultActive?: number;
clickButtonCallback: (data: Data<T>) => void;
}
最后函数接受一下T,
const Index = <T extends React.Key>(props: ButtonsGroupProps<T>) => {
const { data, defaultActive = 0, clickButtonCallback } = props;
const [activeButton, setActiveButton] = useState(defaultActive);
return (
<div className={styles.buttonGroupWrapper}>
{data.map((i, index) => (
<div
className={`${
activeButton === index ? styles.buttonItemActive : ''
} ${styles.buttonItem}`}
key={i.key}
onClick={(e) => {
e.stopPropagation();
setActiveButton(index);
clickButtonCallback(i);
}}
>
{i.name}
</div>
))}
</div>
);
};
export default Index;
Okk,在看一下外面
吐出来的也是T了,就不需要as
了