У меня есть этот useMemo, который используется для поиска данных

import React, { useMemo, useState } from "react";

import "./SearchCharacters.css";

function SearchCharacters({ charactersInfo, setSearchResult }) {
  const [searchText, setSearchText] = useState("");
  useMemo(() => {
    const findCharacter = charactersInfo.filter((character) => {
      return (
        character.gender.toLowerCase() === searchText.toLowerCase() ||
        character.species.toLowerCase() === searchText.toLowerCase() ||
        character.status.toLowerCase() === searchText.toLowerCase()
      );
    });

    findCharacter.length > 0
      ? setSearchResult(findCharacter)
      : setSearchResult(null);
  }, [searchText]);
  return (
    <div className="search_container">
      <input
        className="search_input"
        onChange={(e) => setSearchText(e.target.value)}
        placeholder="Enter characters full name"
      />
    </div>
  );
}

export default SearchCharacters;

charactersInfo - массив объектов, содержащий информацию о персонажах. setSearchResult - это setState, который я передаю от родительского компонента

Warning: Cannot update a component (`Characters`) while rendering a different component (`SearchCharacters`). To locate the bad setState() call inside `SearchCharacters`, follow the stack trace

Есть предложения, пожалуйста?

0
user14587589 21 Авг 2021 в 20:08

2 ответа

Лучший ответ

Вы путаете useMemo с useEffect. useMemo предназначен для функции, возвращающей запомненное значение, а не для запуска побочных эффектов, как вы делаете в конце. так сделай это:

const characters = useMemo(() => {
return charactersInfo.filter((character) => {
  return (
    character.gender.toLowerCase() === searchText.toLowerCase() ||
    character.species.toLowerCase() === searchText.toLowerCase() ||
    character.status.toLowerCase() === searchText.toLowerCase()
  );
});
}, [searchText]);

А затем в ответ на смену персонажей запустите такие эффекты:

useEffect(() => {
characters.length > 0
      ? setSearchResult(findCharacter)
      : setSearchResult(null);
}, [characters])
1
e.a. 21 Авг 2021 в 17:26

Вы не должны делать setState в useMemo. Это должна быть идемпотентная операция, и она не должна иметь побочных эффектов. Обычно вы хотите использовать useMemo, когда вам нужно вычислить что-то тяжелое, и вы хотите запомнить результат, чего здесь нет.

Замените useMemo на useEffect. Также будьте осторожны с предоставлением charactersInfo в массиве зависимостей.

2
Federkun 21 Авг 2021 в 17:22