react antd 常用组件的二次封装

 微软的bing  ai 的简单使用

https://www.bing.com/

react antd 是一个基于 react 的 UI 组件库,提供了丰富的组件和设计规范。但是,有时候我们需要对它的组件进行二次封装,以适应不同的业务场景和需求。二次封装的目的是:

增加或修改组件的功能和样式
统一组件的使用方式和风格
简化组件的调用和传参
二次封装的方法是:

创建一个自定义组件,引入 antd 的组件
定义自定义组件的类型和属性,可以继承或扩展 antd 组件的类型和属性
在自定义组件中实现自己的渲染逻辑,可以使用 antd 组件提供的 API 和属性
将自定义组件需要透传给 antd 组件的属性,通过 rest 参数或解构赋值的方式传递给 antd 组件
例如,如果我们想要封装一个带有搜索和分页功能的下拉选择器,我们可以参考以下代码1:

// 引入 React 和 antd 的 Select 组件
import React from 'react';
import { Select } from 'antd';

// 定义自定义组件的类型和属性,继承 Select 组件的类型和属性,并添加自己需要的属性
interface SearchSelectProps extends SelectProps<any> {
  // 搜索关键字
  keyword: string;
  // 搜索函数,接收关键字和页码,返回 Promise
  onSearch: (keyword: string, page: number) => Promise<any>;
  // 每页显示条数,默认为 10
  pageSize?: number;
}

