[英]Using NextJS with Redux. Should the store be re-initialised between pages with different preloaded states?
我正在嘗試使 Redux 與 NextJS 一起使用。 在 NextJS 官方 repo 中,您可以找到以下示例:
https://github.com/vercel/next.js/tree/canary/examples/with-redux-thunk
這是 Redux 代碼(初始化存儲的代碼)的主要部分。
import { useMemo } from 'react'
import { createStore, applyMiddleware } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension'
import thunkMiddleware from 'redux-thunk'
import reducers from './reducers'
let store
function initStore(initialState) {
return createStore(
reducers,
initialState,
composeWithDevTools(applyMiddleware(thunkMiddleware))
)
}
export const initializeStore = (preloadedState) => {
let _store = store ?? initStore(preloadedState)
// After navigating to a page with an initial Redux state, merge that state
// with the current state in the store, and create a new store
if (preloadedState && store) {
_store = initStore({
...store.getState(),
...preloadedState,
})
// Reset the current store
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) {
const store = useMemo(() => initializeStore(initialState), [initialState])
return store
}
他們是這樣說的:
每個初始的服務器端請求都將使用一個新的存儲。 但是,每個 Router 或 Link 操作都將在用戶瀏覽頁面時保留相同的存儲。 為了演示這個示例,我們可以使用提供的鏈接來回導航到 /show-redux-state。 但是,如果我們直接導航到 /show-redux-state(或刷新頁面),這將導致服務器端渲染,然后將使用新的存儲。
他們的完整示例不是一個很好的示例,因為沒有一個頁面使用getInitialProps
方法。 因此,您在切換頁面時看不到store
的變化。
// Create the store once in the client
從上面的評論中,我的印象是,無論如何,商店只會在客戶端初始化一次(一次) 。 但事實並非如此。
每次我導航到一個將initialState
添加到 Redux 存儲的頁面(這是通過使用getInitialProps
方法完成的)時,都會在我的客戶端代碼上獲取一個新存儲。 我已經從字面上測試了這種行為。 store
引用確實發生了變化。
這讓我想到:在多個渲染中改變 Redux store
引用不是一種不好的做法嗎? 我的意思是,React 會相應地重新渲染,但是異步代碼呢?
假設我有一個 Redux thunk 仍然掛起,我導航離開頁面。 現在,我的 Redux 存儲將被重新初始化,如果:
getState()
? 該getState()
調用也可能鏈接到以前的商店。這是反模式還是什么?
如果這是否是反模式,我沒有最終答案,但是 NextJS 建議應初始化並重新初始化存儲以合並服務器數據的方式肯定存在限制。
我剛剛進行了以下測試:
_app.tsx
import { useEffect } from "react";
import { Provider } from "react-redux";
import { useStore } from "./useStore";
export default function App({ Component, pageProps }) {
console.log("Rendering App...");
const store = useStore(pageProps.initialReduxState);
const dispatch = store.dispatch;
const getState = store.getState;
useEffect(() => {
console.log("store has changed");
}, [store]);
useEffect(() => {
console.log("dispatch has changed");
}, [dispatch]);
useEffect(() => {
console.log("getState has changed");
}, [getState]);
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
);
}
當我導航到沒有任何pageProps.initialReduxState
值的頁面時,我得到的是:
當我導航到具有pageProps.initialReduxState
值的頁面時,會發生以下情況:
作為這個測試的結果,我認為可以安全地假設在 thunk 中運行的待處理代碼將是陳舊的,並且不會對新存儲產生任何影響。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.