React+hook+ts+ant design封装一个input和select搜索的组件

简介: React+hook+ts+ant design封装一个input和select搜索的组件
+关注继续查看

需求分析

首先 我们需要实现一个带有搜索功能的搜索框 本次只实现两种框的搜索功能 一种input 一种select

功能思维

image.png

第一步 初始版本

先写出一个input和一个render 还有两个按钮

<Form.Item
                label="测试数据"
                key="1"
                name="测试数据"
                rules={xxx}
                style={xxx}
            >
                {true ? <Select/> : <Input />}
            </Form.Item>
            <Form.Item>
                <Button htmlType="submit">查询</Button>
            </Form.Item>
            <Form.Item>
                <Button htmlType="reset" onClick={reset}>
                    重置
                </Button>
            </Form.Item>

开始升级版本(动态渲染搜索框)

接下来可以将搜索的数据改为动态渲染 因为按钮可以固定了 值从父级传入

{props.formList.map((item: SearchFormItem) => (
                <Form.Item
                    label={props.showLabel !== false && item.label ? item.label : ''}
                    key={item.name}
                    name={item.name}
                    rules={item.rules}
                    style={{ width: `${item.width}px` }}
                >
                    {item.render ? item.render : <Input placeholder={item.placeholder} />}
                </Form.Item>
            ))}

继续升级(方法通过子传父)

function SearchForm(props: SearchFormProps) {
    const [form] = Form.useForm();

    const reset = () => {
        form.resetFields();
        props.onSearch({});
    };

    const onSearch = () => {
        form.validateFields().then(res => {
            props.onSearch(res);
        });
    };

    return (
        <Form className="layout__search" form={form} layout="inline" onFinish={onSearch}>
            {props.formList.map((item: SearchFormItem) => (
                <Form.Item
                    label={props.showLabel !== false && item.label ? item.label : ''}
                    key={item.name}
                    name={item.name}
                    rules={item.rules}
                    style={{ width: `${item.width}px` }}
                >
                    {item.render ? item.render : <Input placeholder={item.placeholder} />}
                </Form.Item>
            ))}
            <Form.Item>
                <Button htmlType="submit">查询</Button>
            </Form.Item>

            <Form.Item>
                <Button htmlType="reset" onClick={reset}>
                    重置
                </Button>
            </Form.Item>
            {
                props.actions.map((action: SearchFormAction, index: number) => (
                    <Form.Item key={action.name}>
                        <Button type={action.type} onClick={() => props.onClick(index)}>
                            {action.name}
                        </Button>
                    </Form.Item>
                ))
            }
        </Form >
    );
}

继续升级(ts限定数据类型)

import React, { memo } from 'react';
import { Button, Input, Form } from 'antd';
import { ButtonType } from 'antd/es/button/button';
import './index.less';

export interface SearchFormAction {
    name: string;
    type?: ButtonType;
}

export interface SearchFormItem {
    name: string;
    label: string;
    placeholder?: string;
    rules?: object[];
    render?: React.ReactElement;
    width?: any
}

interface SearchFormProps {
    formList: SearchFormItem[];
    onSearch: (values: any) => void;
    actions: SearchFormAction[];
    onClick: (index: number) => void;
    showLabel?: boolean;
    width?: any
}

function SearchForm(props: SearchFormProps) {
    const [form] = Form.useForm();

    const reset = () => {
        form.resetFields();
        props.onSearch({});
    };

    const onSearch = () => {
        form.validateFields().then(res => {
            props.onSearch(res);
        });
    };

    return (
        <Form className="layout__search" form={form} layout="inline" onFinish={onSearch}>
            {props.formList.map((item: SearchFormItem) => (
                <Form.Item
                    label={props.showLabel !== false && item.label ? item.label : ''}
                    key={item.name}
                    name={item.name}
                    rules={item.rules}
                    style={{ width: `${item.width}px` }}
                >
                    {item.render ? item.render : <Input placeholder={item.placeholder} />}
                </Form.Item>
            ))}
            <Form.Item>
                <Button htmlType="submit">查询</Button>
            </Form.Item>

            <Form.Item>
                <Button htmlType="reset" onClick={reset}>
                    重置
                </Button>
            </Form.Item>
            {
                props.actions.map((action: SearchFormAction, index: number) => (
                    <Form.Item key={action.name}>
                        <Button type={action.type} onClick={() => props.onClick(index)}>
                            {action.name}
                        </Button>
                    </Form.Item>
                ))
            }
        </Form >
    );
}

