Как заставить сервер Next.js ждать, пока создатель действий полностью не завершится?
Я использую Next.js с Redux, и мне нужно подождать, пока создатель действий не будет полностью выполнен (включая запрос к внешнему серверу), чтобы данные уже были в начальном рендеринге. Я постараюсь объяснить этот случай на примере.
Я использую HOC из примера в документах и упаковке page
с этим.
Итак, ниже вы можете увидеть пример кода:
index.js в pages
папка.
import withRedux from '../utils/withRedux'
import RunningLineContainer from '../src/containers/news/RunningLineContainer'
const IndexPage = () => <RunningLineContainer />
export default withRedux()(IndexPage)
RunningLineContainer.jsx
import React, { Component } from 'react'
import { connect } from 'react-redux'
import RunningLine from '../../components/RunningLine'
import { fetchLatestNews } from '../../actions/wp_news'
class RunningLineContainer extends Component {
componentDidMount() {
if (!this.props.lastestNews) {
this.props.fetchLatestNews('&count=6')
}
}
render() {
const { latestNews, isLoading } = this.props
return <RunningLine data={latestNews} isLoading={isLoading} />
}
}
const mapStateToProps = ({ newsState }) => {
const { latestNews, isLoading } = newsState
return {
latestNews,
isLoading
}
}
export default connect(mapStateToProps, { fetchLatestNews })(RunningLineContainer)
В настоящее время запрос выполняется на стороне клиента, поэтому данные из запроса не отображаются сервером, а содержимое данных не просматривается поисковыми системами. Моя цель сделать так, чтобы эти данные отвечали на первоначальную загрузку (предоставляемую сервером).
Код создателя действий ниже:
export function fetchLatestNews(params) {
return function (dispatch) {
dispatch({ type: newsTypes.FETCH_WP_LATEST_NEWS_REQUEST })
newsApi.fetchLatestNews(params)
.then(response => {
dispatch({
type: newsTypes.FETCH_WP_LATEST_NEWS_SUCCESS,
payload: response.data,
})
})
.catch(error => {
dispatch({
type: newsTypes.FETCH_WP_LATEST_NEWS_FAILURE,
payload: error,
})
})
}
}
Я пытался использовать статический метод getInitialProps
в index.js page
как это:
import withRedux from '../utils/withRedux'
import RunningLineContainer from '../src/containers/news/RunningLineContainer'
const IndexPage = () => <RunningLineContainer />
IndexPage.getInitialProps = async ({ store }) => {
await store.dispatch(fetchLatestNews())
}
export default withRedux()(IndexPage)
К сожалению, это не работает для меня.
Как я могу решить эту задачу? Есть ли обходной путь?
Заранее спасибо!
2 ответа
Наконец-то я решил эту задачу.
Фактическое решение - сделать возвращаемую функцию в действии создателем асинхронной и добавить await
к запросу API.
Итак, я использую статический метод, как указано выше, как это:
import withRedux from '../utils/withRedux'
import RunningLineContainer from '../src/containers/news/RunningLineContainer'
const IndexPage = () => <RunningLineContainer />
IndexPage.getInitialProps = async ({ store }) => {
await store.dispatch(fetchLatestNews())
}
export default withRedux()(IndexPage)
Мой создатель действий выглядит так:
export const fetchLatestNews = params => {
return async dispatch => {
dispatch({ type: newsTypes.FETCH_WP_LATEST_NEWS_REQUEST })
await newsApi.fetchLatestNews(params)
.then(response => {
dispatch({
type: newsTypes.FETCH_WP_LATEST_NEWS_SUCCESS,
payload: response.data,
})
})
.catch(error => {
dispatch({
type: newsTypes.FETCH_WP_LATEST_NEWS_FAILURE,
payload: error,
})
})
}
}
Создатель вашего действия не возвращает Promise, поэтому он не может быть await
редактор Fix:
export function fetchLatestNews(params) {
return function (dispatch) {
dispatch({ type: newsTypes.FETCH_WP_LATEST_NEWS_REQUEST })
// return statement
return newsApi.fetchLatestNews(params)
.then(response => {
dispatch({
type: newsTypes.FETCH_WP_LATEST_NEWS_SUCCESS,
payload: response.data,
})
})
.catch(error => {
dispatch({
type: newsTypes.FETCH_WP_LATEST_NEWS_FAILURE,
payload: error,
})
})
}
}