#javascript #reactjs #debugging #redux #mui-datatable
#javascript #reactjs #отладка #redux #mui-datatable
Вопрос:
Информация
У меня есть проект, который использует React, Redux и MUI-Datatables. Простую демонстрацию этого проекта можно найти в этом CodeSandbox .
В этом приложении есть два основных компонента: карта и таблица данных. Они взаимодействуют через redux, так что при выборе строки в таблице соответствующий круг на карте выделяется и наоборот.
Проблема
Моя проблема связана с неопределенным переключением флажка выбора в таблице. Когда пользователь выбрал строку, а затем применяет фильтр, флажок selectAll показывает неопределенный символ ‘-‘, но при нажатии на него ничего не происходит.
Шаги для воссоздания:
- Пользователь выбирает первую строку в таблице, circle1.
- Пользователь открывает диалоговое окно фильтра в правом углу таблицы.
- Из выпадающего меню маркера в диалоговом окне фильтра пользователь выбирает circle3 в качестве значения фильтра.
- Пользователь закрывает диалоговое окно фильтра
- Пользователь нажимает на флажок selectAll в верхней части столбца select row. В нем будет отображаться символ ‘-‘.
- Обратите внимание, что ничего не меняется. Ни одна строка не выбрана или не отменена.
Желаемое поведение:
Когда пользователь выбрал строку в таблице, а затем применяет фильтр, флажок selectAll по-прежнему должен выбирать все видимые строки при первом щелчке и отменять выбор всех при втором щелчке так же, как обычно.
Код
Live: CodeSandbox
Компонент таблицы:
import React, { useEffect, useState } from "react";
import MUIDataTable from "mui-datatables";
import { connect } from "react-redux";
import { handleSelection } from "./redux";
import circles from "./assets/data/circles";
import { addToOrRemoveFromArray } from "./utils";
// Table component
const Table = ({ handleSelection, selections }) => {
const [selectionIndexes, setSelectionIndexes] = useState([]);
// When 'selections' changes in redux store:
useEffect(() => {
let indexes = [];
// Iterate selections:
selections.forEach((selection) => {
// Push the index of the selected
// circle into index arr:
let index = circles.indexOf(selection);
indexes.push(index);
});
// Set selections to local state hook:
setSelectionIndexes(indexes);
}, [selections]);
// Table options:
const options = {
rowsSelected: selectionIndexes, // User provided array of numbers (dataIndexes) which indicates the selected rows
selectToolbarPlacement: "none",
selectableRows: "multiple", // Enable selection of multiple rows
setRowProps: (row, dataIndex, rowIndex) => {
return {
style: {
padding: ".5rem",
margin: ".5rem auto"
}
};
},
// When a row(s) is/are selected:
onRowSelectionChange: (
currentRowsSelected,
allRowsSelected,
rowsSelected
) => {
let temp = [];
let indexes = [];
// Iterate rowsSelected:
rowsSelected.forEach((row) => {
// Add or remove row index to/from indexes arr:
indexes = addToOrRemoveFromArray(row, indexes, "indexes");
// Circle data:
let circle_data = circles[row];
// Add or remove circle_data to/from temp arr:
temp = addToOrRemoveFromArray(circle_data, temp, "temp");
});
// Set indexes to local hook:
setSelectionIndexes(indexes);
// Send the circle data to redux:
handleSelection(temp);
}
};
const columns = [
{
name: "marker",
label: "Marker",
options: {
filter: true,
sort: false
}
},
{
name: "lat",
label: "Latitude",
options: {
filter: true,
sort: false
}
},
{
name: "lon",
label: "Longitude",
options: {
filter: true,
sort: false
}
},
{
name: "radius",
label: "Radius",
options: {
filter: true,
sort: false
}
}
];
const table_name = `Circle Markers`;
return (
<>
<div style={{ display: "table", tableLayout: "fixed", width: "100%" }}>
<MUIDataTable
title={<h3>{table_name}</h3>}
data={circles}
columns={columns}
options={options}
/>
</div>
</>
);
};
const mapStateToProps = (state) => {
return {
selections: state.selection.selections
};
};
const mapDispatchToProps = (dispatch) => {
return {
handleSelection: (selections) => dispatch(handleSelection(selections))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Table);
Как я могу заставить флажок selectAll работать должным образом, когда выбрана строка за пределами отфильтрованных данных?
Ответ №1:
Можно ли отменить выбор выбранной строки при применении фильтров? Я сделал обходной путь для достижения желаемого поведения.
Живой код: CodeSandbox
Я добавил дополнительный код в строку 34 Table.jsx
onFilterChange: (changedColumn, changedColumnIndex, displayData) => {
changedColumnIndex.forEach((data, key) => {
if (Array.isArray(data) amp;amp; data.length) {
setSelectionIndexes([]);
}
});
},
Комментарии:
1. Это одно из решений, но оно, к сожалению, не соответствует тому, что мне нужно. Мне нужно, чтобы строка за пределами фильтров оставалась выбранной и чтобы ее можно было переключать с помощью флажка selectAll во время применения фильтров. У React-tables есть функциональность, но мне действительно нравятся MUI Datatables, и я уже проделал большую работу по его настройке для моего проекта, поэтому я бы предпочел не переключаться 😅.
2. Я вижу. Вы пытались добавлять выбранную строку в фильтры всякий раз, когда она была открыта? Возможно, это может сработать.