React-table 动态下拉可重用自定义过滤器

Nei*_*sey 3 reactjs react-table

我有一个反应表,我想在其中添加一些自定义过滤

我想要实现的是一个下拉选择器,它动态填充了所有可用的选择

我快到了,有一个可行的解决方案,但我真正想做的是让我的 customFilter 可用于三个字段中的每一个,名字、姓氏和年龄 - 目前它可以工作,但对每个值都进行了硬编码

所以这一行

.map(item => item.lastName)
Run Code Online (Sandbox Code Playgroud)

需要像

.map(item => item.{accessor})
Run Code Online (Sandbox Code Playgroud)

这不起作用,但想法是我可以获得每个字段的访问器值,然后这将是真正动态且可重用的

const customFilter = ({ filter, onChange }) => {
    return (
      <select
        onChange={event => onChange(event.target.value)}
        style={{ width: "100%" }}
        value={filter ? filter.value : "all"}
      > 
        <option value="all">Show All</option>
        {testData
          .map(item => item.lastName)

          .filter((item, i, s) => s.lastIndexOf(item) == i)
          .map(function (value) {
            log.debug('renderItem: ', value);
            return (
              <option key={value} value={value}>
                {value}
              </option>
            );
          })}
      </select>
    );
  };

  const testData = [
    { firstName: 'Aang', lastName: 'Smith', age: '19' },
    { firstName: 'Appa', lastName: 'Baker', age: '3' },
    { firstName: 'Asami', lastName: 'Smith', age: '19' },
    { firstName: 'Azula', lastName: 'Baker', age: '19' },
    { firstName: 'Bolin', lastName: 'Smith', age: '20' },
    { firstName: 'Jinora', lastName: 'Baker', age: '19' },
    { firstName: 'Katara', lastName: 'Smith', age: '8' },
    { firstName: 'Korra', lastName: 'Baker', age: '19' },
    { firstName: 'Lin Beifong', lastName: 'Smith', age: '19' },
    { firstName: 'Momo', lastName: 'Baker', age: '19' },
    { firstName: 'Mai', lastName: 'Smith', age: '8' },
    { firstName: 'Mako', lastName: 'Baker', age: '29' },
    { firstName: 'Naga', lastName: 'Smith', age: '19' },
    { firstName: 'Pabu', lastName: 'Baker', age: '19' },
    { firstName: 'Sokka', lastName: 'Smith', age: '39' },
    { firstName: 'Suki', lastName: 'Baker', age: '8' },
    { firstName: 'Tenzin', lastName: 'Smith', age: '19' },
    { firstName: 'Toph Beifong', lastName: 'Baker', age: '19' },
    { firstName: 'Ty Lee', lastName: 'Smith', age: '49' },
    { firstName: 'Uncle Iroh', lastName: 'Baker', age: '59' },
    { firstName: 'Varrick', lastName: 'Smith', age: '19' },
    { firstName: 'Zhu Li', lastName: 'Baker', age: '8' },
    { firstName: 'Zuko', lastName: 'Smith', age: '19' }
  ];


  const columns = [
    {
      Header: "First Name",
      accessor: "firstName", 
      filterMethod: (filter, row) =>
        row[filter.id].startsWith(filter.value) &&
        row[filter.id].endsWith(filter.value)
    }, {
      Header: "Last Name",
      id: "lastName",
      accessor: d => d.lastName,
      filterMethod: (filter, row) => {
        return row[filter.id] === filter.value;
      },
      Filter: ({ filter, onChange }) =>
        customFilter({ filter, onChange })
    }, {
      Header: "Age",
      accessor: "age",
      filterMethod: (filter, row) => {
        return row[filter.id] === filter.value;
      },
      Filter: ({ filter, onChange }) =>
        customFilter({ filter, onChange })
    }
  ]


  return (
    <div>
    <ReactTable
      data={testData}
      filterable
      defaultFilterMethod={(filter, row) =>
        String(row[filter.id]) === filter.value}
      columns={columns}
      defaultPageSize={10}
      className="-striped -highlight"
    />
      <br />
    </div>
  );
