我目前正在尝试创建一个可重复使用的组件,它将从远程源中提取数据,并在后端发生更改时根据需要更新表格。这是一个简单的组件:
<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 />
组件将该行添加到列表的顶部。问题是,我需要将额外的逻辑连接到我已有的 redux-saga。我最初的想法是向 DataTable 添加一个 Prop ,例如 deletedItem={DELETE_ORDER_SUCCESS}
,但这似乎是一个非常讨厌的解决方法。我的 reducer 需要遍历切片中的每个渲染表,并检查 action.type === 是否是表显示时初始化的那个。
我目前正在使用 React Boilerplate .
简单描述:
- 有一个可重复使用的 DataTable 组件
- 需要获取数据/填充表格。具有搜索/限制/分页功能
- 想要添加额外的 Hook (如 addItem),如果项目来自 websocket,它将添加到列表的顶部
最佳答案
您可以拥有一组用于 web 套接字相关操作的 reducer。假设当网络套接字收到新订单时,您可以发送 NEW_ORDER 操作。
在您的 reducer 中,您可以更新现有状态以包含新订单(如果需要的话,在列表顶部)。这应该触发重新渲染,因为表数据是从 Redux 存储中读取的。
case LOAD_DATA_SUCCESS:
return state.setIn(['tables', action.id, 'data'], [action.data.data, state.getIn(['tables', 'action.id', 'data']);
您可以针对需要执行的不同事情执行不同的操作。
关于javascript - 编写一个与 redux/redux-saga 共享数据的 HoC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53540720/