And these two days I was trying to use React-router to substitute this old way and it happened this situation between login-page and dashboard-page.
I used to put a submit function calling API to receive the result that decides whether re-render to dashboard-page
But now if I use to re-render which should display, it couldn't pass through the submit function (at least I don't know how to use
So I put history.push() into the submit function's API result, so that when result state is "true", history.push() would be execute.
But the problem happened here, that's, the history.push execute completely and URL has rightly changed to localhost:3000/dashboard but my page doesn't change at all.
By the way, I use the Create-react-app
here is my code
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>
and here is the 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;
You should first define your routes in your App.js
like so:
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);
Then , in your Login.js, import { useHistory } from 'react-router-dom';
inside Login function , const history = useHistory();
and after your submit API result 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 maintains the stack of your history, that makes it easier to navigate through your app, without have to worry about what routes user has taken. In single page apps, there is only single html page.we are reusing the same html page to render the different components based on the navigation. For details on react router I would suggest you going through Getting started with React Router
Hope that helps!!