export default memo(SearchForm);

看看父组件的使用

<Card>
                <SearchForm
                    formList={formList}
                    actions={actions}
                    onSearch={onSearch}
                    onClick={onAddMenu}
                    showLabel={true}
                ></SearchForm>
            </Card>

formList搜索表单值

const formList = useMemo<SearchFormItem[]>(
        () => [
            {
                width: 280,
                name: 'factoryId',
                placeholder: '请选择所属工厂',
                label: '所属工厂',
                render: (
                    <Select
                        style={{ width: '100%' }}
                        placeholder="请选择所属工厂"
                        optionFilterProp="children"
                    >
                        {factoryDataList && factoryDataList.map((item: any) => (
                            <Option value={item.id}>{item.name}</Option>
                        ))}
                    </Select>
                )
            },
        ],
        [],
    );

actions按钮值

const actions = useMemo<SearchFormAction[]>(
        () => [
            {
                name: '新建',
                type: 'primary',
            },
        ],
        [],
    );

onSearch子传父方法值

const onSearch = useCallback(
        (params: MenuSearchParams) => {
            initPageList(params);
        },
        [page],
    );

onAddMenu 控制弹框开启的值

const onAddMenu = useCallback(() => {
        setCurrentMenu(null);
        setEditVisible(true);
    }, []);

image.png

相关文章
|
10月前
|
前端开发 安全 JavaScript
【Message 全局提示】基于 React 实现 Message 组件
使用 ReactDOM.createRoot、React.forwardRef、React.useImperativeHandle 实现 Message 组件。使用 Web Crypto API 生成符合密码学要求的安全的随机 ID。
|
10月前
|
存储 前端开发 JavaScript
React 中非受控和受控的组件
React 中非受控和受控的组件
|
10月前
|
前端开发
react笔记之学习之添加card组件
react笔记之学习之添加card组件
102 0
react笔记之学习之添加card组件
|
10月前
|
前端开发
#yyds干货盘点# react笔记之学习之添加card组件
#yyds干货盘点# react笔记之学习之添加card组件
61 0
#yyds干货盘点# react笔记之学习之添加card组件
|
10月前
|
存储 前端开发 JavaScript
#yyds干货盘点# react笔记之学习之类组件
#yyds干货盘点# react笔记之学习之类组件
67 0
|
10月前
|
前端开发
#yyds干货盘点# react笔记之学习之state组件
#yyds干货盘点# react笔记之学习之state组件
66 0
|
10月前
|
前端开发
#yyds干货盘点# react笔记之学习之修改log组件
#yyds干货盘点# react笔记之学习之修改log组件
74 0
#yyds干货盘点# react笔记之学习之修改log组件
|
10月前
|
前端开发
#yyds干货盘点# react笔记之学习之使用组件完成练习
#yyds干货盘点# react笔记之学习之使用组件完成练习
44 0
#yyds干货盘点# react笔记之学习之使用组件完成练习
|
10月前
|
前端开发
#yyds干货盘点# 歌谣学前端之react笔记之学习之类组件
#yyds干货盘点# 歌谣学前端之react笔记之学习之类组件
52 0
|
10月前
|
前端开发
#yyds干货盘点# 歌谣学前端之react笔记之学习之函数组件
#yyds干货盘点# 歌谣学前端之react笔记之学习之函数组件
61 0
推荐文章
更多