#javascript #reactjs #react-hooks
Вопрос:
const [input, setInput] = useState("");
const [searchedProducts, setSearchedProducts] = useState(products);
const inputChange = (e) => {
setInput(e.target.value);
};
if (input) {
let newProducts =
products amp;amp;
products.filter(function (el) {
return el.Name.toLowerCase().includes(input.toLowerCase());
});
setSearchedProducts([...newProducts]);
}
здесь поисковые продукты, которые имеют продукты в качестве начального значения, мои продукты имеют массив объектов ниже приведен пример:
[
{
"id": "HT-1000",
"Category": "Laptops",
"MainCategory": "Computer Systems",
"TaxTarifCode": "1",
"SupplierName": "Very Best Screens",
"WeightMeasure": 4.2,
"WeightUnit": "KG",
"Description": "Notebook Basic 15 with 2,80 GHz quad core, 15" LCD, 4 GB DDR3 RAM, 500 GB Hard Disc, Windows 8 Pro",
"Name": "Notebook Basic 15",
"DateOfSale": "2017-03-26",
"ProductPicUrl": "https://rukminim1.flixcart.com/image/416/416/jw9ke4w0/computer/a/y/c/lenovo-na-laptop-original-imafgzg4rhdztzww.jpeg?q=70",
"Status": "Available",
"Quantity": 10,
"UoM": "PC",
"CurrencyCode": "EUR",
"Price": 956,
"Width": 30,
"Depth": 18,
"Height": 3,
"DimUnit": "cm"
}
]
здесь я пытаюсь отфильтровать массив продуктов, используя ключевое слово, полученное из состояния ввода, способное отфильтровать массив, но при выполнении setstate появляется ошибка ниже:
Неперехваченная ошибка: Слишком много повторных рендеров. React ограничивает количество рендеров, чтобы предотвратить бесконечный цикл.
на какое-то время я застрял с этой проблемой!!
Комментарии:
1. переместитесь
if (input)...
внутрьuseEffect
крюка. Любой побочный эффект, который каким-либо образом изменит состояние компонента/приложения, должен переместиться вuseEffect
hook с надлежащим предоставлением массива зависимостей2. Цикл вызван вызовом
setSearchedProducts
внутри рендеринга. Фаза рендеринга должна быть чистой, без побочных эффектов.3. Тем не менее, нет причин использовать для этого состояние. Если есть много вычислений (медленных, много продуктов и т. Д.), Вы могли бы рассмотреть возможность использования
useMemo
, в противном случае фильтрация каждого рендеринга подойдет.
Ответ №1:
Вы вызываете setSearchedProducts при каждом рендеринге, когда входные данные имеют достоверное значение. Поскольку вызов setSearchedProducts вызывает повторную визуализацию, у вас бесконечный цикл визуализации.
Если вам нужно установить поисковые продукты в состояние (это кажется довольно избыточным), то вам следует сделать это в эффектном крючке
useEffect(() => {
let newProducts =
products amp;amp;
products.filter(function (el) {
return el.Name.toLowerCase().includes(input.toLowerCase());
});
setSearchedProducts(newProducts);
}, [input])
Наличие входных данных в качестве параметра зависимости приводит к тому, что крючок запускается только при изменении входных данных.
Ответ №2:
Переместите свой оператор if внутрь useEffect hook
, как это, тогда он будет отображаться повторно только после обновления состояния ввода и будет истинным.
useEffect(()=>{
if (input) { // use if condition here
let newProducts =
products amp;amp;
products.filter(function (el) {
return el.Name.toLowerCase().includes(input.toLowerCase());
});
setSearchedProducts([...newProducts]);
}
},[input]); //your input state will be checked and render once changed from the previous state