table icon indicating copy to clipboard operation
table copied to clipboard

V7: Default global filter does not work when filtering by letters: 'u', 'n', 'd', 'e', 'f', 'i'

Open clarkd opened this issue 2 years ago • 3 comments

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

  1. Using the global filter under the headers, enter one of the characters, e.g. 'u'
  2. Observe that nothing happens and no filtering is applied
  3. Try a different letter that should work, e.g. 'a'
  4. 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.

clarkd avatar Jul 14 '23 17:07 clarkd

PR open 🎉

clarkd avatar Jul 14 '23 19:07 clarkd

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?

beatrixmorar avatar Aug 02 '24 10:08 beatrixmorar

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.

shihui-huang avatar Jun 30 '25 14:06 shihui-huang