#sql #reactjs #grid #react-virtualized
#sql #reactjs #сетка #react-виртуализированный
Вопрос:
Я пытаюсь создать хорошее представление результатов для просмотра результатов SQL-запроса. Эти результаты могут содержать тысячи результатов, поэтому был выбран React Virtualized, чтобы избежать отображения всех строк. Компонент MultiGrid был выбран таким образом, чтобы имена столбцов из запроса были привязаны к верхней части представления. Компонент выглядит следующим образом:
Многосеточная сеть имеет динамическую ширину с использованием средства измерения ячеек. Код сильно вдохновлен приведенным здесь примером. Моя проблема в том, что компонент отображается очень медленно, и в тех случаях, когда компонент был отображен, затем скрыт, а затем снова отображен, все приложение зависает на минуту или более. Очевидно, что отображается что-то, чего не должно быть, но я не уверен, в чем проблема. Я попытался очистить CellMeasurerCache, но это, похоже, не сработало. Код для многосеточной сети выглядит следующим образом:
const useStyles = makeStyles((theme) => ({
tableWrapper: {
minHeight: 200,
height: '100%',
width: '100%',
resize: 'vertical',
overflowY: 'hidden',
scrollbarWidth: 'none',
paddingBottom: theme.spacing(2),
},
gridCell: {
whiteSpace: 'nowrap',
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
paddingLeft: '1em',
paddingRight: '1em',
justifyContent: 'center',
},
}));
export default function ResultTable() {
const recordingContext = useContext(RecordingContext);
const classes = useStyles();
const result = recordingContext?.activeRecording?.queryOutput;
if (!result || !result.results) {
return (
<Typography style={{ padding: '8px 16px' }} variant="subtitle1">
No data to show
</Typography>
);
}
const { labels, types, values } = result.results;
function formatDate(d: Date) {
let month = `${d.getMonth() 1}`;
let day = `${d.getDate()}`;
const year = d.getFullYear();
if (month.length < 2) month = `0${month}`;
if (day.length < 2) day = `0${day}`;
return [year, month, day].join('-');
}
function format(index: number, entry: unknown): string {
let datatype = 0;
if (types) {
datatype = types[index];
}
if (datatype === 12) {
if (typeof entry === 'number') {
const date = new Date(Number(entry));
return formatDate(date);
}
const date = new Date(String(entry));
return formatDate(date);
}
return String(entry);
}
const STYLE: CSSProperties = {
width: '100%',
fontFamily: 'raleway',
resize: 'none',
};
const cache = new CellMeasurerCache({
defaultWidth: 100,
fixedHeight: true,
});
type CellRendererType = {
rowIndex: number;
columnIndex: number;
style: React.CSSProperties;
parent: MeasuredCellParent;
};
function cellRenderer({
rowIndex,
parent,
columnIndex,
style,
}: CellRendererType) {
const content =
rowIndex === 0
? labels[columnIndex]
: format(columnIndex, values[rowIndex - 1][columnIndex]);
return (
<CellMeasurer
cache={cache}
parent={parent}
key={`${columnIndex}-${rowIndex}`}
columnIndex={columnIndex}
rowIndex={rowIndex}
>
<div
style={style}
key={`${columnIndex}-${rowIndex}`}
className={classes.gridCell}
>
{content}
</div>
</CellMeasurer>
);
}
return (
<div className={classes.tableWrapper}>
<div
style={{
minHeight: 201,
height: '100%',
width: '100%',
paddingBottom: 1,
}}
>
<AutoSizer>
{({ height, width }) => (
<MultiGrid
cellRenderer={cellRenderer}
columnWidth={cache.columnWidth}
columnCount={labels.length}
height={height}
deferredMeasurementCache={cache}
rowHeight={48}
rowCount={values.length 1}
scrollToColumn={0}
scrollToRow={0}
fixedRowCount={1}
width={width}
style={STYLE}
styleTopRightGrid={{
fontWeight: 'bold',
width: '100%',
backgroundColor: '#404040',
fontSize: 14,
}}
styleBottomRightGrid={{
outline: 'none',
}}
overscanColumnCount={0}
overscanRowCount={20}
/>
)}
</AutoSizer>
</div>
</div>
);
}
Комментарии:
1. Я смог выяснить, что проблема связана с cellmeasurer, устранение этого привело к хорошей загрузке компонента. Это оставляет проблему сетки, не имеющей динамической ширины, так есть ли какой-либо способ исправить это?