javascript - How to make Next.js server waiting until action creator is fully done? - Stack Overflow

admin2025-04-21  0

I'm using Next.js with Redux and I need to wait until action creator is fully done (including request to the external server) so data will be already in the initial rendering. I will try to explain this case in example.

I'm using HOC from example in docs and wrap page with it.

So, below you can see code example:

index.js in pages folder.

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 '../../ponents/RunningLine'
import { fetchLatestNews } from '../../actions/wp_news'

class RunningLineContainer extends Component {

    ponentDidMount() {
        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)

Currently, request is being made on the client side thus data from request is not rendered by the server and data content not being seen by search engines. My aim to make this data being responded on initial loading (rendered by the server).

Action creator code below:

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,
                })
            })
    }
}

I've tried to use static method getInitialProps in index.js page like this:

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)

Unfortunately, it doesn't work for me.

How can I solve this task? Is there any workaround?

Thanks in advance!

I'm using Next.js with Redux and I need to wait until action creator is fully done (including request to the external server) so data will be already in the initial rendering. I will try to explain this case in example.

I'm using HOC from example in docs and wrap page with it.

So, below you can see code example:

index.js in pages folder.

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 '../../ponents/RunningLine'
import { fetchLatestNews } from '../../actions/wp_news'

class RunningLineContainer extends Component {

    ponentDidMount() {
        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)

Currently, request is being made on the client side thus data from request is not rendered by the server and data content not being seen by search engines. My aim to make this data being responded on initial loading (rendered by the server).

Action creator code below:

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,
                })
            })
    }
}

I've tried to use static method getInitialProps in index.js page like this:

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)

Unfortunately, it doesn't work for me.

How can I solve this task? Is there any workaround?

Thanks in advance!

Share Improve this question asked Apr 17, 2018 at 15:18 Denys KotsurDenys Kotsur 2,5992 gold badges17 silver badges27 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 2

Your action creator doesn't return Promise so it cannot be awaited. 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,
                })
            })
    }
}

Finally, I have resolved this task.

Actual solution is to make returning function in action creator asynchronous and add await to the API request.

So, I use static method as mentioned above like this:

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)  

My action creator looks like this:

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,
                })
            })
    }
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745172155a288722.html

最新回复(0)