React Kendo Grid去除重复列过滤器方案咨询
It sounds like your issue is that applying a filter to a column is adding duplicate filter entries (instead of replacing the existing one for that field). Here are two feasible solutions depending on your needs:
Solution 1: Use Default Column Menu with Expanded Filter (Simplest)
If your only customization need is to have the filter section expanded by default, you don't need a custom ColumnMenu component. You can configure the built-in column menu directly on each GridColumn:
<Grid sortable pageable={this.state.pageable} data={this.state.queuedData} sort={this.state.sort} filter={this.state.filter} onFilterChange={this.handleFilterChange} onSortChange={this.handleSortChange} onPageChange={this.handlePageChange} total={this.state.total} skip={this.state.skip} pageSize={this.state.pageSize} resizable > <GridColumn field="entity" title="Entity" sortable={true} columnMenu={{ filter: { expanded: true } }} /> <GridColumn field="name" title="Name" sortable={true} columnMenu={{ filter: { expanded: true } }} /> <GridColumn filter="date" field="changedDate" title="Change Date" sortable={true} columnMenu={{ filter: { expanded: true } }} cell={this.CustomCell} /> </Grid>
This replaces your custom ColumnMenu with the default menu, configured to show the filter section expanded. The built-in menu handles filter replacement automatically, so you won't get duplicates.
Solution 2: Deduplicate Filters in handleFilterChange (For Custom Column Menus)
If you need to keep your custom ColumnMenu component, modify your handleFilterChange function to replace existing filters for the same field instead of appending them:
handleFilterChange = (newFilter) => { if (!newFilter) { this.setState({ filter: null }); return; } // Process incoming filter(s) let filtersToProcess = []; if ('filters' in newFilter) { filtersToProcess = newFilter.filters; } else { filtersToProcess = [newFilter]; } // Use a map to ensure one filter per field const filterMap = new Map(); filtersToProcess.forEach(filter => { // Handle single filter descriptors if ('field' in filter) { filterMap.set(filter.field, filter); } // Handle composite filters (multiple conditions for same field) else if ('filters' in filter && filter.filters.length > 0) { const field = filter.filters[0].field; if (field) { filterMap.set(field, filter); } } }); // Convert map back to filter array const uniqueFilters = Array.from(filterMap.values()); // Create final filter (single descriptor if only one filter, else composite) const updatedFilter = uniqueFilters.length === 1 ? uniqueFilters[0] : { logic: newFilter.logic || 'and', filters: uniqueFilters }; this.setState({ filter: updatedFilter }); };
How This Works:
- We use a
Mapto group filters by theirfieldproperty, ensuring only one filter (either a single condition or a composite of multiple conditions for the same field) is kept per column. - This replaces any existing filter for a field with the latest one applied, eliminating duplicates.
内容的提问来源于stack exchange,提问作者mayank

