簡體   English   中英

如何在這個 React 組件中去抖動搜索 function?

[英]How to debounce search function in this React Component?

我有一個組件,它獲取員工列表作為道具。 我還創建了一個輸入元素,用於按字符串過濾列表。 我將過濾邏輯移動到 function 中,它需要一個數據列表和一個搜索值,因此它可以返回過濾后的列表。

我想在搜索輸入中添加 lodash debounce,所以每當用戶輸入內容時,它會等待 1 秒並將列表過濾掉。

import React from 'react';
import _ from "lodash"

import { IEmployee } from '../../../store/EmployeesStore/reducer'

import AddEmployee from '../AddEmployee/AddEmployee';
import EmployeeItem from './EmployeeItem/EmployeeItem';

import { TextField } from '@material-ui/core';
import InputAdornment from '@material-ui/core/InputAdornment';
import SearchIcon from '@material-ui/icons/Search';

export interface EmployeeProps {
  employees: IEmployee[];
}

class EmployeeList extends React.Component<EmployeeProps> {
  state = {
    searchValue: ''
  };

//function which returns filtered list
  filterList = (employeesList: IEmployee[], searchValue: string) => { 

    return employeesList.filter((item: any) => {
      const fullName = `${item.firstName}${item.lastName}`.toLowerCase();
      const reversedFullName = `${item.lastName}${item.firstName}`.toLowerCase();
      const trimmedSearchValue = searchValue
        .replace(/\s+/g, '')
        .toLowerCase();
      return (
        fullName.includes(trimmedSearchValue) ||
        reversedFullName.includes(trimmedSearchValue)
      );
    });
  };

  render() {
    // saving filtered list data in filteredList variable
    let filteredList = this.filterList(this.props.employees, this.state.searchValue)
      
    return (
      <>
        <AddEmployee />
        <TextField
          style={{ marginLeft: '20px' }}
          size="medium"
          id="input-with-icon-textfield"
          variant="outlined"
          value={this.state.searchValue}
          onChange={(e) => this.setState({ searchValue: e.target.value })}
          InputProps={{
            endAdornment: (
              <InputAdornment position="end">
                <SearchIcon />
              </InputAdornment>
            ),
          }}
          InputLabelProps={{
            shrink: true,
          }}
        />
        <div>
          <ul
            style={{
              margin: '0px',
              padding: '0px',
              listStyle: 'none',
              display: 'flex',
              flexWrap: 'wrap',
            }}
          >
            {filteredList.map((employee) => {
              return <EmployeeItem key={employee.id} {...employee} />;
            })}
          </ul>
        </div>
      </>
    );
  }
}

export default EmployeeList;

我應該在哪里添加 _.debounce function 以及如何添加?

您不應該在 return 語句中調用您的 filterList function,而是必須在 TextField 的 onChange 上調用它。

像這樣的東西:

handleChange = (e) => {
    this.setState({ searchValue: e.target.value })};
    const debouncedCall = _.debounce(() => this.filterList(this.props.employees, e.target.value), 1000);
    debouncedCall();    
}

//Rest of your code

render() {
   <TextField
        onChange={(e) => handleChange(e)}
        ...other attributes
   />
}

僅顯示相關更改:-

constructor (props) {
super(props)
this.state = {
    searchValue: ''
  };
this.debouncedHandler = _.debounce(this.handleChange.bind(this),1000);
}
handleChange = (e) => {
    this.setState({ searchValue: e.target.value })};
}
        <TextField
          style={{ marginLeft: '20px' }}
          size="medium"
          id="input-with-icon-textfield"
          variant="outlined"
          value={this.state.searchValue}
          onChange={this.debouncedHandler}
          InputProps={{
            endAdornment: (
              <InputAdornment position="end">
                <SearchIcon />
              </InputAdornment>
            ),
          }}
          InputLabelProps={{
            shrink: true,
          }}
        />

解釋:我們通過onChange重復調用debouncedHandler ,因此我們需要確保僅在1000毫秒的突發結束后才觸發handleChange ,並且在此持續時間內沒有調用debouncedHandler 如果在該突發間隔內發生另一個對debouncedHandler的調用,則開始一個新的突發間隔。

從您的組件的角度來看,除非用戶在 1000 毫秒內沒有在TextField組件中輸入任何其他字符,否則我們每次都會將在handleChange內部的主邏輯的執行延遲1000 1000ms ,一旦1000毫秒結束, setState將被觸發到 state state ---> 表示重新渲染 -----> 表示新的過濾列表並將其顯示給用戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM