我有一个无服务器 Next.js 应用程序,其中有一些组件依赖于从 redux 存储传递的数据。目前我的方法需要 redux-persist 在用户导航时保存商店,否则如果来自商店的数据不存在,上述组件将崩溃。我遇到的问题是围绕整个应用程序的 redux-persist 的 PersistGate 正在阻止对站点的外部请求访问每个页面内的动态元标记。像 metatags.io 这样的工具只能看到来自persistgate 的加载组件。
如果我删除了门,那么标题标签将呈现良好,但 redux 状态不再持久,如果用户在某些页面上刷新页面,则会导致问题。
我已经尝试了 this github issue 中讨论的一些方法,但有条件地包装persistgate 仍然会导致问题,并且“next/head”组件呈现在实际主体内部而不是头部内部。
我对 Next.js 还是很陌生,它提供的 SEO 改进是我选择它而不是简单的 React 的原因。我愿意接受一些不涉及 redux-persist 和可能使用 localstorage 的模式建议。
这是 _app.js 目前的布局:
import App from 'next/app';
// Redux:
import { useStore } from 'redux/store';
import { Provider } from 'react-redux';
import { persistStore } from 'redux-persist';
import { PersistGate } from 'redux-persist/integration/react';
import LoadingView from 'components/base/LoadingView';
import Layout from 'components/base/Layout';
// i18n wrapper:
import { appWithTranslation } from 'i18n';
function MyApp({ Component, pageProps }) {
const store = useStore(pageProps.initialReduxState);
const persistor = persistStore(store, {}, function persist() {
persistor.persist();
});
return typeof window !== 'undefined' ? (
<Provider store={store}>
<PersistGate loading={<LoadingView />} persistor={persistor} onBeforeLift={() => new Promise(resolve => setTimeout(resolve, 1000))}>
<Layout>
<Component {...pageProps} />
</Layout>
</PersistGate>
</Provider>
) : (
<Provider store={store}>
<Layout>
<Component {...pageProps} />
</Layout>
</Provider>
);
}
MyApp.getInitialProps = async appContext => {
const appProps = await App.getInitialProps(appContext);
return { ...appProps };
};
export default appWithTranslation(MyApp);
这是带有 redux-persist 的商店:
// Taken from demo: https://github.com/vercel/next.js/blob/canary/examples/with-redux-persist/store.js
import { useMemo } from 'react';
import { createStore, applyMiddleware } from 'redux';
// Redux DevTools middleware:
import { composeWithDevTools } from 'redux-devtools-extension';
import reduxPromise from 'redux-promise';
// Persist Redux:
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
// Main reducer:
import rootReducer from './reducers';
let store;
const persistConfig = {
key: 'primary',
storage
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
export const makeStore = () => createStore(persistedReducer, composeWithDevTools(applyMiddleware(reduxPromise)));
export const initializeStore = preloadedState => {
let _store = store ?? makeStore(preloadedState);
if (preloadedState && store) {
_store = makeStore({
...store.getState(),
...preloadedState
});
store = undefined;
}
// For SSG and SSR always create a new store
if (typeof window === 'undefined') return _store;
// Create the store once in the client
if (!store) store = _store;
return _store;
};
export function useStore(initialState) {
return useMemo(() => initializeStore(initialState), [initialState]);
}
预先感谢您提供的任何帮助。