Run Code Online (Sandbox Code Playgroud)

Nei*_*sey 5

找到了解决办法

所以对于每个列过滤器,我给了它一个 fieldName 变量 - 然后我可以调用它来更改值并使其可重用

所以这一行

.map(item => item.lastName)
Run Code Online (Sandbox Code Playgroud)

变成这个

.map(item => item[fieldName])
Run Code Online (Sandbox Code Playgroud)

效果很好:-)

const customFilter = ({ fieldName, filter, onChange }) => {

    return (
      <select
        onChange={event => onChange(event.target.value)}
        style={{ width: "100%" }}
        value={filter ? filter.value : "all"}
      > 
        <option value="all">Show All</option>
        {testData
          .map(item => item[fieldName])

          .filter((item, i, s) => s.lastIndexOf(item) == i)
          .map(function (value) {
            log.debug('renderItem: ', value);
            return (
              <option key={value} value={value}>
                {value}
              </option>
            );
          })}
      </select>
    );
  };

  const testData = [
    { firstName: 'Aang', lastName: 'Smith', age: '19' },
    { firstName: 'Appa', lastName: 'Baker', age: '3' },
    { firstName: 'Asami', lastName: 'Smith', age: '19' },
    { firstName: 'Azula', lastName: 'Baker', age: '19' },
    { firstName: 'Bolin', lastName: 'Smith', age: '20' },
    { firstName: 'Jinora', lastName: 'Baker', age: '19' },
    { firstName: 'Katara', lastName: 'Smith', age: '8' },
    { firstName: 'Korra', lastName: 'Baker', age: '19' },
    { firstName: 'Lin Beifong', lastName: 'Smith', age: '19' },
    { firstName: 'Momo', lastName: 'Baker', age: '19' },
    { firstName: 'Mai', lastName: 'Smith', age: '8' },
    { firstName: 'Mako', lastName: 'Baker', age: '29' },
    { firstName: 'Naga', lastName: 'Smith', age: '19' },
    { firstName: 'Pabu', lastName: 'Baker', age: '19' },
    { firstName: 'Sokka', lastName: 'Smith', age: '39' },
    { firstName: 'Suki', lastName: 'Baker', age: '8' },
    { firstName: 'Tenzin', lastName: 'Smith', age: '19' },
    { firstName: 'Toph Beifong', lastName: 'Baker', age: '19' },
    { firstName: 'Ty Lee', lastName: 'Smith', age: '49' },
    { firstName: 'Uncle Iroh', lastName: 'Baker', age: '59' },
    { firstName: 'Varrick', lastName: 'Smith', age: '19' },
    { firstName: 'Zhu Li', lastName: 'Baker', age: '8' },
    { firstName: 'Zuko', lastName: 'Smith', age: '19' }
  ];


  const columns = [
    {
      Header: "First Name",
      accessor: "firstName", 
      filterMethod: (filter, row) =>
        row[filter.id].startsWith(filter.value) &&
        row[filter.id].endsWith(filter.value)
    }, {
      Header: "Last Name",
      id: "lastName",
      accessor: d => d.lastName,
      filterMethod: (filter, row) => {
        return row[filter.id] === filter.value;
      },
      Filter: ({ filter, onChange }) =>
        customFilter({ fieldName:'lastName', filter, onChange })
    }, {
      Header: "Age",
      accessor: "age",
      filterMethod: (filter, row) => {
        return row[filter.id] === filter.value;
      },
      Filter: ({ filter, onChange }) =>
        customFilter({ fieldName:'age', filter, onChange })
    }
  ]


  return (
    <div>
    <ReactTable
      data={testData}
      filterable
      defaultFilterMethod={(filter, row) =>
        String(row[filter.id]) === filter.value}
      columns={columns}
      defaultPageSize={10}
      className="-striped -highlight"
    />
      <br />
    </div>
  );
Run Code Online (Sandbox Code Playgroud)