首页 > 解决方案 > 我有一个搜索功能,只有在输入第二个字母后才有效

问题描述

所以我有一个基本的信使反应应用程序。

然而,我的搜索功能只有在我输入第二个字母后才起作用。怎么回事?我猜它必须与我的 onChange 处理程序或 e.target.value 做些什么?

此外,当我退格时,我的 setSearch 钩子不会清除为空的“”。

输入第一个字母“f”

第一个字母

输入第二个字母“u”

第二个字母

代码

import { Avatar, IconButton } from '@material-ui/core';
import React, { useEffect, useState } from 'react';
import './Sidebar.css';
import SearchIcon from '@material-ui/icons/Search';
import { RateReviewOutlined } from '@material-ui/icons';
import { SidebarChat } from './SidebarChat';
import { useSelector } from 'react-redux';
import { selectUser } from './features/userSlice';
import db, { auth } from './firebase';

import { makeStyles } from '@material-ui/core/styles';
import Modal from '@material-ui/core/Modal';
import Backdrop from '@material-ui/core/Backdrop';
import Fade from '@material-ui/core/Fade';

const useStyles = makeStyles((theme) => ({
  modal: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  },
  paper: {
    backgroundColor: theme.palette.background.paper,
    border: '2px solid #000',
    boxShadow: theme.shadows[5],
    padding: theme.spacing(2, 4, 3),
  },
}));

export function Sidebar(props) {
  const user = useSelector(selectUser);
  const [chats, setChats] = useState([]);
  const classes = useStyles();
  const [open, setOpen] = useState(false);
  const [search, setSearch] = useState('');

  const handleOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  useEffect(() => {
    db.collection('chats').onSnapshot((snapshot) =>
      setChats(
        snapshot.docs.map((doc) => ({
          id: doc.id,
          data: doc.data(),
        }))
      )
    );
  }, []);

  const addChat = () => {
    const chatName = prompt('Please enter a chat name');
    if (chatName) {
      db.collection('chats').add({
        chatName: chatName,
      });
    }
  };

  const searchFunction = (e) => {
    setSearch(e);
    console.log(search);
    console.log(chats);
    const filtered = chats.filter((chat) => {
      return chat.data.chatName.toLowerCase().includes(search.toLowerCase());
    });
    // console.log(filtered)
    setChats(filtered);
  };
  return (
    <div className="sidebar">
      <div className="sidebar__header">
        <Avatar
          onClick={handleOpen}
          src={user.photo}
          className="sidebar__avatar"
        />
        <div className="sidebar__input">
          <SearchIcon />
          <input
            placeholder="Search"
            value={search}
            onChange={(e) => searchFunction(e.target.value)}
          />
        </div>
        <IconButton variant="outlined" className="sidebar__inputButton">
          <RateReviewOutlined onClick={addChat} />
        </IconButton>
      </div>
      <div className="sidebar__chats">
        {chats.map(({ id, data: { chatName } }) => (
          <SidebarChat key={id} id={id} chatName={chatName} />
        ))}
      </div>

      <Modal
        aria-labelledby="transition-modal-title"
        aria-describedby="transition-modal-description"
        className={classes.modal}
        open={open}
        onClose={handleClose}
        closeAfterTransition
        BackdropComponent={Backdrop}
        BackdropProps={{
          timeout: 500,
        }}
      >
        <Fade in={open}>
          <div className={classes.paper}>
            <h2 id="transition-modal-title">
              Are you sure you want to sign out?
            </h2>
            <button onClick={() => auth.signOut()}>Yes</button>
            <button onClick={handleClose}>No</button>
          </div>
        </Fade>
      </Modal>
    </div>
  );
}

标签: reactjsreact-hooks

解决方案


在 searchFunction 中,您正在根据搜索值的当前状态更新聊天,而不是您要设置的状态。您应该根据 searchFunction e中的参数过滤您的聊天。

为了进一步澄清,即使您在调用setSearch(e)之前先调用setChats(filtered),这两个状态更新也会同时发生。因此,状态值search尚未更新为新值。


推荐阅读