- I used to change page by rendering whole page’s component in which way to use setState “currentPage:’xxx'” with switch case inside render to match the right parameter, so that it could render the ‘xxx’ ‘s content.
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.
- I’ve the second question which is what’s the advantage of using React-router compared to my old swich-case-render way?
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:'[email protected]',
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;
2
Answers
please declare the history object outside of the class.
for example
and then please change these lines
Finally,
In addition, I recommend that you should use Link instead of a tag
You should first define your routes in your
App.js
like so: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')
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!!