URL изменяется, но новая страница страницы не отображается Ionic React, IonReactRouter с историей
Я пишу приложение с использованием Ionic 5 с React и Redux. Я пытаюсь перейти на новую страницу / tabs / home после успешной попытки входа в систему. Я пытаюсь сделать это, вставив новый URL-адрес в опору истории реактивного маршрутизатора, когда я получаю успешный ответ от бэкэнда. Это работает тем, что он меняет URL-адрес с / login на / tabs / home, но страница входа по-прежнему отображается.
index.tsx
import React from 'react';
import {render} from 'react-dom';
import App from './App';
import { Provider } from 'react-redux';
import { store } from './helpers/store';
import { Router } from 'react-router';
import CreateBrowserHistory from 'history/createBrowserHistory';
export const history = CreateBrowserHistory();
render(
<Provider store={store}>
<Router history={history}>
<App />
</Router>
</Provider>,
document.getElementById('root')
);
App.tsx
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { history } from './index';
import { alertActions } from './actions/alert.actions';
import { Route } from 'react-router-dom';
import {
IonApp,
} from '@ionic/react';
import { IonReactRouter } from '@ionic/react-router';
import { LoginPage } from './pages/Login';
import MainTabs from './pages/MainTabs';
function App() {
const alert = useSelector(state => state.alert);
const dispatch = useDispatch();
useEffect(() => {
history.listen((location, action) => {
console.log(location);
console.log(action);
dispatch(alertActions.clear());
});
}, []);
return (
<IonApp>
{/*
// @ts-ignore*/}
<IonReactRouter history={history}>
<Route path="/tabs" component={MainTabs} />
<Route path="/login" component={LoginPage} />
</IonReactRouter>
</IonApp>
)
}
export default App;
Login.tsx
function LoginPage() {
const [inputs, setInputs] = useState({
username: '',
password: ''
});
const [submitted, setSubmitted] = useState(false);
const { username, password } = inputs;
const loggingIn = useSelector(state => state.authentication.loggingIn);
const dispatch = useDispatch();
useEffect(() => {
dispatch(userActions.logout());
}, []);
function handleChange(e) {
const { name, value } = e.target;
setInputs(inputs => ({ ...inputs, [name]: value }));
}
function handleSubmit(e) {
e.preventDefault();
setSubmitted(true);
if (username && password) {
dispatch(userActions.login(username, password));
}
}
return (
<IonPage id="login-page">
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonMenuButton></IonMenuButton>
</IonButtons>
<IonTitle>Login</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
<form noValidate onSubmit={handleSubmit}>
<IonList>
<IonItem>
<IonLabel position="stacked" color="primary">Username</IonLabel>
<IonInput name="username" type="text" value={username} spellCheck={false} autocapitalize="off" onIonChange={handleChange} className={'form-control' + (submitted && !username ? ' is-invalid' : '')} required>
</IonInput>
</IonItem>
<IonItem>
<IonLabel position="stacked" color="primary">Password</IonLabel>
<IonInput name="password" type="password" value={password} onIonChange={handleChange} className={'form-control' + (submitted && !password ? ' is-invalid' : '')} required>
</IonInput>
</IonItem>
</IonList>
<IonRow>
<IonCol>
{loggingIn && <span className="spinner-border spinner-border-sm mr-1"></span>}
<IonButton type="submit" expand="block">Login</IonButton>
</IonCol>
<IonCol>
<IonButton routerLink="/signup" color="light" expand="block">Signup</IonButton>
</IonCol>
</IonRow>
</form>
</IonContent>
</IonPage>
)
}
export { LoginPage };
действие входа
function login(username, password) {
return dispatch => {
dispatch(request({ username }));
userService.login(username, password)
.then(
user => {
dispatch(success(user));
history.push('/tabs/home');
},
error => {
dispatch(failure(error.toString()));
dispatch(alertActions.error(error.toString()));
}
);
};
function request(user) { return { type: userConstants.LOGIN_REQUEST, user } }
function success(user) { return { type: userConstants.LOGIN_SUCCESS, user } }
function failure(error) { return { type: userConstants.LOGIN_FAILURE, error } }
}
3 ответа
ВЫПУСК:
Согласно документу:
В IonReactRouter
компонент обертывает традиционный BrowserRouter
компонент из React Router и настраивает приложение для маршрутизации. Поэтому используйтеIonReactRouter
на месте BrowserRouter
. Вы можете передать любой реквизит вIonReactRouter
и они будут переданы нижестоящему BrowserRouter
.
Я думаю обычай history
не поддерживается BrowserRouter
, как вы видете BrowserRouter
поддерживает этот реквизит, там нет history
реквизит там
basename
forceRefresh
getUserConfirmation
keyLength
children
history
реквизит доступен для Router
РЕШЕНИЕ:
Итак, я внес ниже изменения для использования пользовательской истории, и она работает
index.js
import React from "react";
import { render } from "react-dom";
import App from "./App";
import { Provider } from "react-redux";
import { store } from "./helpers/store";
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
App.tsx
<IonApp>
<Router history={history}>
{/* <IonReactRouter history={history}> */}
<Route path="/tabs" component={MainTabs} />
<Route exact path="/" component={LoginPage} />
{/* </IonReactRouter> */}
</Router>
</IonApp>
ИЛИ
Вы можете использовать что-то вроде этого как hack, ref
import React from 'react'
import { History } from 'history'
import { useHistory } from 'react-router'
// Add custom property 'appHistory' to the global window object
declare global {
interface Window { appHistory: History }
}
const MyApp: React.FC = () => {
// Store the history object globally so we can access it outside of React components
window.appHistory = useHistory()
...
}
Просто положите exact
атрибут в Маршруте, чтобы решить эту
<Route path="/tabs" exact component={MainTabs} />
<Route path="/login" exact component={LoginPage} />
В вашем коде у вас есть
<Route path "/tabs" component={MainTabs} />
Когда вместо этого должно быть
<Route path "/tabs/home" component={MainTabs} />
Когда вы пытаетесь продвинуть свою историю с помощью /tabs/home
для этого не указан маршрут, поэтому он не будет знать, куда идти.
Также в вашем индексном файле я бы порекомендовал иметь дополнительный маршрут вроде этого
<Route exact path "/tabs" component={SomeComponent} />
<Route path "/tabs/home" component={MainTabs} />
На всякий случай, если вы планируете привязать к вашему /tabs
маршрут.