Next.js + Redux:在 getInitialProps 中获取数据操作完成之前加载一个页面
Posted
技术标签:
【中文标题】Next.js + Redux:在 getInitialProps 中获取数据操作完成之前加载一个页面【英文标题】:Next.js + Redux: A Page is loaded before fetching data actions in getInitialProps is complete 【发布时间】: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
【问题讨论】:
【参考方案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
对象
【讨论】:
以上是关于Next.js + Redux:在 getInitialProps 中获取数据操作完成之前加载一个页面的主要内容,如果未能解决你的问题,请参考以下文章
Next.js:在 getServerSideProps 中使用带有 TypeScript 的 next-redux-wrapper 调用 Thunks?
我已经在 next js 中使用 next-redux-wrapper 成功实现了 redux-persist