如何在next.js中渲染之前等待复杂的redux-saga操作流程完成?

时间:2019-04-10 13:03:29

标签: redux-saga next.js

我在等待“一个动作流”从头到尾完成时遇到问题。该应用程序可以在客户端正常运行,但是在服务器端执行该操作时,它直到结束时才结束。

为澄清起见,我同时使用了“ next-redux-wrapper”和“ next-redux-saga”,因为当我对sagas使用更简单的流时,可以实现延迟渲染。

我认为错误主要是我完全理解(或不知道)传奇效果的方式。

为简洁起见,一些代码被省略了。

api.saga.js

const makeRequest = ({ body, url, method }) =>
  axios({ method, url: url, data: body });


export function* requestWatcher(action) {
  const { feature } = action.meta;

  try {
    const { data: response } = yield call(makeRequest, action.meta);
    yield put(apiSuccess({ response, feature }));
  } catch (error) {
    yield put(apiError({ error: error, feature }));
  }
}

export default function* apiSaga() {
  yield takeEvery(action => action.type.includes(API_REQUEST), requestWatcher);
}

smallBusiness.saga.js

function* watchApiSuccess(action) {
  yield put(
    setPositions({ positions: action.payload.positions })
  );
  yield put(setLoader({ isLoading: false, feature: SMALL_BUSINESS }));
}

function* watchApiError() {
  yield put(setLoader({ isLoading: false, feature: SMALL_BUSINESS }));
}

function* watchFetchPositions() {
  yield put(
    apiRequest({
      body: null,
      method: 'GET',
      url: SMALL_BUSINESS_URL,
      feature: SMALL_BUSINESS
    })
  );
  yield put(setLoader({ isLoading: true, feature: SMALL_BUSINESS }));
}

export default function* smallBusinessSaga() {
  yield all([
    takeLatest(`${SMALL_BUSINESS} ${API_SUCCESS}`, watchApiSuccess),
    takeLatest(`${SMALL_BUSINESS} ${API_ERROR}`, watchApiError),
    takeLatest(FETCH_POSITIONS, watchFetchPositions)
  ]);
}

rootSaga.js

export default function* rootSaga() {
  yield all([call(smallBusinessSaga), call(apiSaga)]);
}

configureStore.js

store.sagaTask = sagaMiddleware.run(rootSaga);

客户端函数“ watchApiSuccess”被调用,而服务器端则没有。除了已经提到的生成器功能外,每个生成器功能都称为服务器端。

当我使用下面的代码示例简化流程时,应用将预先渲染服务器端。

function* watchPrefetchPositions() {
  const meta = {
    body: null,
    method: 'GET',
    url: SMALL_BUSINESS_URL,
    feature: SMALL_BUSINESS
  };

  const { data: response } = yield call(makeRequest, meta);
  yield put(setPositions({ positions: response.positions }));
}

export default function* smallBusinessSaga() {
  yield all([
    ...
    takeLatest(PRE_FETCH_POSITIONS, watchPrefetchPositions)
  ]);
}

我无法处理复杂的流水的主要问题是,sagas无法执行归一化等操作。

1 个答案:

答案 0 :(得分:0)

您可以使用标志来控制何时以及是否应该渲染组件。这是一种常见的解决方案,用于呈现后备UI(例如,微调框或文本),以等待异步进程(传奇,thunk,API服务等)完成并且组件具有呈现其自身所需的全部内容。 / p>

我在这里附加了一个CodeSandBox示例,以便您可以一眼看到它的工作方式。 https://codesandbox.io/embed/2586j3k1p

您会看到加载出现一会儿,直到提取数据为止。请注意,CodeSandBox正在缓存此API调用,因此您在第一次单击后几乎看不到正在加载的文本。

React路线图包括一个用于处理异步渲染功能的发行版,称为“ Suspense”,它针对您所描述的这种特定类型的流量问题模仿了相同的行为。在发布React Async Rendering之前,我建议使用标志。

如果您想了解更多详细信息,建议您观看Dan Abramov: Beyond React 16 | JSConf Iceland 2018

祝你好运