#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 });
}