Next.js + Redux:在服务器端获取的数据永远不会移动到页面道具
Posted
技术标签:
【中文标题】Next.js + Redux:在服务器端获取的数据永远不会移动到页面道具【英文标题】:Next.js + Redux: Data fetched on server side never move to the page props 【发布时间】:2020-08-11 14:44:58 【问题描述】:我正在使用 next.js 和 redux 构建一个 Web 应用程序,并尝试从服务器端的 getInitialProps 获取数据。
在 getInitialProps 中有一个准备触发的 redux 操作,它会在我点击或刷新页面时触发。
问题是,在触发后,数据从数据库中获取并成功存储在 redux 存储中,但存储的数据从未移动到页面道具,所以我根本无法使用获取的数据。
如果我在触发动作后检查“store.getState()”,则有从 DB 获取的数据。
有趣的是,如果我点击一个触发相同动作的按钮,数据会被获取并移动到页面道具,以便我可以使用它们。
我在这里做错了什么,如何首先将存储的数据自动发送到页面道具?
import Head from 'next/head'
import Link from 'next/link'
import connect from 'react-redux'
import getItems from '../../store/actions/itemAction'
const Index = props =>
return (
<>
<Head>
<title>Item List</title>
</Head>
<div>
<Button onClick=() => props.getItems()>Get Items!</Button>
</div>
</>
)
Index.getInitialProps = async ( store ) =>
await store.dispatch(getItems())
return
const mapStateToProps = state => (
goods: state.item.goods,
)
const mapDispatchToProps = dispatch => (
getItems: () => dispatch(getItems())
)
export default connect(mapStateToProps, mapDispatchToProps)(Index)
这里是 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
【问题讨论】:
为什么不在初始道具中访问商店并在对象中退货。否则,您可以尝试删除 await。 @Jose Felix 感谢您的评论。我知道我可以访问“getInitialProps”中的商店并最终返回商品对象,以便我可以使用页面中的商品道具。但是我想知道为什么商品道具即使成功存储在状态中并从mapStateToProps映射到道具,也不会首先移动到页面。如果我从 getInitialProps 中获取了货物对象,则意味着 mapStateToProps 不起作用且无用。 我相信,这是因为您返回的是一个空对象。在它从 Redux 获取状态后,你的getInitialProps
返回一个空对象,删除你拥有的任何东西。但是,当您通过按钮更新状态时,您会通过连接获取值,而 getInitialProps
不会覆盖它们。
据我了解,您是说“props.goods”不存在。如果是这种情况,您应该共享您的减速器以查看您返回的内容
@Yilmaz 感谢您的关注。我刚刚添加了 itemReducer.js。我想不通的是,即使getItems()在Index.getInitialProps
中调度,并且取到的数据存储在全局状态中,状态通过mapStateToProps
映射到页面props,结果是页面中的props.item.goods
为空。我可以知道获取的数据是在调度动作之后存储的,因为当我在getInitialProps
中调度动作之后console.log store.getState()
时,它表明`goods'数组中存储了数据。
【参考方案1】:
首先,getInitialProps()
通常会返回一些页面道具。那么,您知道mapStateToProps()
有第二个(可选)输入参数吗?见react-redux documentation。
const Index = ( goods, getItems ) => (
<>
<Head>
<title>Item List</title>
</Head>
<div>JSON.stringify(goods)</div>
<div>
<Button onClick=() => getItems()>Get Items!</Button>
</div>
</>
);
Index.getInitialProps = async ( store ) =>
const goods = await store.dispatch(getItems());
return goods ;
;
const mapStateToProps = (state, ownProps) => (
// At this point you could source your data either
// from `state.goods` or `ownProps` (which now has a `goods` prop).
// But sourcing it from the redux store means as soon as `goods`
// changes in the redux store, your component will re-render with
// the updated `goods`. A key aspect of `mapStateToProps()`.
goods: ...state.goods
);
const mapDispatchToProps = dispatch => (
// I am assuming that dispatching this action will create
// a value in the redux store under the `goods` property
getItems: () => dispatch(getItems())
);
export default connect(mapStateToProps, mapDispatchToProps)(Index);
【讨论】:
以上是关于Next.js + Redux:在服务器端获取的数据永远不会移动到页面道具的主要内容,如果未能解决你的问题,请参考以下文章
Next.js + Redux:在 getInitialProps 中获取数据操作完成之前加载一个页面
Next.js s-s-r 存储访问令牌而不使用 redux
next.js 的缺点超过 create react app + redux + s-s-r [关闭]
如何实现redux-toolkit和next,js又不丢s-s-r