Поскольку _app.js - это HoC, ваш Компонент внутри _app.js - это, по сути, страница, которую вы хотите загрузить из папки страниц (если вы создаете дальше, вы можете распространять другой HoC и впоследствии загружать свою страницу, зависит от ваше приложение, но затем в вашем сочинительном HoC вы должны снова реализовать getInitialProps и затем выполнить getInitialProps вашего последнего page.js). Каждая страница может иметь свой собственный getInitialProps (например, на странице контактов вы хотите загрузить адрес своей компании и только там во всем приложении). _app.js выполняет Component.getInitProps (если установлено). Если метод Компонента возвращает непустой объект, он становится вашим PageProps, который вы, наконец, предоставляете Компоненту внутри метода рендеринга.
В вашем page.js теперь реализован метод getInitProps, который отправляет саг-задачу и возвращает isServer ... при условии, что только ваше хранилище гидратируется отправкой действия - getInitProps не нужно ничего ждать и возвращает логическое значение. После увлажнения магазина ваш компонент будет обновлен, так как ваши реквизиты в магазине загружены / обновлены.
Однако сейчас я сталкиваюсь с той же проблемой:
Я отправляю саги Задачи в моем getInitProps, но поскольку действия асинхронные, я получаю реквизиты после ComponentDidMount.
EDIT:
Ссылка для чтения
TL: DR;
- Задачи Saga - это потоки или, если вы хотите что-то вроде слушателей событий.
- Каждый раз, когда вы отправляете действие саги (в зависимости от вашей саги), слушатель раскручивается
- В нашем случае, если мы запускаем действие в нашем getInitialProps, мы отправляем действия в хранилище с помощью саг-задач, однако метод store.dispatch не async =>, что приводит к тому, что getInitialProps не блокируется действием и мгновенно возвращает реквизиты, хотя запущенные задания не завершены
- Решение Виктора, а также решение из пакета next-redux-saga: 1. отправить действие 'END', которое останавливает текущую корневую задачу, и 2. применить метод toPromise (), который дает вам возможность асинхронно ждать для саг до конца. => Вы как бы блокируете getInitialProps и заставляете метод ждать завершения саг до возврата метода;
- Важно: когда вы останавливаете свои потоки саги, это нормально, и ДОЛЖНО / ДОЛЖНО быть выполнено на сервере, но вашему приложению нужны саги на стороне клиента для правильной обработки побочных эффектов магазина, таким образом, вы ДОЛЖНЫ перезапускать саги, если! IsServer.
UPDATE:
Это не работает. Вы можете остановить саги на сервере только потому, что они нужны только для первоначального выполнения, саги на сервере впоследствии бесполезны. Однако на стороне клиента вы не можете остановить саги.
Вот мой store.js ... вы можете выполнить начальные саги, и сервер будет ждать их завершения в getInitialProps, поскольку toPromise () выполняет асинхронную остановку.
На стороне клиента вы должны пройти через жизненные циклы и т. Д. ... Гидратация магазина на стороне клиента не работает, как я ожидал, это сработает. Возможно, это лучше, так как в противном случае вы бы заблокировали React от рендеринга, что в целом противоречит React.
store.runSagas = () => {
if (!store.currentSagas) {
store.currentSagas = sagaMiddleware.run(rootSaga);
}
};
store.stopSagas = async () => {
if (store.currentSagas) {
store.dispatch(END);
await store.currentSagas.toPromise();
}
};
store.execTasks = isServer => async (tasks = []) => {
tasks.forEach(store.dispatch);
if (isServer) {
await store.stopSagas();
}
};