簡體   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