【react】搜索组件封装

本文介绍了如何使用React开发一个功能丰富的组件,它具备搜索功能,并在无输入时展示走马灯效果。组件接收父组件传递的值和数据,利用防抖技术处理搜索请求,并通过定时器实现数据轮播。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

功能:实现搜索功能,并且当搜索框中没有值的时候,搜索框中以走马灯的形式显示数据。

在data.d.ts中

interface RevolvingDoorProps {
  getValues: (val) => void; // 传给父组件 搜索框中的值
  list; // 父组件传入走马灯的数据
  values: string;  // 父组件传过来的值 (搜索框中)
}
export type { RevolvingDoorProps };

在index.tsx中

import { Search } from '@nascent/nui';
import React, { useEffect, useRef, useState } from 'react';
import type { RevolvingDoorProps } from './data';
import { ContentArea } from './styled';
import { useDebounce, useUpdateEffect } from 'ahooks';
const RevolvingDoor: React.FC<RevolvingDoorProps> = (props) => {
  const { getValues, list, values } = props;
  const [value, setValue] = useState(undefined) as any;
  const debouncedValue = useDebounce(value, { wait: 1000 }); // 用来处理防抖值的 Hook。

  useEffect(() => {
    if (values) {
      setValue(values);
    }
  }, [values]);
  let timer: any = null;
  const contentBox = useRef<any>();
  const parent = useRef<any>();
  const parentTwo = useRef<any>();

  const handleSearch = (val: any) => {
    setValue(val);
  };
  useUpdateEffect(() => {
    getValues(debouncedValue); // 返回给父组件的值
  }, [debouncedValue]);

  useEffect(() => {
    if (list?.length && contentBox.current && parent.current && parentTwo.current) {
      parentTwo.current.innerHTML = parent.current.innerHTML;
      const autoScrollLine = () => {
        if (!contentBox.current) return;
        /*判断滚动内容是否已经滚完,滚完了则滚动的值重新设置到0
      否则就每隔30毫秒向上滚动1px*/
        if (contentBox.current.scrollTop >= parent.current.offsetHeight) {
          contentBox.current.scrollTop = 0;
        } else {
          contentBox.current.scrollTop++;
        }
        /*判断滚动的距离刚好为一条公告的高度时停掉定时器,
        隔1s之后重新启动定时器即可实现公告滚动停留效果 */
        if (contentBox.current.scrollTop % contentBox.current.offsetHeight == 0) {
          clearInterval(timer);
          setTimeout(() => {
            timer = setInterval(autoScrollLine, 30);
          }, 1000);
        }
      };
      // eslint-disable-next-line react-hooks/exhaustive-deps
      timer = setInterval(autoScrollLine, 30);
    }
    return () => {
      timer = null;
    };
  }, [list]);

  return (
    <ContentArea zIndex={value}>
      <Search.Input
        bordered="none"
        style={{ width: 240 }}
        placeholder={list && list.length > 0 ? '' : '搜索菜单…'}
        value={value}
        onSearch={handleSearch}
      />
      <div className="scroll-box" ref={contentBox}>
        <div ref={parent}>
          {list &&
            list.map((item: { menu_name: string }) => (
              <span key={item.menu_name}>{item.menu_name}</span>
            ))}
        </div>
        <div ref={parentTwo} />
      </div>
    </ContentArea>
  );
};

export default React.memo(RevolvingDoor);

在styled.ts中

import styled from 'styled-components';

const ContentArea = styled.div<{
  zIndex: string;
}>`
  .ant-search-input-icon {
    color: rgba(0, 0, 0, 0.85);
  }
  position: relative;
  .scroll-box {
    position: absolute;
    top: 8px;
    left: 36px;
    z-index: ${(p: { zIndex: any }) => (p.zIndex ? -1 : 2)};
    width: 204px;
    height: 32px;
    overflow: hidden;
    line-height: 32px;
    pointer-events: none;
    div {
      margin: 0;
      span {
        display: block;
        color: #bfbfbf;
        font-size: 14px;
      }
    }
  }
`;
export { ContentArea };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值