在 NextJS 的 getServerSideProps 中访问 Redux 存储
Posted
技术标签:
【中文标题】在 NextJS 的 getServerSideProps 中访问 Redux 存储【英文标题】:Access Redux store in getServerSideProps in NextJS 【发布时间】:2020-10-30 05:53:22 【问题描述】:我想在 getServerSideProps() 中访问我的 redux 存储;在我的 Next.js 应用程序中。我想拥有存储在 Redux Store 中的用户 ID,以便我可以预加载用户数据。我现在正在使用 next-redux-wrapper 并且在客户端它正在工作。但是当我在 getServerSideProps() 中访问我的商店时,它会返回初始状态。我检查了几个示例,但无法正常工作。
我的 configureStore.js
import createStore, applyMiddleware, compose from "redux";
import reducer from "./../service";
import thunk from 'redux-thunk'
import createWrapper, HYDRATE from 'next-redux-wrapper';
const SET_CLIENT_STATE = 'SET_CLIENT_STATE';
const storeEnhancers = typeof window != 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const makeStore = ( isServer ) =>
if (isServer)
return createStore(reducer, storeEnhancers(applyMiddleware(thunk)) );
else
const persistStore, persistReducer = require('redux-persist');
const storage = require('redux-persist/lib/storage').default;
const persistConfig =
key: 'nextjs',
whitelist: ['userReducer'],
storage
;
const store = createStore(
persistReducer(persistConfig, reducer),
storeEnhancers(applyMiddleware(thunk))
);
store.__PERSISTOR = persistStore(store);
return store;
;
export const wrapper = createWrapper(makeStore);
export const setClientState = (clientState) => (
type: SET_CLIENT_STATE,
payload: clientState
);
我的 _app.js:
import React from 'react';
import PropTypes from 'prop-types';
import Head from 'next/head';
import ThemeProvider from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import theme from '../styles/theme';
import useStore from "react-redux";
import PersistGate from 'redux-persist/integration/react';
import wrapper from './../redux/configureStore';
const MyApp = (Component, pageProps) =>
const store = useStore((state) => state);
React.useEffect(() =>
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles)
jssStyles.parentElement.removeChild(jssStyles);
, []);
return (
<React.Fragment>
<Head>
<title>Deeltuinen</title>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
</Head>
<PersistGate persistor=store.__PERSISTOR loading=null>
<ThemeProvider theme=theme>
<CssBaseline />
<Component ...pageProps />
</ThemeProvider>
</PersistGate>
</React.Fragment>
);
export default wrapper.withRedux(MyApp);
MyApp.propTypes =
Component: PropTypes.elementType.isRequired,
pageProps: PropTypes.object.isRequired
;
最后是我想要获取商店状态的页面:
import React from 'react';
import Layout from './../../components/Layout';
import API from './../../service/api';
import connect from "react-redux";
import wrapper, setClientState from './../../redux/configureStore';
const AccountSettings = (data) =>
return (
<Layout title="Deeltuinen">
// User form
</Layout>
);
export const getServerSideProps = wrapper.getServerSideProps(
(store, req, res) =>
const state = store.getState();
console.log(state);
//const data = await API.getUser(state.userReducer.user.token);
);
export default connect(state => state,setClientState)(AccountSettings);
【问题讨论】:
getServerSideProps 几乎是在页面被点击时运行的前几个函数之一,那么它如何包含除 redux 的 intialState 之外的任何其他状态? 我正在使用 redux persist 来保存页面之间的存储。我将用户 ID 存储在我想在 getServerSideProps 中使用的 Redux 存储中。 Redux persist 默认将 redux 状态存储在 localStorage 中,这是一种浏览器实现,因此在服务器端不可用。除非你手动实现了一些东西来持久化状态服务器端,否则它不会工作。 那么获取用户 ID 并使用用户数据创建服务器端呈现页面的最佳策略是什么? 【参考方案1】:我的代码:
export const getServerSideProps = wrapper.getServerSideProps(async ( req, res, store ) =>
const state = store.getState();
console.log('state', state);
return
props: ,
;
);
`
【讨论】:
我得到了初始存储状态,没有我之前存储的值。 @Emke 你找到解决方案了吗?【参考方案2】:如果您需要将一些参数传递给 getServerSideProps,您应该设置页面结构来执行此操作。
例子:
如果我需要从用户那里获得一些积分,而我的 api 需要“userId”参数,我会这样设置我的页面:
pages/credits/[userId].js
这样我可以通过这种方式访问getServerSideProps函数中的userId参数:
export async function getServerSideProps (context)
const userId = context.params
...
// API call to get the Credits by userId
【讨论】:
以上是关于在 NextJS 的 getServerSideProps 中访问 Redux 存储的主要内容,如果未能解决你的问题,请参考以下文章
从零搭建一个基于React+Nextjs的SSR网站:如何搭建服务器并部署Nextjs项目