【React工作记录七十七】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

相关文章
|
前端开发
React使用useRef ts 报错
【8月更文挑战第17天】
295 4
|
存储 前端开发 JavaScript
React 表单输入组件 Input:常见问题、易错点及解决方案
本文介绍了在 React 中使用表单输入组件 `Input` 的基础概念,包括受控组件与非受控组件的区别及其优势。通过具体代码案例,详细探讨了创建受控组件、处理多个输入字段、输入验证和格式化的方法,并指出了常见易错点及避免方法,旨在提升表单的健壮性和用户体验。
349 4
|
前端开发 算法 JavaScript
React项目input输入框输入自动失去焦点
本文讨论了在React项目中如何处理input输入框自动失去焦点的问题,特别是在移动端开发中。文章提供了一个使用React Native的TouchableWithoutFeedback组件来监听点击事件,并在事件处理函数中通过调用Keyboard.dismiss()方法使输入框失去焦点的示例代码。这种方法可以确保在用户点击页面其他区域时,键盘能够收起,输入框失去焦点。
534 1
React项目input输入框输入自动失去焦点
|
前端开发
react动态生成input、select标签以及思路总结
本文介绍了在React中动态生成input和select标签的方法,包括准备数据结构、在组件挂载时动态添加状态、页面渲染以及输入处理,最后总结了实现思路。
238 1
react动态生成input、select标签以及思路总结
|
资源调度 JavaScript 前端开发
使用vite+react+ts+Ant Design开发后台管理项目(二)
使用vite+react+ts+Ant Design开发后台管理项目(二)
|
前端开发 C++
使用 Vite 创建 React+TS+SW 项目并整合 AntDesign 、Scss 等组件或插件
本文记录了如何使用Vite创建一个React+TypeScript+Service Workers(SW)项目,并整合AntDesign组件库和Scss等插件,包括项目的创建、配置问题解决、AntDesign和Scss的整合方法。
1046 1
|
JavaScript 前端开发
react18【系列实用教程】双向绑定表单 (2024最新版)含受控组件、非受控组件、单行多行输入框 input,下拉选择 select,单选 radio,多选 checkbox,标签 label
react18【系列实用教程】双向绑定表单 (2024最新版)含受控组件、非受控组件、单行多行输入框 input,下拉选择 select,单选 radio,多选 checkbox,标签 label
353 1
|
JavaScript 前端开发 开发者
深入比较Input、Change和Blur事件:Vue与React中的行为差异解析
深入比较Input、Change和Blur事件:Vue与React中的行为差异解析
react使用ant desgin 组件实现便利开发
react使用ant desgin 组件实现便利开发
|
设计模式 前端开发 数据可视化
【第4期】一文了解React UI 组件库
【第4期】一文了解React UI 组件库
850 0