【问题标题】:How to implement filtering logic in React table?如何在 React 表中实现过滤逻辑?
【发布时间】:2018-02-21 16:01:39
【问题描述】:

我正在使用 React Table 来显示我从 API 调用收到的数据。目前我在本地保存状态,表格显示数据。我为两列添加了列值过滤。我的过滤逻辑如下:

    <ReactTable
  data={tableData}
  noDataText="Loading.."
  filterable
  defaultFilterMethod={(filter, row) =>
    String(row[filter.id]) === filter.value}
    };
  }}
  columns={[
    {
      columns: [
        {
          Header: 'Name',
          accessor: 'Name',
          id: 'Name',
          Cell: ({ value }) => (value === 'group1' ? 
          'group1' : 'group2'),
          filterMethod: (filter, row) => {
            if (filter.value === 'all') {
              return true;
            }
            if (filter.value === 'group1') {
              return row[filter.id] === 'group1';
            }
            if (filter.value === 'group2') {
              return row[filter.id] === 'group2';
            }
          },
          Filter: ({ filter, onChange }) =>
            <select
              onChange={event => onChange(event.target.value)}
              style={{ width: '100%' }}
              value={filter ? filter.value : 'all'}
            >
              <option value="all">All</option>
              <option value="group1">Group1</option>
              <option value="group2">Group2</option>
            </select>,
        },
   }

到目前为止,过滤规则是在两个值之间硬编码的。如何实现过滤器逻辑以使过滤是动态的?(如果特定列中有 3 或 7 个不同的值,则下拉列表应显示所有 7 个值,并且过滤器应根据所选的任何值工作)。因为我使用 React Table(https://react-table.js.org)。

【问题讨论】:

  • @SeaWarrior404..这是什么“返回行[filter.id] ==='group2';”返回,理想情况下它应该返回true或false..我怀疑它返回布尔值或任何值....请澄清
  • 这个问题还没有解决吗?未解决?您似乎已经转向其他问题,但这里没有回应.. 为什么?如果我建议的答案不起作用,也许您现在自己已经有了答案,您可以回答自己的问题并接受它:stackoverflow.com/help/self-answer

标签: javascript reactjs web html-table


【解决方案1】:

我假设您想从选项列表中选择选项。 如果是这样,您可以使用以下方法:

const exampleList = ['option1','option2','option3','option4',...,'option n']

在您的专栏中:

filterMethod:  (filter, row) => customOptionsFilterMethod(filter, row),
Filter: () => ({filter, onChange}) => customOptionsFilter({filter, onChange})

在 render() 内部实现 customOptionsFilter 和 customOptionsFilterMethod 为:

const customOptionsFilter = ({filter, onChange}) => {
      return(
        <select
          onChange={e => onChange(e.target.value)}
          style={{  width: '100%'  }}
          value={filter ? filter.value : 'all'}
          >
          <option value='all'>Show All</option>
          {
            exampleList.map( k => {
              return <option key={k.toString()} value={k}>{k}</option>
            })
          }
        </select>
      )
    }



const customOptionsFilterMethod = (filter, row) => {

      if(filter.value === '') { return true }

      if(exampleList.includes(filter.value)){
        return row[filter.id] === filter.value
      } else { return true }

    }

【讨论】:

  • 我对Filter和filterMethod分别是什么感到非常困惑,但如果我没记错的话,Filter是获取视图上的过滤器类型,而filterMethod是实现过滤器本身。如果我错了,请纠正我。
【解决方案2】:

没有用过这个库,但听起来像这样可以工作

if (filter.value === 'all') {
  return true;
} else {
  // what ever the value is, we will only
  // show rows that have a column value
  // that matches it
  // If value is 'group1' just show the ones where the column
  // value is 'group1', etc etc.
  return row[filter.id] == filter.value;
}

请注意,在您获得完全匹配之前,这不会显示任何内容。因此,即使您有像“group1”这样的列值,搜索词“grou”也不会匹配它。如果这不是您想要的行为,那么您会想要退出

return row[filter.id] == filter.value;

类似

return row[filter.id].indexOf(filter.value) >= 0;

作为替代方法,如果您需要更多限制,您可以从数组构建您的选项

const options = [ { value: "all" , label: "All" }, { value: "group1" , label: "Group1" }];

并像使用它一样

       <select
          onChange={event => onChange(event.target.value)}
          style={{ width: '100%' }}
          value={filter ? filter.value : 'all'}
        >
          { options.map(({value,label}) => <option value={value}>{label}</option>)}
        </select>,

在您的过滤器逻辑中,您可以检查 filter.value 值是否在 'options` 数组中。

// check if there is some (any) value that matches the criteria
// of opt.value == filter.value
return  options.some(opt => opt.value == filter.value);

【讨论】:

  • 这种方法在特定条件下有效。然而我需要的答案不是这个。我将其保持打开状态,因为可能还有另一个可能解决此问题的潜在答案。我一直忙于应用程序的其他部分,所以当我找到解决这个问题的方法时,我会相应地更新。
  • 好的,感谢您的反馈。也许您可以在问题中添加更多信息,突出我建议的两个解决方案无法解决的那种情况?
  • 顺便说一句。对不起“唠叨”和我评论的责备语气。当 OP 很长时间没有对某个问题做出回应时,它看起来很糟糕,即使这个人在其他问题上都很活跃。有些人只是提出问题,然后再也不回来接受答案或感谢,这与 Stackoverflow 的理念背道而驰。但我也可以看到没有立即回复的其他原因,如果我不公平,请见谅。
  • 没关系!正如我上面提到的。我很重视你的回答,它确实在一定程度上帮助我解决了这个问题。因此,当我找到解决方案时,我将自己提供解决方案。欣赏你的洞察力。 :)
猜你喜欢
  • 2014-07-15
  • 2023-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-15
  • 2021-08-22
  • 2018-09-09
  • 1970-01-01
相关资源
最近更新 更多