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
- 我过去常常通过渲染整个页面的组件来更改页面,其中使用 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但是我的页面根本没有改变。
- 我有第二个问题,与我的旧 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.js、import { 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
希望对您有所帮助!!
- 我过去常常通过渲染整个页面的组件来更改页面,其中使用 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但是我的页面根本没有改变。
- 我有第二个问题,与我的旧 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.js、import { 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
希望对您有所帮助!!