簡體   English   中英

如何修復 react.js 中 onChange 事件的數據過濾器問題

[英]How to fix the data filter problem on onChange event in react.js

我有一個 function 過濾掉 onChange 事件的數據。 就過濾而言,它工作正常,但問題在於 onChange 事件和 setState

我正在使用 React Select 來賦予 onChange 值:

<Select
  id="status"
  isClearable={false}
  options={statusOptions}
  defaultValue={statusOptions[0]}
  onChange={(choice) => handleStatusFilter(choice.value)}
/>

這里的狀態選項是:

const statusOptions = [
  { value: '', label: 'Clear' },
  { value: 'draft', label: 'Draft' },
  { value: 'ready', label: 'Ready' },
  { value: 'expired', label: 'Expired' },
]

現在 onChange 事件我調用handleStatusFilter

// state
const [status, setStatus] = useState('')

// ** handleStatusFilter
// ** Function to handle status filter
const handleStatusFilter = (value) => {
  let updatedData = []
  const dataToFilter = () => {
    if (title.length || type.length || createdAt.length || createdBy.length || status.length) {
      return filteredData
    } else {
      return results
    }
  }

  setStatus(value)
  if (value.length) {
    updatedData = dataToFilter().filter((item) => {
      const startsWith = item.status.toLowerCase().startsWith(value.toLowerCase())
      const includes = item.status.toLowerCase().includes(value.toLowerCase())

      if (startsWith) {
        return startsWith
      } else if (!startsWith && includes) {
        return includes
      } else return null
    })
    setFilteredData([...updatedData])
    setStatus(value)
  }
}

所以它在用戶選擇任何選項時第一次起作用,但之后改變他的選擇時不起作用。 例如; 當用戶選擇draft選項時,數據會被過濾。 但是當他直接從draft進入ready時它不起作用,並且如果用戶清除 state 從statusOptions中點擊Clear選項,然后用戶選擇ready然后數據被正確地過濾這個值。

我假設應該有一種方法可以清除 onChange 的值,而不是手動清除選擇空字符串。 那么如何應對這個問題,有沒有更好的方法可以遵循,而不是 setState 方法。

問題或多或少與這里的這種情況有關:

  const dataToFilter = () => {
    if (title.length || type.length || createdAt.length || createdBy.length || status.length) {
      return filteredData
    } else {
      return results
    }
  }

可能它會在第一次選擇時返回results ,因為條件中的所有值都是假的。 可以肯定的是status.length0並且因此是falsy 從那時起,它總是返回filteredData ,因為status.length是真實的。 顯然,過濾后的值不再包含其他值。 所以無論你 select,你總是會再次過濾 filteredData。

相反,您必須過濾每個選擇的原始值results

     updatedData = results.filter( // here use results instead of filtered values.
(item) => {
          const startsWith = item.status.toLowerCase().startsWith(value.toLowerCase())
          const includes = item.status.toLowerCase().includes(value.toLowerCase())
    
/** besides that, this can be simplified
          if (startsWith) {
            return startsWith
          } else if (!startsWith && includes) {
            return includes
          } else return null
        })**/
    return startsWith || includes

Edit1:我上面說的沒有錯,但是沒有考慮其他過濾器。 所以一般來說,您會限制您的結果,以便它們無法進一步過濾。 相反,您必須應用同一個過濾器 function 中的所有過濾器,以過濾值。 是一個帶有完整示例的代碼框。

我為此使用了一個 useEffect,並使用了一個簡單的 html select 進行演示。 但是您可以輕松地將其應用到您的代碼中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM