我是 next-redux-wrapper 的新手,并试图用它来跨页面保持状态。
在主页上,我有登录操作。登录成功后,我将 session.loggedIn : true 添加到 redux 商店。
当我转换到下一页 (getServerSideProps) 时,正在调用 HYDRATE 操作,但 action.payload 为空。当这个空对象与之前的状态合并时,之前的所有状态都会丢失。
我在第一页的代码与 getInitial Props:
//Index.getInitialProps = async(/* ctx */) => {
Index.getInitialProps = wrapper.getInitialPageProps( store => async ({pathname, req, res}) => {
try {
let promises = []
promises.push(fetch(URLMap("categoriesAPI")).then(res => res.json()))
const pageNum=1, itemsPerPage=10
let collectionsURL = URLMap('myCollectionAPI')
collectionsURL = `${collectionsURL}?pageNum=${pageNum}&itemsPerPage=${itemsPerPage}`
promises.push(fetch(collectionsURL).then(res => res.json()))
let results = await Promise.all(promises)
//console.log("Result of my collections: ",results[1])
return {categories:results[0].categories, products:results[1].products}
} catch (e) {
console.error("errr while fetching data in 'getInitialProps'", e)
//TODO: Implement a google like notification indicating network failure.
return {}
}
})
转换后的(新页面)具有 getServerSideProps 的以下代码:
export default connect(state => state)(ShopProductPage)
//export async function getServerSideProps({query}) {
export const getServerSideProps = wrapper.getServerSideProps(store => async({query}) => {
console.log('Inside server side props');
let shopId = query.shopId
let productId = query.productId;
console.log("shop id:", shopId)
console.log("product id:", productId)
let promises = []
promises.push(getShopInfo(shopId));
promises.push(getProductInfo(productId));
try {
let allPromises = Promise.all(promises)
let results = await allPromises;
return {props: {
id: shopId,
shopInfo: results[0],
productInfo :results[1]
}}
} catch(e) {
console.error("Failure:", e)
return { props: {}}
}
})
我可以看到,每次我导航到新页面时,水合物有效负载都是空的,并且会覆盖之前的状态。我在这里错过了什么吗?
编辑
我的reducer代码如下:我意识到服务器端没有太多的状态,如果我将它与客户端的状态合并,它将一扫而光。所以,我决定在他的水合物方法中返回未修改的状态(没有合并)。现在,它适用于我的用例。
我还有另一个问题,如果我重新加载页面,或者通过浏览器的地址栏导航到新页面,这将是一个新的加载并且没有可用的状态。看起来我已经使用 Redux Persist 来解决第二个问题。
import {applyMiddleware, createStore} from 'redux';
import {createWrapper, HYDRATE} from 'next-redux-wrapper';
import thunk from "redux-thunk"
import logger from 'redux-logger'
let store
const initialState = {
//TODO: Add initial state of our app here.
//showLogin: false,
loginProcessState: 0, // 0:false (don't show), 1:showLoginDialog, 2:login submit begin, 3: login submit failed, 4:showOTPDialog,
contactInfoDisplay: false, // false:don't show; true: show
contactEditDisplay: false,
session: { loggedIn : false
/*
// If logged in, it will have these values also (sample)
name: "Ravindranath M",
mobile: "xxxxxxx982",
email: "someone@somewhere.com",
pincode: "560097"
*/
},
cart: {total: 0, products : []}, // product structure {_id:'', qty:''}
contactInfoDisplay: 0 //0:no display, 1:display, 2:edit
}
const reducer = (state=initialState, action) => {
switch (action.type) {
case HYDRATE: // important case for persisting state between client and server!
//return {...state, ...action.payload}
return {...state }
case 'SET_CATEGORIES':
return {
...state,
categories: action.categories
}
case 'SHOW_LOGIN_DLG':
console.log("Reducer executing 'SHOW_LOGIN_DLG' action...")
return { ...state, loginProcessState: 1 } // show login dialog