URL 更改但页面新页面未呈现 Ionic React , IonReactRouter with history [英] URL changes but page new page is not rendered Ionic React , IonReactRouter with history

查看:26
本文介绍了URL 更改但页面新页面未呈现 Ionic React , IonReactRouter with history的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 React 和 Redux 的 Ionic 5 编写应用程序.我试图在成功登录后导航到新页面/tabs/home.当我从后端获得成功响应时,我试图通过将新 URL 推送到 react 路由器历史记录道具来做到这一点.这是有效的,它将 url 从/login 更改为/tabs/home,但仍显示登录页面.

I am writing an app using Ionic 5 with React and Redux. I am attempting to navigate to a new page, /tabs/home, upon a successful login attempt. I am trying to do this by pushing the new URL onto the react router history prop when I get a successful response from the backend. This is working in that it changes the url from /login to /tabs/home but the login page is still displayed.

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;

登录.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 } }
}

推荐答案

ISSUE :

根据文档:

IonReactRouter 组件包装了来自 React Router 的传统 BrowserRouter 组件,并设置应用程序以进行路由.因此,使用 IonReactRouter 代替 BrowserRouter.您可以将任何道具传递给 IonReactRouter,它们将向下传递到底层的 BrowserRouter.

The IonReactRouter component wraps the traditional BrowserRouter component from React Router, and sets the app up for routing. Therefore, use IonReactRouter in place of BrowserRouter. You can pass in any props to IonReactRouter and they will be passed down to the underlying BrowserRouter.

我认为 BrowserRouter 不支持自定义 history,如您所见 BrowserRouter 支持这个props,那里没有history props

I think custom history is not supported by BrowserRouter, as you can see BrowserRouter supports this props, there no history props there

basename
forceRefresh
getUserConfirmation
keyLength
children

history 道具可用于 Router

history props is available for Router

github 上的问题

解决方案:

因此,我对使用自定义历史记录进行了以下更改,并且可以正常工作

So I've made below changes for using custom history and it's working

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


App.tsx

    <IonApp>
      <Router history={history}>
        {/* <IonReactRouter history={history}> */}
        <Route path="/tabs" component={MainTabs} />
        <Route exact path="/" component={LoginPage} />
        {/* </IonReactRouter> */}
      </Router>
    </IonApp>


你可以使用这样的东西作为黑客,ref

You can use something like this as 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()

  ...
}

这篇关于URL 更改但页面新页面未呈现 Ionic React , IonReactRouter with history的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