У меня есть компонент Home с компонентом Grid внутри. Компонент grid имеет компонент MaterialTable, который считывает данные с удаленного сервера. Это параметр данных:
data={query =>
new Promise((resolve, reject) => {
props.refreshGrid(query.page, query.pageSize, resolve, reject);
})
}
и создатель действия:
export function refreshGrid(page, pageSize, resolve, reject) {
return async (dispatch, getState, api) => {
api.taskhours.home(page, pageSize).then((response) => {
var rows = response.data.rows;
var total = response.data.total;
// Grid data inside Redux Store is not being used right now, everything is done inside "resolve"
dispatch(updateGrid(rows, page, pageSize, total));
resolve({
data: rows,
page: page,
totalCount: total,
})
}).catch((error) => {
console.log("Error:",error);
});
};
}
Все мои компоненты работают (не используют классы).
Это отлично работает. Тем не менее, у меня есть модальная форма в другом компоненте, и когда пользователь отправляет, мне нужно обновить sh сетки. Так как я извлекаю данные с удаленного сервера, таблица материалов обрабатывает отображение строк, разбивку на страницы и загрузку, и я знаю, что я могу обновить sh сетки только с помощью tableRef.current.onQueryChange (). , Как я могу вызвать это из другого компонента (модального)?
Я попытался сохранить ссылку в хранилище React Redux, но это дало мне «Невозможно обновить компонент внутри тела функции другого компонента». ошибка, а также выполнение бесконечного рекурсивного выполнения функции.
Кроме того, поскольку сетка обновляется сама, мне нужно, чтобы она НЕ выполнялась повторно, в противном случае я теряю свое внутреннее состояние (номер страницы, размер страницы). Мне пришлось использовать React.memo (), чтобы избежать повторного рендеринга, вызванного родительским компонентом, который выглядит очень нечистым. Я довольно новичок в React, поэтому я не могу делать все правильно. Есть ли лучший способ реализовать это?
EDIT
Мне удалось решить это, используя другой подход. Материал-таблица, кажется, довольно ограничен и не очень дружественен к редуксу. Я основал решение на этом посте, спасибо lfernando-silva за обходной путь:
https://github.com/mbrn/material-table/issues/630
Так что в основном я заменил обещание на "данных" с переменной хранилища избыточных данных. Поскольку этот метод используется только для предоставления всего набора данных (вместо одной страницы), вы не можете изменить страницу и максимальное количество строк по умолчанию, поэтому мне пришлось вручную установить атрибуты компонента «TablePagination» для отображения правильные значения.
return (
<React.Fragment>
<MaterialTable
title="title"
tableRef={tableRef}
columns={[
// (...)
]}
options={{
emptyRowsWhenPaging: false
}}
data={
props.grid.rows
}
onChangeRowsPerPage={pageSize => {
refreshGrid(props.grid.page, pageSize);
}}
components={{
Pagination: (componentProps) => <TablePagination
{...componentProps}
count={props.grid.total}
page={props.grid.page}
rowsPerPage={props.grid.pageSize}
onChangePage={(evt, page) => {
refreshGrid(page, props.grid.pageSize)
}}
/>
}}
isLoading={props.grid.isLoading}
actions={[
// (...)
]}
/>
</React.Fragment>
);
И мой создатель действия "refreshGrid":
export function refreshGrid(page, pageSize) {
return async (dispatch, getState, api) => {
dispatch(startLoadingGrid());
api.taskhours.home(page, pageSize).then((response) => {
var rows = response.data.rows;
var total = response.data.total;
dispatch(updateGrid(rows, page, pageSize, total));
dispatch(stopLoadingGrid());
}).catch((error) => {
console.log("Error:",error);
dispatch(stopLoadingGrid());
});
};
}