React Router V4 защищенный частный маршрут с Redux-persist и React-snapshot

Я реализую частный маршрут так, используя компонент React Router Route:

function PrivateRoute({component: Component, authed, emailVerified, ...rest}) {
  return (
    <Route
      {...rest}
      render={props =>
        authed === true
          ? <Component {...props} />
          : <Redirect to={{pathname: '/', state: {from: props.location}}} />}/>
  )
}

Ожидаемое поведение:

authed сохраняется через обновление страницы с помощью redux-persist На странице refresh или reload, если authed prop имеет значение true тогда маршрутизатор должен отображать <Component/> без перехода к пути "/"

Фактическое поведение, которое является проблемой:

С authed === true (сохраняется) перезагрузка страницы или ее обновление приводит к выполнению следующих действий (проверено redux devtools): "@@router/LOCATION_CHANGE" выполняется и переводит его на правильный безопасный маршрут, но затем "@@router/LOCATION_CHANGE" снова запускается и перенаправляется на "/" на мгновение, и, наконец, "@@router/LOCATION_CHANGE" снова запускается и перенаправляет маршрут обратно на безопасный путь, даже если authed === true через все это в redux devtools

Тогда: Я предполагаю, что эта ошибка имеет что-то с моим основным компонентом App Component до того, как у redux-persist есть время, чтобы повторно увлажнить хранилище Redux.

Поэтому я попытался сделать следующее:

Я попытался отложить мой основной компонент App до тех пор, пока мой магазин не будет повторно гидратирован с использованием redux-persist следующим образом:

  render() {
    const {authed, authedId, location, rehydrationComplete} = this.props
    return (
      <div>
      { rehydrationComplete
       ? <MainContainer>
          <Switch key={location.key} location={location}>
            <Route exact={true} path='/' component={HomeContainer} />
            <Route render={() => <h2> Oops. Page not found. </h2>} />
          </Switch>
      </MainContainer>
      : <div>...Loading </div> }
      </div>
    )
  }

Это эффективно устраняет проблему выше изменения пути при "@@router/LOCATION_CHANGE" действия "@@router/LOCATION_CHANGE" (только изменения ключей пути). Однако это приводит к другой проблеме с помощью React-snapshot Теперь: все статические генерируемые html файлы из react-snapshot Теперь содержат только ...Loading. Я попытался установить snapshotDelay из 8200 в опции react-snapshot, но это не решило проблему.

Затем: я попробовал следующее: отложить вызов React-snapshot чтобы он отображал html после того, как хранилище было регидратировано:

import {render as snapshotRender} from 'react-snapshot'
import {ConnectedRouter} from 'react-router-redux'

async function init() {
const store = await configureStore()
snapshotRender(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <App />
    </ConnectedRouter>
  </Provider>,
  document.getElementById('root')
)

registerServiceWorker()
}

init()

Но теперь я получаю ошибку: этот 'render' from react-snapshot was never called. Did you replace the call to ReactDOM.render()? 'render' from react-snapshot was never called. Did you replace the call to ReactDOM.render()?

Я знаю, что это загруженный вопрос, но я хочу эффективно использовать эти 3 библиотеки (React-Router V4, Redux-persist, React-snapshot) вместе, чтобы обслуживать защищенные маршруты без упомянутых ошибок.

Ответы

Ответ 1

У меня что-то похожее на вас. Здесь я использую React-Router V4 и постоянную библиотеку.

Ваш маршрутизатор/маршруты не обязательно должны знать о сохранении. Они должны полагаться на ваш магазин redux. Сохранение должно заново хранить ваш магазин со всеми данными.

Я не видел, где вы используете компонент PrivateRoute в своем примере. Где это находится?