[英]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.length
是0
並且因此是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.