javascript - 编写一个与 redux/redux-saga 共享数据的 HoC

标签 javascript reactjs redux redux-saga

我目前正在尝试创建一个可重复使用的组件,它将从远程源中提取数据,并在后端发生更改时根据需要更新表格。这是一个简单的组件:

<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/

相关文章:

javascript - 删除 Angular 为 4 的 Aux 路由“?

JavaScript 给出了不正确的比较结果

javascript - 从嵌套组件更新上下文不起作用

reactjs - React native - 如何动态设置容器或文本输入,这对所有设备都是响应式的

javascript - 将两个 Action 连接到一个 reducer ?

reactjs - 将状态值从 redux reducer 传递到另一个 reducer

javascript - Eclipse:类型不匹配:无法从 String[] 转换为任何

reactjs - react native map 标记不显示

javascript - ES6 模块 : property is not exported 中导入时出现问题

javascript - ACE 有条件地更改键绑定(bind)