// 创建自定义组件,接收 props 参数
const SearchSelect: React.FC<SearchSelectProps> = (props) => {
  // 获取 props 中的属性,将需要透传给 Select 组件的属性放在 rest 中
  const { keyword, onSearch, pageSize = 10, ...rest } = props;

  // 定义 state,用来存储搜索结果和分页信息
  const [options, setOptions] = useState<any[]>([]);
  const [total, setTotal] = useState<number>(0);
  const [current, setCurrent] = useState<number>(1);

  // 定义搜索函数,根据关键字和页码调用 onSearch 函数,并更新 state
  const handleSearch = async (keyword: string, page: number) => {
    try {
      // 调用 onSearch 函数,获取返回结果
      const result = await onSearch(keyword, page);
      // 更新 options,total 和 current
      setOptions(result.data);
      setTotal(result.total);
      setCurrent(page);
    } catch (error) {
      // 处理错误情况
      console.error(error);
    }
  };

  // 定义分页函数,根据方向参数调用搜索函数,并更新页码
  const handlePagination = (direction: 'prev' | 'next') => {
    // 根据方向参数计算新的页码
    const newPage = direction === 'prev' ? current - 1 : current + 1;
    // 调用搜索函数,并更新 current
    handleSearch(keyword, newPage);
    setCurrent(newPage);
  };

  // 使用 useEffect 钩子,在 keyword 或 pageSize 变化时调用搜索函数,并重置页码为 1
  useEffect(() => {
    handleSearch(keyword, 1);
    setCurrent(1);
  }, [keyword, pageSize]);

  // 返回自定义组件的 JSX 元素,使用 Select 组件,并传递 rest 参数和其他自定义属性
  return (
    <Select {...rest}>
      {/* 遍历 options 数组,生成 Option 子元素 */}
      {options.map((option) => (
        <Select.Option key={option.value} value={option.value}>
          {option.label}
        </Select.Option>
      ))}
      {/* 如果有分页信息,生成 Pagination 子

优化一下这个代码

当然,我很乐意帮你优化这个代码。我有一些建议:

你可以使用 useCallback 钩子,来缓存 handleSearch 和 handlePagination 函数,避免每次渲染时重新创建函数,提高性能
你可以使用 useMemo 钩子,来缓存 options 数组,避免每次渲染时重新生成 JSX 元素,提高性能
你可以使用 antd 的 Pagination 组件,来替换自定义的分页逻辑,简化代码,提高可读性
优化后的代码如下:

// 引入 React 和 antd 的 Select 和 Pagination 组件
import React, { useCallback, useMemo } from 'react';
import { Select, Pagination } from 'antd';

// 定义自定义组件的类型和属性,继承 Select 组件的类型和属性,并添加自己需要的属性
interface SearchSelectProps extends SelectProps<any> {
  // 搜索关键字
  keyword: string;
  // 搜索函数,接收关键字和页码,返回 Promise
  onSearch: (keyword: string, page: number) => Promise<any>;
  // 每页显示条数,默认为 10
  pageSize?: number;
}

// 创建自定义组件,接收 props 参数
const SearchSelect: React.FC<SearchSelectProps> = (props) => {
  // 获取 props 中的属性,将需要透传给 Select 组件的属性放在 rest 中
  const { keyword, onSearch, pageSize = 10, ...rest } = props;

  // 定义 state,用来存储搜索结果和分页信息
  const [options, setOptions] = useState<any[]>([]);
  const [total, setTotal] = useState<number>(0);
  const [current, setCurrent] = useState<number>(1);

  // 使用 useCallback 钩子,缓存搜索函数,根据关键字和页码调用 onSearch 函数,并更新 state
  const handleSearch = useCallback(async (keyword: string, page: number) => {
    try {
      // 调用 onSearch 函数,获取返回结果
      const result = await onSearch(keyword, page);
      // 更新 options,total 和 current
      setOptions(result.data);
      setTotal(result.total);
      setCurrent(page);
    } catch (error) {
      // 处理错误情况
      console.error(error);
    }
  }, [onSearch]);

  // 使用 useEffect 钩子,在 keyword 或 pageSize 变化时调用搜索函数,并重置页码为 1
  useEffect(() => {
    handleSearch(keyword, 1);
    setCurrent(1);
  }, [keyword, pageSize, handleSearch]);

  // 使用 useMemo 钩子,缓存 options 数组,生成 Option 子元素
  const optionElements = useMemo(() => {
    return options.map((option) => (
      <Select.Option key={option.value} value={option.value}>
        {option.label}
      </Select.Option>
    ));
  }, [options]);

  // 返回自定义组件的 JSX 元素,使用 Select 组件,并传递 rest 参数和其他自定义属性
  return (
    <Select {...rest}>
      {/* 渲染 optionElements */}
      {optionElements}
      {/* 如果有分页信息,使用 Pagination 组件,并传递相关属性 */}
      {total > pageSize && (
        <Pagination
          size="small"
          current={current}
          total={total}
          pageSize={pageSize}
          onChange={(page) => handleSearch(keyword, page)}
        />
      )}
    </Select>

你能解释一下 useCallback 和 useMemo 的区别吗?

​
useCallback 和 useMemo 都是 React 的自定义钩子,用来缓存函数或值,避免不必要的渲染或计算。它们的区别是:

useCallback 返回一个函数,当把它返回的这个函数作为子组件的 props 时,可以避免每次父组件更新时都重新渲染这个子组件12。
useMemo 返回一个值,当这个值是由复杂的计算得到的时,可以避免每次渲染时都重新计算这个值34。
使用 useCallback 和 useMemo 时,需要注意以下几点:

它们都接收两个参数,第一个参数是函数,第二个参数是依赖项的数组。只有当依赖项改变时,才会重新执行函数并返回新的函数或值。
它们都有一定的性能成本,因为需要调用内置的钩子、防止依赖项和缓存的函数或值被垃圾回收、检查依赖项是否改变等。所以不要滥用它们,只在必要的情况下使用它们5。
它们都可能导致代码的复杂度增加,所以要确保依赖项数组中包含了所有需要的依赖项,并且尽量保持代码的可读性和可维护性。
已收到消息. useCallback 和 useMemo 都是 React 的自定义钩子,用来缓存函数或值,避免不必要的渲染或计算。它们的区别是: - useCallback 返回一个函数,当把它返回的这个函数作为子组件的 props 时,可以避免每次父组件更新时都重新渲染这个子组件 。 - useMemo 返回一个值,当这个值是由复杂的计算得到的时,可以避免每次渲染时都重新计算这个值 。 使用 useCallback 和 useMemo 时,需要注意以下几点: - 它们都接收两个参数,第一个参数是函数,第二个参数是依赖项的数组。只有当依赖项改变时,才会重新执行函数并返回新的函数或值。 - 它们都有一定的性能成本,因为需要调用内置的钩子、防止依赖项和缓存的函数或值被垃圾回收、检查依赖项是否改变等。所以不要滥用它们,只在必要的情况下使用它们。 - 它们都可能导致代码的复杂度增加,所以要确保依赖项数组中包含了所有需要的依赖项,并且尽量保持代码的可读性和可维护性。

​

猜你喜欢

转载自blog.csdn.net/weixin_46600931/article/details/130095045