[英]React DOM not re-rendering after state change of array property
我知道这个问题很常见,大多数人可能会发现这是重复的,但我无能为力,这就是我来这里的原因。
我有一个名为App
的 React 组件,它是一个功能组件。
App
组件的开始
function App() {
const [results, setResults] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [name, setName] = useState('');
const [isNameSelected, setIsNameSelected] = useState(false);
...
有一个子组件目前运行不正常,它是App
function 的返回组件的一部分。
App
组件return
语句中的代码部分:
<ListGroup className="typeahead-list-group">
{!isNameSelected &&
results.length > 0 &&
results.map((result: Result) => (
<ListGroupItem
key={result.cik}
className="typeahead-list-group-item"
onClick={() => onNameSelected(result)}
>
{result.cik + ' | ' + result.name}
</ListGroupItem>
))}
</ListGroup>
对results
的更改由组件FormControl
的onChange
function 处理,这里也是App
return
语句的一部分:
<FormControl
placeholder="Entity/CIK"
id="searchInput"
type="text"
autoComplete="off"
onChange={handleInputChange}
value={name}
/>
handleInputChange
在App
function 中被定义为:
const handleInputChange = (e: any) => { // Triggers when search bar is changed
// remove error bubble
setAlertMessage(new AlertData('', false));
const nameValue = e.target.value; // get the new input
setName(nameValue); // set the new input
// even if we've selected already an item from the list, we should reset it since it's been changed
setIsNameSelected(false);
setResults([]); // clean previous results
if (nameValue.length > 1) { // if the input is more than 1 character
setIsLoading(true); // set loading to true
updateSearchInput(nameValue) // get the results
.then((res) => {
setResults(res as React.SetStateAction<never[]>); // set the results
setIsLoading(false); // set loading to false
})
.catch((error) => {
// error bubble
let strError = error.message;
strError = strError.split(':').pop();
let errorMessage: AlertData = new AlertData(strError, true); // create error message for empty search
setAlertMessage(errorMessage); // set alert message
// loading spinner
setIsLoading(false);
});
}
}
然而,当表单控件中的输入发生变化时,比如输入一个完整的单词,搜索功能就会起作用,用建议的单词填充 DOM。 但是,当我非常快地清除FormControl
中的值时(通过快速连续按几次 Backspace/Delete),搜索结果就会保留下来。 然而,缓慢地执行或一次选择并清除它并不会显示这种不稳定的行为。
我已经使用console.log
在这样的空组件中打印出results
值:
{console.log(results) && (<div><div/>)}
在App的return
语句中查看results
的内容是什么。 但是它确实表明results
值没有被setResults()
更新。
然而,对于此处使用的其他状态,此问题不存在。 为什么?
编辑
从下面接受的@ghybs的答案。 这是通话可能发生的事情的时间表:
await
呼叫运行但请求响应很慢,因此需要一段时间。handleInputChange
调用中使用setResults([])
将results
清空。setResults(res as React.SetStateAction<never[]>)
运行使results
非空。您很可能只有大量并发请求(每次击键 1 个,包括退格键?),以及来自updateSearchInput
async 的无序结果 function:最后收到的结果会覆盖您的results
,但该请求可能不是来自您的最后一次击键(一个从你的文本区域中删除最后一个字符的)。
通常,如果空搜索比大量单词搜索快,则空输入的结果确实会清除您的results
,但随后这些结果将由先前搜索的结果再次填充。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.