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

相关文章
|
7月前
|
设计模式 前端开发 数据可视化
【第4期】一文了解React UI 组件库
【第4期】一文了解React UI 组件库
373 0
|
7月前
|
存储 前端开发 JavaScript
【第34期】一文学会React组件传值
【第34期】一文学会React组件传值
79 0
|
7月前
|
前端开发
【第31期】一文学会用React Hooks组件编写组件
【第31期】一文学会用React Hooks组件编写组件
82 0
|
7月前
|
存储 前端开发 JavaScript
【第29期】一文学会用React类组件编写组件
【第29期】一文学会用React类组件编写组件
78 0
|
7月前
|
前端开发 开发者
【第26期】一文读懂React组件编写方式
【第26期】一文读懂React组件编写方式
65 0
|
7月前
|
资源调度 前端开发 JavaScript
React 的antd-mobile 组件库,嵌套路由
React 的antd-mobile 组件库,嵌套路由
127 0
|
7月前
|
前端开发 JavaScript 安全
使用React、TypeScript和Ant Design构建现代化前端应用
使用React、TypeScript和Ant Design构建现代化前端应用
201 0
|
7月前
|
存储 前端开发 中间件
React组件间的通信
React组件间的通信
54 1
|
7月前
|
前端开发 JavaScript API
React组件生命周期
React组件生命周期
122 1
|
7月前
|
存储 前端开发 JavaScript
探索 React Hooks 的世界:如何构建出色的组件(下)
探索 React Hooks 的世界:如何构建出色的组件(下)
探索 React Hooks 的世界:如何构建出色的组件(下)