如何用tan栈覆盖react 表中的全局过滤器匹配函数?

我想添加对使用"精确匹配的支持.例如,在搜索"male"时,不应该包含的行包含"female"行(类似于Google上的工作方式).

我有一个 idea ,可以创造出这样的东西(未经过测试):

function getRandomBoolean = (filter, row) => {
  const searchTerm = filter.value.trim();
  if (searchTerm.startsWith('"') && searchTerm.endsWith('"')) {
    // Perform an exact match search if the search term is enclosed in quotes
    const exactSearchTerm = searchTerm.slice(1, -1);
    return row === exactSearchTerm;
  } else {
    // Perform a regular search if no quotes are used
    return row.toLowerCase().includes(searchTerm.toLowerCase());
  }
}

但是,不确定如何覆盖默认的全局筛选函数.有可能吗?

或者,有没有其他设置可以让这类搜索变得更容易?

我试着在这里查看,但认为文档很难阅读: https://react-table-v7.tanstack.com/docs/api/useGlobalFilter

我有一个基于本教程的示例代码: https://www.youtube.com/watch?v=GsDP1bLoIQU&list=PLC3y8-rFHvwgWTSrDiwmUsl4ZvipOw9Cz&index=8

这是一个用于全局搜索的工作示例(我将所有内容都放在同一个文件中,以便更容易在新项目中进行测试).我想可能只有一个地方可以推翻它.有谁知道在哪里或者懂文档怎么做的?

import React, { useMemo } from 'react'

import { useTable, useGlobalFilter } from 'react-table'
//import { COLUMNS } from './columns'
//import MOCK_DATA from './MOCK_DATA.json'
const COLUMNS = [
    { Header: 'id', accessor: 'id' },
    { Header: 'First name', accessor: 'first_name' },
    { Header: 'Last name', accessor: 'last_name' },
    { Header: 'Mail', accessor: 'email' },
    { Header: 'gender', accessor: 'gender' },
    { Header: 'age', accessor: 'age' },
    { Header: 'country', accessor: 'country' },
    { Header: 'Phone', accessor: 'phone' }
];
const MOCK_DATA =
[{"id":1,"first_name":"Abey","last_name":"Shattock","email":"ashattock0@who.int","gender":"male","age":60,"country":"Sweden","phone":"3235563967"},
{"id":2,"first_name":"Gert","last_name":"Verey","email":"gverey1@miitbeian.gov.cn","gender":"male","age":39,"country":"Argentina","phone":"6617228260"},
{"id":3,"first_name":"Elsa","last_name":"McDermott-Row","email":"gmcdermottrow2@fc2.com","gender":"female","age":73,"country":"China","phone":"5049019528"},
{"id":4,"first_name":"Ade","last_name":"Southwick","email":"asouthwick3@gmpg.org","gender":"male","age":58,"country":"France","phone":"2562514369"},
{"id":5,"first_name":"Angelina","last_name":"Almond","email":"aalmond4@ezinearticles.com","gender":"Female","age":30,"country":"Paraguay","phone":"9509201868"},
]
export const GlobalFilter = ({filter, setFilter}) => {
    return (
        <span>
            Search: {' '} 
            <input value={filter || ''} onChange={(e) => setFilter(e.target.value)} />
        </span>
    )
}

export const BasicTable = () => {

   const columns = useMemo( () => COLUMNS, []);
   const data = useMemo( () => MOCK_DATA, []);

    const tableInstance = useTable({
            columns: columns,
            data: data
        },
        useGlobalFilter
    )

    const {getTableProps, getTableBodyProps, prepareRow, state, setGlobalFilter, headerGroups, rows } = tableInstance

   const  { globalFilter } = state
    return (
        <div>
            <GlobalFilter filter={globalFilter} setFilter={setGlobalFilter}/>
            <table { ...getTableProps() }>
                <thead>
                    {
                        headerGroups.map( (headerGroup) => (
                            <tr {...headerGroup.getHeaderGroupProps()}>
                                {
                                    headerGroup.headers.map(( column ) => (
                                        <th {...column.getHeaderProps()}>{column.render('Header')}</th>
                                    ))
                                }
                            </tr>
                        ))
                    }
                </thead>
                <tbody { ...getTableBodyProps() }>
                    
                        {rows.map( (row) => {
                            prepareRow(row)
                            return (
                                <tr {...row.getRowProps()}>
                                    {
                                        row.cells.map((cell) => {
                                            return <td {...cell.getCellProps()}> {cell.render('Cell')}</td>
                                        })
                                    }
                                </tr>
                            )
                        })
                        }

                </tbody>
            </table>
        </div>
    )
}

推荐答案

下面是您如何重写global alFilter并进行"完全匹配".

如果首先只输入了一个",而最后没有输入匹配,则忽略.

import React, { useMemo } from 'react'


import { useTable, useGlobalFilter } from 'react-table'

