过滤列表在 React 中有一次击键延迟

Filter a list has one keystroke lag in React

我正在尝试做一个简单的 Filter 组件来过滤带有输入的列表。

问题是列表的呈现有一次击键延迟。

例如: 我输入 'a' 没变化 我输入另一个 'a' 所以过滤器看起来像“aa” 该列表根据字符串 "a"

的先前状态进行过滤

我知道 setState 是异步的,但我不知道如何使用良好的做法。

index.js

import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(<App />, document.getElementById("root"));

App.js

import React, { useState, useEffect } from "react";
import axios from "axios";

const Filter = ({ countries, setCountriesToShow }) => {
  const [filter, setFilter] = useState("");

  const handleOnChangeEvent = (e) => {
    setFilter(e.target.value);
    setCountriesToShow(
      countries.filter((country) => {
        return country.name.toLowerCase().startsWith(filter.toLowerCase());
      })
    );
  };

  return (
    <div>
      find countries
      <input onChange={handleOnChangeEvent} />
    </div>
  );
};

const App = () => {
  const [countries, setCountries] = useState([]);
  const [countriesToShow, setCountriesToShow] = useState([]);

  useEffect(() => {
    axios.get("https://restcountries.eu/rest/v2/all").then((response) => {
      console.log(response.data);
      setCountries(response.data);
      setCountriesToShow(response.data);
    });
  }, []);

  return (
    <div>
      <Filter countries={countries} setCountriesToShow={setCountriesToShow} />
      {countriesToShow.map((country) => {
        return <li key={country.name}>{country.name}</li>;
      })}
    </div>
  );
};

export default App;

状态更新不会立即反映出来。因此,当您尝试过滤时,请使用从输入元素而不是状态

接收的输入
const handleOnChangeEvent = (e) => {
    const newFilter = e.target.value;
    setFilter(newFilter);
    setCountriesToShow(
      countries.filter((country) => {
        return country.name.toLowerCase().startsWith(newfilter.toLowerCase());
      })
    );
  };

另一种实现方法是使用useEffect

const handleOnChangeEvent = (e) => {
    const newFilter = e.target.value;
    setFilter(newFilter);
  };
useEffect(() => {
   setCountriesToShow(
      countries.filter((country) => {
        return country.name.toLowerCase().startsWith(filter.toLowerCase());
      })
    );
}, [filter]);