В настоящее время я пытаюсь создать повторно используемый компонент, который будет извлекать данные из удаленного источника и обновлять таблицу по мере необходимости, если элементы будут меняться на серверной части.Вот простой компонент:
<React.Fragment>
<Header />
<table>
<thead>
<tr>
{columns.map(c => (
<th key={c.header}>{c.header}</th>
))}
</tr>
</thead>
<tbody>{data.map(row => children(row))}</tbody>
</table>
<Pagination />
</React.Fragment>
Цель состояла в том, чтобы со страницы моего заказа я мог назвать ее так, как показано ниже:
<DataTable
id="app/OrderPage/orders"
url="http://localhost:8081/api/orders"
columns={[
{ header: 'Name' },
{ header: 'Actions' },
]}
>
{order => (
<tr key={order.id}>
<td>{order.name}</td>
<td>
<Link to={`/admin/orders/${order.id}`}>
View
</Link>
</td>
</tr>
)}
</DataTable>
Теперь идея заключается в том, что я хочу использовать это повторнокомпонент в нескольких местах.В настоящее время я использую redux-saga для выполнения выборки и обновления данных, когда возвращаются данные.(В настоящее время я предоставляю ID с возможностью датирования, который затем передается в FETCH_DATA, LIMIT_CHANGED, SEARCH_CHANGED и т. Д ..., который я затем использую для обновления частей среза, которые необходимо изменить:
function dataTableReducer(state = initialState, action) {
switch (action.type) {
case INIT: {
const { id, url, deletedItem } = action;
return state.setIn(
['tables', id],
initialTableState
.set('id', id)
.set('url', url)
.set('deletedItem', deletedItem),
);
}
case LOAD_DATA_SUCCESS:
return state.setIn(['tables', action.id, 'data'], action.data.data);
case LIMIT_CHANGED:
return state.setIn(['tables', action.id, 'limit'], action.limit);
case SEARCH_CHANGED:
return state.setIn(['tables', action.id, 'search'], action.search);
default:
return state;
}
}
Моя текущая сага для компонента DataTable:
function* getData({ id }) {
const dt = yield select(selectDataTableInstance(), { id });
const { url, limit, search, page } = dt;
const res = yield call(request, url, {
qs: {
limit,
search,
page,
},
});
yield put(loadDataSuccess(id, res));
}
// Individual exports for testing
export default function* dataTableSaga() {
yield all([
takeEvery(LOAD_DATA, getData),
takeEvery(LIMIT_CHANGED, getData),
takeLatest(SEARCH_CHANGED, getData),
]);
}
Теперь возникает проблема, как добавить дополнительную логику к этому компоненту? Например, когда новый заказ поступает поверхwebsocket, мне бы хотелось, чтобы компонент <DataTable />
добавил эту строку в верхнюю часть списка. Проблема в том, что мне нужно было бы подключить дополнительную логику к имеющейся у меня избыточной саге. Сначала я думал, чтодобавьте реквизит в DataTable, например deletedItem={DELETE_ORDER_SUCCESS}
, но это выглядит как очень неприятный обходной путь. Моему редуктору нужно было бы перебрать каждую визуализированную таблицу в срезе и проверить, было ли инициализировано action.type === той, которая была инициализированакогда отображается таблица.
В настоящее время я использую React Boilerplate .
TLDR:
- Наличие многократно используемого компонента DataTable
- Требуется получить данные / заполнить таблицу.Имеет функцию поиска / ограничения / разбиения на страницы
- Хотите добавить дополнительные хуки (например, addItem), которые добавят элемент в верхнюю часть списка, если он получен из веб-сокета