Как заставить сервер 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,
                })
            })
    }
}
Другие вопросы по тегам