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

相关文章
|
13天前
|
前端开发 JavaScript 测试技术
React 分页组件 Pagination
本文介绍了如何在 React 中从零构建分页组件,涵盖基础概念、常见问题及解决方案。通过示例代码详细讲解了分页按钮的创建、分页按钮过多、初始加载慢、状态管理混乱等常见问题的解决方法,以及如何避免边界条件、性能优化和用户反馈等方面的易错点。旨在帮助开发者更好地理解和掌握 React 分页组件的开发技巧,提升应用的性能和用户体验。
43 0
|
17天前
|
移动开发 前端开发 API
React 拖拽组件 Drag & Drop
本文介绍了在 React 中实现拖拽功能的方法,包括使用原生 HTML5 Drag and Drop API 和第三方库 `react-dnd`。通过代码示例详细讲解了基本的拖拽实现、常见问题及易错点,帮助开发者更好地理解和应用拖拽功能。
47 9
|
12天前
|
前端开发 UED 开发者
React 分页组件 Pagination
本文介绍了如何在 React 中实现分页组件,从基础概念到常见问题及解决方案。分页组件用于将大量数据分成多个页面,提升用户体验。文章详细讲解了分页组件的基本结构、快速入门步骤、以及如何处理页面跳转不平滑、页码过多导致布局混乱、边界条件处理和数据加载延迟等问题。通过本文,读者可以全面了解并掌握 React 分页组件的开发技巧。
18 2
|
16天前
|
设计模式 前端开发 编译器
与普通组件相比,React 泛型组件有哪些优势?
与普通组件相比,React 泛型组件有哪些优势?
32 6
|
18天前
|
前端开发 UED
React 模态框 Modal 组件详解
【10月更文挑战第27天】本文介绍了如何在 React 中实现一个功能完善的模态框组件。从基础概念入手,逐步讲解了简单的模态框实现、CSS 样式、传递子组件、键盘事件处理等高级功能。同时,还探讨了常见问题及易错点,如背景点击关闭、键盘事件冲突和动画效果。通过本文,读者可以全面了解 React 模态框组件的实现细节。
35 0
|
6月前
|
设计模式 前端开发 数据可视化
【第4期】一文了解React UI 组件库
【第4期】一文了解React UI 组件库
362 0
|
6月前
|
存储 前端开发 JavaScript
【第34期】一文学会React组件传值
【第34期】一文学会React组件传值
77 0
|
6月前
|
前端开发
【第31期】一文学会用React Hooks组件编写组件
【第31期】一文学会用React Hooks组件编写组件
79 0
|
6月前
|
存储 前端开发 JavaScript
【第29期】一文学会用React类组件编写组件
【第29期】一文学会用React类组件编写组件
76 0
|
6月前
|
资源调度 前端开发 JavaScript
React 的antd-mobile 组件库,嵌套路由
React 的antd-mobile 组件库,嵌套路由
122 0
下一篇
无影云桌面