const COLUMNS = [
    { Header: 'id', accessor: 'id' },
    { Header: 'First name', accessor: 'first_name' },
    { Header: 'Last name', accessor: 'last_name' },
    { Header: 'Mail', accessor: 'email' },
    { Header: 'gender', accessor: 'gender' },
    { Header: 'age', accessor: 'age' },
    { Header: 'country', accessor: 'country' },
    { Header: 'Phone', accessor: 'phone' }
];
const MOCK_DATA =
[{"id":1,"first_name":"Abey","last_name":"Shattock","email":"ashattock0@who.int","gender":"male","age":60,"country":"Sweden","phone":"3235563967"},
{"id":2,"first_name":"Gert","last_name":"Verey","email":"gverey1@miitbeian.gov.cn","gender":"male","age":39,"country":"Argentina","phone":"6617228260"},
{"id":3,"first_name":"Elsa","last_name":"McDermott-Row","email":"gmcdermottrow2@fc2.com","gender":"female","age":73,"country":"China","phone":"5049019528"},
{"id":4,"first_name":"Ade","last_name":"Southwick","email":"asouthwick3@gmpg.org","gender":"male","age":58,"country":"France","phone":"2562514369"},
{"id":5,"first_name":"Angelina","last_name":"Almond","email":"aalmond4@ezinearticles.com","gender":"Female","age":30,"country":"Paraguay","phone":"9509201868"},
]

// Remove the value here in input else you get a warning
export const GlobalFilter = ({filter, setFilter}) => {
    return (
        <span>
            Search: {' '} 
            <input  onChange={(e) => setFilter(e.target.value)} />
        </span>
    )
}

export const BasicTable = () => {
   
    // You need to define your global filter here
    const globalFilter = React.useCallback((rows, ids, query) => {
        const searchTerm = String(query);

        return rows.filter((row) => {
            const matches = ids.filter((id) => {
                const rowValue = row.values[id];
                let searchTermLower = searchTerm.toLowerCase();

                if (searchTerm == '"')  {
                    // ignore first ' " ' handle it as no input
                    return true
                }
                else if (searchTerm.startsWith('"') && searchTerm.endsWith('"')) {
                    const exactSearchTerm = searchTerm.slice(1, -1);
                    return String(rowValue) === exactSearchTerm;
                }
                else if (searchTerm.startsWith('"'))  {
                    // ignore until ending ' " ' has been entered
                    searchTermLower = searchTerm.slice(1);
                }
   
                return rowValue !== undefined
                    ? String(rowValue).toLowerCase().includes(searchTermLower.toLowerCase())
                    : false;
            });

            return matches.length > 0;
        });
    }, []); 


   const columns = useMemo( () => COLUMNS, []);
   const data = useMemo( () => MOCK_DATA, []);

    const tableInstance = useTable({
            columns: columns,
            data: data,
            globalFilter: globalFilter // send it in here
        },
        useGlobalFilter
    )

    const { getTableProps, getTableBodyProps, prepareRow, setGlobalFilter, headerGroups, rows } = tableInstance

    return (
        <div>
            <GlobalFilter filter={globalFilter} setFilter={setGlobalFilter}/>
            <table { ...getTableProps() }>
                <thead>
                    {
                        headerGroups.map( (headerGroup) => (
                            <tr {...headerGroup.getHeaderGroupProps()}>
                                {
                                    headerGroup.headers.map(( column ) => (
                                        <th {...column.getHeaderProps()}>{column.render('Header')}</th>
                                    ))
                                }
                            </tr>
                        ))
                    }
                </thead>
                <tbody { ...getTableBodyProps() }>
                    
                        {rows.map( (row) => {
                            prepareRow(row)
                            return (
                                <tr {...row.getRowProps()}>
                                    {
                                        row.cells.map((cell) => {
                                            return <td {...cell.getCellProps()}> {cell.render('Cell')}</td>
                                        })
                                    }
                                </tr>
                            )
                        })
                        }

                </tbody>
            </table>
        </div>
    )
}

Reactjs相关问答推荐

客户端组件中服务器组件的两难境地

如何使用Reducer更新全局变量

Redux Provider Stuck甚至彻底遵循了文档

为什么我的React App.js只在页面刷新时呈现3次?

如何使数据库数据在第一次呈现时显示?

是否在Extra Reducer完成作业(job)时触发createListenerMiddleware?

Mantine DatePickerInput呈现错误

阻止组件更新的多分派Redux Thunk或setState是否有任何问题

React 为什么标签导致 onClick 事件运行 2 次?

Next.js `getLayout` 函数没有被调用

验证 Yup 中的对象项

在 React 中将 MUI 样式外包到单独的文件中?

单击按钮时如何添加或删除 3d 对象

Firebase Storage: 对象不存在图片上传路径错误

React 测试库包装器组件

useEffect 渲染没有依赖数组的组件

如何在 ReactJS 中提交后删除 URL 中的查询参数

使用带有搜索字符串的全局过滤器时如何在 React-Table 中进行精确匹配?

react-router v6 中的 BrowserRouter 和 createBrowserRouter 有什么区别?我可以在不使用数据 API 的情况下使用 createBrowserRouter 吗?

在 redux 状态更改时更新react 按钮禁用状态