React-router history.push() 已成功更改 URL 但未将我的 JXS 内容重新呈现为具有匹配路径的正确路由内容

React-router history.push() has changed URL successfully but not re-render my JXS content to the right Route content with matched path

  1. 我过去常常通过渲染整个页面的组件来更改页面,其中使用 setState "currentPage:'xxx'" 和 render 内的 switch case 来匹配正确的参数,这样它就可以渲染 'xxx' 的内容。

这两天我想用React-router来代替这种老办法,在login-page和dashboard-page之间就出现了这种情况

我曾经放置一个调用 API 的提交函数来接收决定是否重新呈现到仪表板页面的结果

但是现在如果我用re-render 来显示应该显示的,它不能通过提交功能(至少我不知道如何使用

所以我把history.push()放入提交函数的API结果中,这样当结果状态为"true"时,history.push()就会被执行。

但是这里出现了问题,即history.push完全执行并且URL正确地更改为localhost:3000/dashboard但是我的页面根本没有改变。

  1. 我有第二个问题,与我的旧 swich-case-render 方式相比,使用 React-router 有什么优势?

对了,我用的是Create-react-app

这是我的代码

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import axios from 'axios';
import './dist/css/adminlte.min.css';
import './plugins/fontawesome-free/css/all.min.css';
import './plugins/icheck-bootstrap/icheck-bootstrap.min.css';
import  { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Login from "./Login";
import Board from "./Board";
import { createBrowserHistory } from 'history';

class Ares extends React.Component {
    constructor(props) {
        super(props);
        console.log("reconstructor");
        this.state={
            currentPage:"login",
            currentMainContent:"empty",
            currentNav:"Classic",
            account:'moore_huang@you-ce.net',
            email:'',
            password:'abc123' ,
            sid:'',
            startAt:new Date('1970-01-01 12:00:00'),
            endAt:new Date(),
            access_token:'',
            memberPage:1,
            memberData:[],
            nowPick:'',
        };
    }
    handleChange(event){//每一鍵輸入後觸發 檢查輸入字元
        const target=event.target;
        this.setState({
            [target.name]: target.value
        });
    }
    submitLogin(event){
        event.preventDefault();
        //------------------------------------------------------
        axios.post('/api/login',
            {
                email:this.state.account,
                password:this.state.password
            },
            {
                baseURL:'http://www.localhost.ares.net'
            })
            .then((result) => this.getSidFunc(result.data))
            .catch((error) => { console.error(error) })
    }
    submitLogin2(event){
        event.preventDefault();
        this.setState({
            sid:'Im in',
            currentPage:'home',
        });
    }
    getSidFunc(response){
        if(response.status===1){
            console.log("login success");
            let history=createBrowserHistory();
            // let history = this.props.history;
            history.push("/dashboard",true);
            // this.state.history.push("/dashboard");
            console.log(history);
            // window.location.href=window.location.origin+"/dashboard";
            this.setState({
                sid:'Im in',
                currentPage:'home',
                access_token:response.result.access_token
            });
            console.log("----------------------------");

        }else{
            console.log("login fail");
            alert("wrong account or password");
        }
    }
    postRequest(url, payload, onLoadFunc, onErrorFunc, bRetry){
        var xhr = new XMLHttpRequest();
        xhr.open("POST", url);
        xhr.setRequestHeader('Content-type', 'application/json');
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xhr.onload = function(event)
        {
            var jsonData = null;
            try
            {
                jsonData = JSON.parse(xhr.responseText);
                if (onLoadFunc)
                    onLoadFunc(jsonData);
            }
            catch(e)
            {
                console.log(e);
                console.log("xhr json error    bRetry: " + bRetry + "    data: \n" + xhr.responseText);
                if (bRetry)
                {
                    setTimeout(function()
                    {
                        this.postRequest(url, payload, onLoadFunc, onErrorFunc, bRetry);
                    }, 3000);
                }
            }
        };
        xhr.onerror = function(event)
        {
            console.log("xhr onerror    bRetry: " + bRetry);
            if (onErrorFunc)
                onErrorFunc(event);
            if (bRetry)
            {
                setTimeout(function()
                {
                    this.postRequest(url, payload, onLoadFunc, onErrorFunc, bRetry);
                }, 3000);
            }
        };

        xhr.send(JSON.stringify(payload));
    }


    render() {
        console.log("////////////");
        console.log(this.state);
        return (
            <Router>
                <Switch>
                    <Route exact={true} path="/">
                        <Login
                            submitLogin={(event) => this.submitLogin(event)}
                            submitLogin2={(event) => this.submitLogin2(event)}
                            handleChange={(event) => this.handleChange(event)}
                            account={this.state.account}
                            password={this.state.password}
                        />
                    </Route>
                    <Route exact={true} path="/dashboard">
                        <Board

                        />
                    </Route>
                </Switch>
            </Router>
        );
    }
}
// ========================================

ReactDOM.render(
    <Ares />,
    document.getElementById('root')
);
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">

    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />

    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>

  </body>
</html>

这里是 Login.js

import React from 'react';
import ReactDOM from 'react-dom';
import  { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';

function Login(props) {
    console.log("renderLogin");
    return (
        <div className="hold-transition login-page">
            <div className="login-box">
                <div className="login-logo">
                </div>
                <div className="card">
                    <div className="card-body login-card-body">
                        <p className="login-box-msg">Sign in to start your session</p>
                        <form onSubmit={props.submitLogin}>
                            <div className="input-group mb-3">
                                <input
                                    type="email"
                                    className="form-control"
                                    placeholder="Email"
                                    onChange={props.handleChange}
                                    name={"account"}
                                    value={props.account}
                                />
                                <div className="input-group-append">
                                    <div className="input-group-text">
                                        <span className="fas fa-envelope"></span>
                                    </div>
                                </div>
                            </div>
                            <div className="input-group mb-3">
                                <input
                                    type="password"
                                    className="form-control"
                                    placeholder="Password"
                                    onChange={props.handleChange}
                                    name={"password"}
                                    value={props.password}
                                />
                                <div className="input-group-append">
                                    <div className="input-group-text">
                                        <span className="fas fa-lock"></span>
                                    </div>
                                </div>
                            </div>
                            <div className="row">
                                <div className="col-8">
                                    <div className="icheck-primary">
                                        <input type="checkbox" id="remember"/>
                                        <label htmlFor="remember">
                                            Remember Me
                                        </label>
                                    </div>
                                </div>
                                <div className="col-4">
                                    {/*<Link to='/dashboard'>*/}
                                        <button className="btn btn-primary btn-block">Sign In</button>
                                    {/*</Link>*/}
                                </div>
                            </div>
                        </form>

                        <div className="social-auth-links text-center mb-3">
                            <p>- OR -</p>
                            <a onClick={props.submitLogin2}>
                                <i  className="fab fa-facebook mr-2"></i> Sign in using Facebook
                            </a>
                            <a href="#" className="btn btn-block btn-danger">
                                <i className="fab fa-google-plus mr-2"></i> Sign in using Google+
                            </a>
                        </div>

                        <p className="mb-1">
                            <a href="forgot-password.html">I forgot my password</a>
                        </p>
                        <p className="mb-0">
                            <a href="register.html" className="text-center">Register a new membership</a>
                        </p>
                    </div>
                </div>
            </div>
        </div>
    );
}

export default Login;

请在 class 之外声明历史对象。 例如

const history = createBrowserHistory();

然后请更改这些行

let history=createBrowserHistory();
history.push("/dashboard",true);

history.push("/dashboard")

最后,

render() {
    console.log("////////////");
    console.log(this.state);
    return (
        <Router history={history}>
            <Switch>

此外,我建议您使用 Link 而不是标签

您应该首先在 App.js 中定义您的路线,如下所示:

import React, { Component } from 'react';
import './App.css';
import {BrowserRouter, Route, Redirect, Switch, withRouter,browserHistory} from 'react-router-dom';
import {Router} from 'react-router';
import Login from './Login';
import DashBoard from './DashBoard';

class App extends Component {
  render() {
    return (
      
<div className="App">
<Switch>
    <Route exact path='/' component={Login} />
    <Route exact path='/DashBoard' component={DashBoard} />
  </Switch>
      </div>
   );
  }
}

export default withRouter(App);

然后,在您的 Login.jsimport { useHistory } from 'react-router-dom';

登录函数中,const history = useHistory();

在您提交 API 结果后 history.push('/DashBoard')

Now coming your second question what's the advantage of using React-router compared to my old swich-case-render way?

React router 维护你的历史堆栈,这使得在你的应用程序中导航更容易,而不必担心用户选择了哪些路线。在单页面应用程序中,只有一个 html page.we 重复使用相同的 html 页面来根据导航呈现不同的组件。有关反应路由器的详细信息,我建议您通过 Getting started with React Router

希望对您有所帮助!!