繁体   English   中英

state 更改数组属性后,React DOM 不会重新呈现

[英]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的更改由组件FormControlonChange function 处理,这里也是App return语句的一部分:

<FormControl
  placeholder="Entity/CIK"
  id="searchInput"
  type="text"
  autoComplete="off"
  onChange={handleInputChange}
  value={name}
/>

handleInputChangeApp 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的答案。 这是通话可能发生的事情的时间表:

  1. 输入搜索
  2. await呼叫运行但请求响应很慢,因此需要一段时间。
  3. 删除搜索中的所有关键字
  4. handleInputChange调用中使用setResults([])results清空。
  5. 等待通话结束。 setResults(res as React.SetStateAction<never[]>)运行使results非空。

您很可能只有大量并发请求(每次击键 1 个,包括退格键?),以及来自updateSearchInput async 的无序结果 function:最后收到的结果会覆盖您的results ,但该请求可能不是来自您的最后一次击键(一个从你的文本区域中删除最后一个字符的)。

通常,如果空搜索比大量单词搜索快,则空输入的结果确实会清除您的results ,但随后这些结果将由先前搜索的结果再次填充。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM