V7: Default global filter does not work when filtering by letters: 'u', 'n', 'd', 'e', 'f', 'i'
Describe the bug
When using the global filter, and filtering by one of the following characters: 'u', 'n', 'd', 'e', 'f', 'i', all rows are returned - seemingly no filtering has been applied.
Having investigated this issue, I think I've spotted the cause:
- The default globalFilter in react-table uses this code to filter rows
xport const text = (rows, ids, filterValue) => { rows = rows.filter(row => { return ids.some(id => { const rowValue = row.values[id] return String(rowValue) .toLowerCase() .includes(String(filterValue).toLowerCase()) }) }) return rows - Notice the
String(rowValue)conversion for every value... - Our tables have various optional, and hence undefined columns, e.g. Description
- When you call String(undefined), it returns the string 'undefined'
- So whenever you filter using a letter in the word undefined, it matches every row... 🤯
Notably this is fixed in V8 because the default global filter function does the below, including a null invoke operator so undefined values not get converted to a string and simply return false when filtering.
return Boolean(
row
.getValue<string | null>(columnId)
?.toString()
?.toLowerCase()
?.includes(search)
)
Your minimal, reproducible example
https://codesandbox.io/s/react-table-v7-with-all-the-features-czz21?file=/src/App.js
Steps to reproduce
- Using the global filter under the headers, enter one of the characters, e.g. 'u'
- Observe that nothing happens and no filtering is applied
- Try a different letter that should work, e.g. 'a'
- Observe that the results change and the total number of rows changes
Expected behavior
When filtering by one of the given letters, the table should be filted
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
Any - but on MacOS/Chrome
react-table version
7.7.0
TypeScript version
5.0.4
Additional context
No response
Terms & Code of Conduct
- [X] I agree to follow this project's Code of Conduct
- [X] I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
PR open 🎉
Hi @clarkd. I'm curious how did you solve this issue in v7? I've seen your solution in the PR but was this accepted in the end?
Hi @beatrixmorar I solved this in v7 by taking the default text filter from react-table v7 and adding minimal null/undefined handling:
const safeGlobalFilter = (rows, columnIds, filterValue) => {
return rows.filter(row => {
return columnIds.some(id => {
const rowValue = row.values[id]
// The key fix: handle null/undefined before String conversion
if (rowValue == null) return false
return String(rowValue)
.toLowerCase()
.includes(String(filterValue).toLowerCase())
})
})
}
Then pass it as the globalFilter option. This maintains all default behavior while preventing the String(undefined) = "undefined" false matches that cause searches like "in" to match all rows.