程序应将输入的用户键入,搜索数据并在下拉列表中返回结果。 当用户输入超过3个符号时,将调用Search(),并且出现“错误:重新渲染过多”。找不到渲染循环。
import LTCityNames from "../lt-city-names.json"; //JSON object
const Openweathermap = () => {
const [searchList, setSearcList] = useState([]); //drop down list according to search word
const [text, setText] = useState(""); //text in the input field
const Search = (userinput) => {
let correctResult = "";
let dropdownList = [];
const regex = new RegExp(`^${userinput}`, "i");
for (let i = 0; i < LTCityNames.length; i++) {
correctResult = regex.test(LTCityNames[i].name);
if (correctResult){
dropdownList.push(LTCityNames[i]);
setSearcList(dropdownList);
}
}
};
const onChangeInput = (userinput) => {
setText(userinput);
if (userinput.length > 2) {
Search(userinput);
}
};
return (
<input
value={text}
onChange={(e) => {onChangeInput(e.target.value)} }
type="text"
placeholder="Enter address"
></input>
<div id="myDropdownWeather" className="dropdown-content">
{searchList.map((itemInArray) => {
return (
<ul>
<li>{itemInArray.name}</li>
</ul>
);
})
}
答案 0 :(得分:3)
我认为您必须像这样使用useEffect:
const [text, setText] = useState(""); //text in the input field
const lastFilter = useRef(text);
useEffect(() => {
if (lastFilter.current !== text && text.lenght>2) {
Search(userinput);
lastFilter.current = text;
}
}, [text]);
const onChangeInput = (event) => {
var userinput=event.target.value;
setText(userinput);
};
并更改
onChange={(e) => {onChangeInput(e.target.value)} }
到
onChange={(e) => {onChangeInput(e)} }
答案 1 :(得分:2)
第一:为什么会出现“错误:重新渲染过多”?
使用React Functional Components时,每次调用“ setState” 时,React都会重新加载所有Component,并且由于您在组件内部使用函数,因此每次也会加载这些函数。您的组件更改。因此,当您键入搜索内容时,该元素将无法控制地重新呈现。
解决问题:
代码:
import React, { useCallback, useState } from 'react';
import LTCityNames from '../lt-city-names.json'; // JSON object
const Openweathermap = () => {
const [searchList, setSearcList] = useState([]); // drop down list according to search word
const [text, setText] = useState(''); // text in the input field
const Search = useCallback((userinput) => {
const correctResult = '';
const dropdownList = [];
const regex = new RegExp(`^${userinput}`, 'i');
for (let i = 0; i < LTCityNames.length; i++) {
const correctResult = regex.test(LTCityNames[i].name);
if (correctResult) {
dropdownList.push(LTCityNames[i]);
setSearcList(dropdownList);
}
}
}, []);
const onChangeInput = useCallback(
(e) => {
const userinput = e.target.value;
setText(userinput);
if (userinput.length > 2) {
Search(userinput);
}
},
[Search],
);
return (
<> // Fragment element start
<input
value={text}
onChange={(e) => onChangeInput(e)}
type="text"
placeholder="Enter address"
/>
<div id="myDropdownWeather" className="dropdown-content">
{searchList.map((itemInArray) => {
return (
<ul>
<li>{itemInArray.name}</li>
</ul>
);
})}
</div>
</> // Fragment element end
);
};
了解useCallback:
const myReactFunction = useCallback(() => {}, [a,b,c....] )
为您改善组件退货:
您无需使用下面列出的任何提示,但它们可以提高代码的可读性。
由于您使用(e) => onChangeInput(e)
调用了onChange输入,因此您只能将输入更改为onChangeInput
:
<input
value={text}
onChange={onChangeInput} // same as (e) => function(e)
type="text"
placeholder="Enter address"
/>
第二个技巧是在地图功能内部,因为您使用的是箭头功能,因此无需键入return()
:
{searchList.map((itemInArray) => (
<ul>
<li>{itemInArray.name}</li>
</ul>
))}
答案 2 :(得分:0)
import LTCityNames from "../lt-city-names.json"; //JSON object
const Openweathermap = () => {
const [searchList, setSearcList] = useState([]); //drop down list according to search word
const [text, setText] = useState(""); //text in the input field
const Search = (userinput) => {
let correctResult = "";
let dropdownList = [];
const regex = new RegExp(`^${userinput}`, "i");
for (let i = 0; i < LTCityNames.length; i++) {
correctResult = regex.test(LTCityNames[i].name);
if (correctResult){
dropdownList.push(LTCityNames[i]);
setSearcList(dropdownList);
}
}
};
const onChangeInput = (userinput) => {
setText(userinput);
if (userinput.length > 2) {
Search(userinput);
}
};
//remove value={text}
return (
<input
onChange={(e) => {onChangeInput(e.target.value)} }
type="text"
placeholder="Enter address"
></input>
<div id="myDropdownWeather" className="dropdown-content">
{searchList.map((itemInArray) => {
return (
<ul>
<li>{itemInArray.name}</li>
</ul>
);
})
}
删除值= {text}