Базовая фильтрация в react-data-grid

#javascript #reactjs #react-data-grid

#javascript #reactjs #react-data-grid

Вопрос:

Недавно я немного больше изучаю «react-data-grid» и пытаюсь заставить базовую функцию фильтрации работать в моем приложении React. Это их базовый пример фильтрации, на который я смотрю:

http://adazzle.github.io/react-data-grid/docs/examples/column-filtering

Их пример кода в codesandbox: https://codesandbox.io/s/w6jvml4v45?from-embed

Я скопировал большинство примеров артефактов кода в свой компонент класса и попытался найти эквивалентное решение для React useState() (я новичок в React и useState, по-видимому, недоступных в классах).

Мой код был немного изменен для этого форума и указывает на общедоступный веб-сайт JSONPlaceholder для имитации вызова REST API с реального сервера с тестовыми данными. Так что, надеюсь, вы можете просто запустить его. Вот мой App.js код:

 import React, { Component } from "react";
import ReactDataGrid from "react-data-grid";
import { Toolbar, Data } from "react-data-grid-addons";

import "./App.css";
import "bootstrap/dist/css/bootstrap.css";

const defaultColumnProperties = {
  filterable: true,
  width: 120,
  editable: true
};

const columns = [
  { key: "id", name: "ID" },
  { key: "username", name: "Username" },
  { key: "email", name: "Email" }
].map(c => ({ ...c, ...defaultColumnProperties }));

function getRows(rows, filters) {
  const selectors = Data.Selectors;
  return selectors.getRows({ rows, filters });
}

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      rows: [],
      isLoaded: false,
      filters: {},
      setFilters: {}
    };
  }

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(res => res.json())
      .then(json => {
        this.setState({
          isLoaded: true,
          rows: json
        });
      });
  }

  onGridRowsUpdated = ({ fromRow, toRow, updated }) => {
    this.setState(state => {
      const rows = state.rows.slice();
      for (let i = fromRow; i <= toRow; i  ) {
        rows[i] = { ...rows[i], ...updated };
      }
      return { rows };
    });
  };

  render() {
    // const [filters, setFilters] = useState({});
    const filteredRows = getRows(this.state.rows, this.state.filters);

    // Commenting ORIGINAL handleFilterChange example code temporarily
    // const handleFilterChange = filter => filters => {
    //   const newFilters = { ...filters };
    //   if (filter.filterTerm) {
    //     newFilters[filter.column.key] = filter;
    //   } else {
    //     delete newFilters[filter.column.key];
    //   }
    //   return newFilters;
    // };


    // Temporarily rewrote handleFilterChange function for DEBUGGING purpose and not using arrow fucntions
    // Used babeljs.io to generate non arrow based handleFilterChange function.
    var handleFilterChange = function handleFilterChange(filter) {
      debugger;
      console.log("handleFilterChange(filter)"   filter);

      return function(filters) {
        debugger;
        console.log("function(filters)"   filters);

        var newFilters = { ...filters };

        if (filter.filterTerm) {
          newFilters[filter.column.key] = filter;
        } else {
          delete newFilters[filter.column.key];
        }

        return newFilters;
      };
    };

    return (
      <ReactDataGrid
        columns={columns}
        rowGetter={i => filteredRows[i]}
        rowsCount={filteredRows.length}
        minHeight={500}
        toolbar={<Toolbar enableFilter={true} />}
        onAddFilter={filter =>
          this.setState({ setFilters: handleFilterChange(filter) })
        }
        onClearFilters={() => this.setState({ setFilter: {} })}
      />
    );
  }
}
export default App;
  

Согласно комментариям в приведенном выше примере кода, который я использовал babeljs.io для создания функции handleFilterChange, не основанной на стрелках, и добавления некоторых журналов и инструкций отладки

По какой-то причине вложенная функция:

   return function(filters) {
    var newFilters = {
      ...filters
    };

    if (filter.filterTerm) {
      newFilters[filter.column.key] = filter;
    } else {
      delete newFilters[filter.column.key];
    }
  

не вызывается. Отладчик в Chrome не достигает точки останова и не распечатывает какие-либо добавленные мной журналы отладки.

Этот журнал всегда вызывается:

       console.log("handleFilterChange(filter)"   filter);
  

Этот журнал во внутренней функции никогда не вызывается, что, я полагаю, является проблемой?

        console.log("function(filters)"   filters);
  

Функция handleFilterChange, не основанная на стрелках, работает, когда я использую ее в их примере и заменил их код handleFilterChange, поэтому я считаю, что сам код в порядке, и все журналы отладки отображаются в консоли. Внутренняя функция также вызывается. Рад использовать функцию arrow, хотя, если я смогу получить небольшую помощь, чтобы заставить это работать.

Я также написал базовую версию фильтра, не основанную на классе, но столкнулся с проблемами при загрузке довольно больших данных JSON с сервера. Не исследовал это дальше, но я считаю, что это была проблема со временем.

Из-за проблемы таблица загружается в браузере, и я могу нажать кнопку «Фильтровать строки» в правом верхнем углу. Это уменьшит поля редактирования поиска, и я смогу вводить буквы, но таблица не фильтруется на лету при вводе букв.

Ответ №1:

 
    handleFilterChange(filter) {

        let newFilters = Object.assign({}, this.props.filters);

        if (filter.filterTerm) {
            newFilters[filter.column.key] = filter;
        } else {
            delete newFilters[filter.column.key];
        }
        this.setState({ filters: newFilters });
    }