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 в своем примере. Где это находится?