在反应中使用 'useMemo' 时仅在数组中显示匹配的字符串

Only show matching string in array when using 'useMemo' in react

我有一个自动完成的输入字段,并且 运行 最初将输出隐藏在我的数组中时遇到了问题。我只想显示匹配的字符串,而不是在安装时显示我的所有项目。让我的状态为空 const [filteredRecipes, setFilteredRecipes] = useState(); 会在我的循环中引发错误。

Codesanbox: https://codesandbox.io/s/quzwg?file=/App.js:251-313

Js:

export default function App() {
  const items = useMemo(
    () => ["item1", "item2", "anotheritem", "yetanotheritem", "myitem"],
    []
  );

  const [search, setSearch] = useState("");
  const [filteredRecipes, setFilteredRecipes] = useState(items);

  const handleSearchChange = event => {
    setSearch(event.target.value);
  };

  useEffect(() => {
    setFilteredRecipes(
      items.filter(el => el.toLowerCase().includes(search.toLowerCase()))
    );
  }, [search, items]);

  return (
    <div>
      <input
        type="search"
        placeholder="type here to filter"
        value={search}
        onChange={handleSearchChange}
      />
      <div>
        {filteredRecipes.map(recipe => (
          <p>{recipe}</p>
        ))}
      </div>
    </div>
  );
}

如果我对你的问题的理解正确,在你的例子中 filteredRecipes 是你想要在安装时最初隐藏的自动完成建议,或者,只要搜索值是假的,在这里做一个假设。您可以通过有条件地过滤 search 状态 truthy/falsey 来做到这一点。所有字符串都将包含空字符串 (''),因此您希望以不同方式处理这种情况。

setFilteredRecipes(
  search
    ? items.filter((el) => el.toLowerCase().includes(search.toLowerCase()))
    : []
);

代码

export default function App() {
  const items = useMemo(
    () => ["item1", "item2", "anotheritem", "yetanotheritem", "myitem"],
    []
  );

  const [search, setSearch] = useState("");
  const [filteredRecipes, setFilteredRecipes] = useState([]);

  const handleSearchChange = (event) => {
    setSearch(event.target.value);
  };

  useEffect(() => {
    setFilteredRecipes(
      search
        ? items.filter((el) => el.toLowerCase().includes(search.toLowerCase()))
        : []
    );
  }, [search, items]);

  return (
    <div>
      <input
        type="search"
        placeholder="type here to filter"
        value={search}
        onChange={handleSearchChange}
      />
      <div>
        {filteredRecipes.map((recipe) => (
          <p>{recipe}</p>
        ))}
      </div>
    </div>
  );
}