我正在使用react-route,我在路由方面遇到了一些麻烦。
整个页面正在重新加载,导致我已经提取并存储在reducer中的所有数据每次都加载。
这是我的路线档案:
var CustomRoute = React.createClass({
render:function(){
return <Router history={browserHistory}>
<Route path="/" component={Layout}>
<IndexRedirect to="/landing" />
<Route path="landing" component={Landing} />
<Route path="login" component={Login} />
<Route path="form" component={Form} />
<Route path="*" component={NoMatch} />
</Route>
</Router>
},
});
在路由之前,我已经通过调用main.jsx
中的操作来存储数据/** @jsx React.DOM */
'use strict'
var ReactDOM = require('react-dom')
var React = require('react')
var Index = require('./components/index')
var createStore = require("redux").createStore
var applyMiddleware = require("redux").applyMiddleware
var Provider = require("react-redux").Provider
var thunkMiddleware = require("redux-thunk").default
var reducer = require("./reducers")
var injectTapEventPlugin =require('react-tap-event-plugin');
injectTapEventPlugin()
var createStoreWithMiddleware=applyMiddleware(thunkMiddleware)(createStore);
var store=createStoreWithMiddleware(reducer);
store.dispatch(actions.load_contacts()) //////////// <<<<<< this is what i call to store data already
ReactDOM.render( <Provider store={store}><Index/></Provider> , document.getElementById('content'))
问题是如果成功登录,我必须路由到另一个页面:
this.props.dispatch(actions.login(this.state.login,this.state.password,(err)=>{
this.setState({err:err})
if (!err){
window.location = "/form"
}
}));
window.location 可以解决问题,但它会重新加载效率非常低的所有内容。
在手动路线中,我使用<Link\>
路由而不重新加载,但是对于自动化,我不知道该怎么做。
任何建议都将不胜感激。
答案 0 :(得分:9)
对于最新版本(v2.0.0-rc5
),推荐的导航方法是直接推送到历史单例。
相关代码
import { browserHistory } from './react-router'
browserHistory.push('/some/path')
如果使用较新的react-router API,则需要在组件内部使用来自history
的{{1}}:
this.props
如果使用static propTypes = {
history: React.PropTypes.object
}
this.props.history.push('/some/path');
,它会提供react-router-redux
功能,您可以这样发送:
push
在 v2.4.0 及更高版本中,使用更高阶的组件将路由器作为组件的支柱。
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
访问此链接以获取更多信息:http://kechengpuzi.com/q/s31079081
答案 1 :(得分:2)
React >= 16.8 和 react-router v4
没有人提到使用钩子的应用程序的解决方案。从 React 16.8(和 react-router 4,不知道最小版本是什么,我用的是最新的),你可以使用一个叫做 useHistory 的钩子。
import { useHistory } from 'react-router';
const MyHookComponent: React.FC = () => {
const routerHistory = useHistory();
routerHistory.push('/page-where-to-redirect');
return <></>;
}
export default MyHookComponent;
点击此处https://reactrouter.com/web/api/Hooks/了解更多信息。
答案 2 :(得分:1)
以下是我在某些项目中使用的示例路由配置,它应该对您有所帮助:
import App from '../App';
import Home from '../components/pages/Home';
import Login from '../components/pages/Login';
import Register from '../components/pages/Register';
function shouldBeLoggedIn(nextState, replace) {
// const status = getLoginStatus(); //From the State manager
// if( status && !status.loggedin ){
// replace({
// pathname: '/login',
// state: { nextPathname: nextState.location.pathname }
// })
// }
console.log('Should be Logged in!')
}
function shouldNotBeLoggedIn(nextState, replace) {
// const status = getLoginStatus();
// if( status && status.loggedin ){
// replace({
// pathname: '/home',
// state: { nextPathname: nextState.location.pathname }
// })
// }
console.log('Should Not be Logged in!')
}
const rootRoute = {
path: '/',
component: App,
indexRoute: {
component: Login,
onEnter: shouldNotBeLoggedIn
},
indexRedirect: {
to: '/'
},
childRoutes: [ {
path: 'home',
component: Home,
onEnter: shouldBeLoggedIn
}, {
path: 'login',
component: Login,
onEnter: shouldNotBeLoggedIn
}, {
path: 'register',
component: Register,
onEnter: shouldNotBeLoggedIn
}
]
}
export default rootRoute;
在上面的代码中,每个路由都有一个onEnter挂钩到路由器的生命周期方法,它将决定是否应该输入路由。如果你查看评论,你可以决定在钩子方法中做什么。
您可以在以下github repo:http://github.com/pankajpatel/kickstart-react和https://github.com/pankajpatel/kickstart-react/blob/master/src/js/routes/routes.js
上的文件中浏览以上代码以下是react-router's API documentation:
中的示例const userIsInATeam = (nextState, replace, callback) => {
fetch(...)
.then(response = response.json())
.then(userTeams => {
if (userTeams.length === 0) {
replace(`/users/${nextState.params.userId}/teams/new`)
}
callback();
})
.catch(error => {
// do some error handling here
callback(error);
})
}
<Route path="/users/:userId/teams" onEnter={userIsInATeam} />
答案 3 :(得分:1)
首先导入Link组件:
import { Link } from 'react-router-dom'
而不是:
<Route path="landing" component={Landing} />
使用:
<Link to="landing" />
答案 4 :(得分:0)
React Router v4-重定向组件
react-router v4推荐的方法是允许您的render方法捕获重定向。使用状态或道具来确定是否需要显示重定向组件。
参考:https://reacttraining.com/react-router/web/api/Redirect
从Redirect
导入react-router
。
import { Redirect } from 'react-router';
定义Click事件以更改状态。
handleOnClick = () => {
// redirect
this.setState({redirect: true});
}
更改渲染方法,如
render() {
if (this.state.redirect) {
return <Redirect push to="/yourpath" />;
}
return ( <button onClick={this.handleOnClick} type="button">Button</button> );
}
示例代码:
import { Redirect } from 'react-router'; //import Redirect
export default class ConfirmationDialog extends Component{
constructor(props)
{
super(props);
//init the state
this.state = {
redirect : false
}
}
handleOnClick = () => {
//set the redirect property to true for allow redirect
this.setState({redirect: true});
}
render() {
//check if the redirec is allowed
if (this.state.redirect) {
return <Redirect push to="/yourpath" />;
}
//if not put your code here
return (
//your code
<button onClick={this.handleOnClick}
type="button">Button</button>
);
}
}