PersistGate 在状态加载之前打开

PersistGate opens before state loads

我已经用 redux-persist 实现了 redux。 一切正常,除了 PersistGate 组件在页面加载的最开始,在刷新后释放流而不从存储中加载状态。

正如您在下图中看到的,我收到了一个从 redux 存储中转储状态的日志。此日志位于 PersistGate 组件之后。而上面的状态是页面完全加载后的状态。

我的 index.js 文件(只有导入和 ReactDOM.render() 方法):

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <ThemeProvider theme={theme}>
        <CookiesProvider>
          <Router>
            <PersistGate loading={null} persistor={persistor}>
              {console.log('store after gate opens', store.getState())}
              <App />
            </PersistGate>
          </Router>
        </CookiesProvider>
      </ThemeProvider>
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

我的 store.js 文件:

import storage from 'redux-persist/lib/storage';
import { createStore } from 'redux';
import rootReducers from './reducers';
import { persistReducer, persistStore, autoMergeLevel2 } from 'redux-persist';

const persistConfig = {
  key: 'root',
  storage,
  stateReconciler: autoMergeLevel2
}
const persistedReducer = persistReducer(persistConfig, rootReducers);  

const store = createStore(persistedReducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
export const persistor = persistStore(store);

export default store;

我的问题是我有一个请求拦截器,它将令牌注入 header 以获得授权。在商店加载之前几乎没有请求(因为这个门过早打开),这使得我的调用在没有令牌的情况下触发。

我是不是漏掉了什么?

所以最终我放弃了这个并采用了不同的解决方案。

创建了我自己的组件:

import { useEffect, useState } from "react"
import { useSelector } from "react-redux";

const StoreGate = ({children}) => {
  const [isGateOpen, setIsGateOpen] = useState(false)
  const _persist = useSelector(state => state._persist);

  useEffect(() => {
    setIsGateOpen(_persist.rehydrated);

  }, [_persist.rehydrated])

  return ( 
    <>
      {isGateOpen ? children: null}
    </>
  )
}

export default StoreGate

用法:

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <ThemeProvider theme={theme}>
        <CookiesProvider>
          <Router>
            <StoreGate>
              <App />
            </StoreGate>
          </Router>
        </CookiesProvider>
      </ThemeProvider>
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

这将锁定内容道具的渲染,直到状态被水合。