组件封装


组件封装

高亮关键词组件

传入整段话 和 关键词,

返回带高亮的整段话
export const Mark = ({ name, keyword }: { name: string; keyword: string }) => {
    // 可以直接用的高亮关键词组件 暂时不太懂    
    if (!keyword) {
        return <>{name}</>;
    }

  const arr = name.split(keyword);
  
  return (
        <>
            {arr.map((str, index) => (
                <span key={index}>
                {str}
                {index === arr.length - 1 ? null : (
                    <span style={{color: '#257ADF'}}>{keyword}</span>
                )}
                </span>
            ))}
        </>
    );
};

⭐️收藏组件

import { Rate } from "antd";

interface PinProps extends React.ComponentProps<typeof Rate> {
    check?: boolean;
    onCheckChange?: (check: boolean) => void;
}
const Pin = ({ check, onCheckChange, ...restProps }: PinProps) => {
    return (
        <Rate
        count={1}
        value={check ? 1 : 0}
        onChange={(num) => onCheckChange?.(!!num)}
        {...restProps}
        />
    );
};

export default Pin;
// use 

// 柯里化 传入函数,多个函数接收余下参数的技术。
const pinProject = (id: number) => (pin: boolean) => mutate({id, pin}); // 柯里化 refresh : 刷新列表

<Table
  pagination={false}
  columns={[
  {
    title: <Pin check={true} disabled={true} />,
    render: (value, project) => <Pin check={project.pin} onCheckChange={pinProject(project.id)} />
  },

数字select

无论是原生 select 还是 antd Select 都会将值默认转化为 string 类型,

这可能会造成错误。

这个组件传入的值可传入任意类型,

但统一会转化为数字类型。
import { Select } from "antd";
import { Raw } from "types"; //  Raw : string | number

type SelectProps = React.ComponentProps<typeof Select>

interface IdSelectProps extends Omit<SelectProps, 'value' | 'onChange' | 'defaultOptionName' | 'options'> {
    value?: Raw | null | undefined
    onChange?: (value?: number) => void
    defaultOptionName?: string
    options?: {name: string, id: number}[]
}

export const IdSelect = (props: IdSelectProps) => {
    const { value, onChange, defaultOptionName, options } = props;
 
    return (
        <Select value={options?.length ? toNumber(value) : 0} onChange={(value) => {
            onChange?. (toNumber(value) || undefined)
        }}>
            {defaultOptionName ? (
                <Select.Option value={0}>{defaultOptionName}</Select.Option>
            ) : null}
            {options?.map((option: any) => <Select.Option key={option.id} value={option.id}>{option.name}</Select.Option>)}
        </Select>
    );
};

const toNumber = (value: unknown) => isNaN(Number(value)) ? 0 : Number(value);
// use

/**
* 将请求的数据传入 Select 组件,外部直接调用 UseSelect 组件
*
* 这样的优点是 更具灵活性。
*
* 可以请求其他不同的接口,将数据传入
*/

import useUser from "logichooks/useUsers";
import React from "react";
import { IdSelect } from "./id-select";

export const UseSelect = (props: React.ComponentProps<typeof IdSelect>) => {
    const {data: user} = useUser();
    return <IdSelect options={user || []} {...props} />
};
// use

// 不传入onChange 直接使用

import { UseSelect } from "components/use-select";

<Form.Item label='经办人 ' name='processorId'>
    <UseSelect defaultOptionName="经办人" />
</Form.Item>

错误边界组件

import React from "react";

type FallBackRender = (props: {error : Error | null}) => React.ReactElement;
export class ErrorBoundary extends React.Component<React.PropsWithChildren<{fallBackrender: FallBackRender}>, any> {
    state: Readonly<any> = {
        error: null,
    }; 
    // 当子组件抛出异常 这里会收到并调用
    static getDerivedStateFormError(error: Error) {
        return {error};
    };

    render(): React.ReactNode {
        const {error} = this.state;
        const {fallBackrender , children} = this.props;

        if (error) {
            return fallBackrender(error);
        }
        return children;
    };
};

文章作者: KarlFranz
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 reprint policy. If reproduced, please indicate source KarlFranz !
评论
  目录