【问题标题】:Next.js + Redux: A Page is loaded before fetching data actions in getInitialProps is completeNext.js + Redux:在 getInitialProps 中获取数据操作完成之前加载一个页面
【发布时间】:2020-08-11 08:28:25
【问题描述】:

我正在尝试通过在页面中触发 getInitialProps 中的“getItems”操作从 API 获取数据。(假设它是页面 A)

如果我通过Link(next/link)从其他页面转到页面A,则可以成功获取数据。

但是,如果我在页面 A 中刷新,则永远不会获取数据,我必须通过触发 getItems 操作手动获取数据。

任何人都可以告诉我即使在刷新页面时我应该如何获取数据?

_app.js

const MyApp = props => {
  const { Component, pageProps, store } = props

  return (
    <>
      <Head>
        <link rel='stylesheet' href='/styles/global.css' />
      </Head>
      <Provider store={store}>
        <MainLayout>
          <Component {...pageProps} />
        </MainLayout>
      </Provider>
    </>
  )
}

MyApp.getInitialProps = async ({ Component, ctx }) => {
  const pageProps = Component.getInitialProps
    ? await Component.getInitialProps(ctx)
    : {}
  return { pageProps }
}

export default withRedux(store)(MyApp)

pageA.js

import Head from 'next/head'
import Link from 'next/link'
import { connect } from 'react-redux'
import { getItems, addItem } from '../../store/actions/itemAction'
import { GET_ITEMS } from '../../store/types'

const Index = props => {
  return (
    <>
      <Head>
        <title>Item List</title>
        <link rel='stylesheet' href='/styles/css_pages/shop.css' />
      </Head>
      <div><div>
    </>
  )
}

Index.getInitialProps = async ({ store }) => {
  await store.dispatch(getItems())
  return {}
}

const mapStateToProps = state => ({
  goods: state.item.goods,
})

const mapDispatchToProps = dispatch => ({
  getItems: () => dispatch(getItems()),
  addItem: () => dispatch(addItem()),
})

export default connect(mapStateToProps, mapDispatchToProps)(Index)

itemAction.js

import fetch from 'isomorphic-unfetch'
import { GET_ITEMS } from '../types'

export const getItems = () => {
  return dispatch => {
    fetch('http://localhost:5000/item')
      .then(res => res.json())
      .then(data => dispatch({ type: GET_ITEMS, payload: data }))
      .catch(err => console.error(err))
  }
}

itemReducer.js

import { GET_ITEMS } from '../types'

const initialState = { goods: [], loading: false }

const itemReducer = (state = initialState, action) => {
  switch (action.type) {
    case GET_ITEMS:
      return {
        ...state,
        goods: action.payload,
        loading: false,
      }

    default:
      return state
  }
}

export default itemReducer

store.js

import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import rootReducer from './rootReducer'

const bindMiddleware = middleware => {
  if (process.env.NODE_ENV !== 'production') {
    const { composeWithDevTools } = require('redux-devtools-extension')
    return composeWithDevTools(applyMiddleware(...middleware))
  }

  return applyMiddleware(...middleware)
}

export const store = () => createStore(rootReducer, bindMiddleware([thunk]))

rootReducer.js

import { combineReducers } from 'redux'
import itemReducer from './reducers/itemReducer'

const rootReducer = combineReducers({
  item: itemReducer
})

export default rootReducer

【问题讨论】:

    标签: reactjs redux react-redux next.js redux-thunk


    【解决方案1】:

    在返回和呈现之前,您应该等待 pageA 的 getInitialProps 中的 getItems 操作响应。

    我想如果你尝试使用await,它会解决你的问题:

    Index.getInitialProps = async ({ store }) => {
      await store.dispatch(getItems())
      return {}
    }
    

    【讨论】:

    • 我试过了,但同样的事情发生了。刷新时永远不会获取数据。
    • 只是为了确定,您如何检查是否使用此代码获取数据?
    • 刷新后控制台记录道具时,“props.goods”数组为空,这意味着我猜数据永远不会被获取。但是,当通过 Link(next/link) 呈现客户端时,它不是空的,而是来自 DB 的数据。
    【解决方案2】:

    我会尝试研究这个例子https://github.com/vercel/next.js/blob/canary/examples/with-redux-wrapper/store/store.js

    建议使用next-redux-wrapper 包来包装您的页面。然后您将在您的Index.getInitialProps 上获得store 对象

    【讨论】:

      猜你喜欢
      • 2021-08-06
      • 1970-01-01
      • 1970-01-01
      • 2020-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-28
      • 1970-01-01
      相关资源
      最近更新 更多