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

像 next.js 这样的服务器端渲染中状态管理的最佳方法是啥?

我已经在 next js 中使用 next-redux-wrapper 成功实现了 redux-persist