使用 React-Router-4,如何以编程方式设置索引路由 `/`
With React-Router-4, how to programmatically set the index route `/`
使用 React-Router-4 如何以编程方式设置索引路由 /
例如,如果用户未通过身份验证,则应触发:
<Route path="/" component={LandingPage}>
如果用户通过身份验证:
<PrivateRoute path="/dashboard" component={Dashboard} />
有关 PrivateRoute
的信息
更新尝试
const WithMainLayout = ({component: Component, ...more}) => {
return <Route {...more} render={props => {
return (
<MainLayout {...props}>
<Component {...props} />
</MainLayout>
);
}}/>;
};
const isLoggedIn = () => {
console.log('do it')
return true;
};
....
<WithMainLayout exact path="/" component={Home} render={() => (
isLoggedIn() ? (
<Redirect to="/dashboard" />
) : (
<Home />
)
)}/>
看到上面的尝试,由于某种原因,console.log
没有在 isLoggedIn 函数中输出任何内容。
您使用 history
道具。您可以在这里阅读:https://reacttraining.com/react-router/web/api/history
本质上,您将组件包装在 withRouter
HOC 中,它会将 history
属性传递给您的组件,您将在此处看到:https://reacttraining.com/react-router/web/api/withRouter。它与 React Recompose 融合得很好。我修改了 react router 文档的 "basic example" 作为这里使用 withRouter 和 history
prop
的例子
// create-react-app test && cd test && npm i && npm install react-router-dom
// replace contents of App.js then `npm run start`
import React, { Component } from 'react';
import { withRouter } from 'react-router'
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom'
class BasicExample extends Component {
render() {
return(
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<hr/>
<Route exact path="/" component={withRouter(Home)}/>
<Route path="/about" component={About}/>
</div>
</Router>
)
}
}
class Home extends Component {
render() {
const {history} = this.props;
const handleClick = (e) => {
history.push("/about")
}
console.log(history)
return (
<div>
<h2>Home</h2>
<button onClick={handleClick}>To about</button>
</div>
)
}
}
const About = () => (
<div>
<h2>About</h2>
</div>
)
export default BasicExample;
如果您在 JSX 中创建 link,请使用 Link
组件,它看起来像这样
<Link to="/">...</Link>
如果您在 PrivateRoute
组件内部执行此操作,我认为您想要的更像是 Redirect
组件:https://reacttraining.com/react-router/web/api/Redirect
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
props.isAuthorized ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/',
state: { from: props.location }
}}/>
)
)}/>)
我会在 IndexRoute
上使用 onEnter
方法,并根据需要以编程方式将用户发送到正确的位置:
<IndexRoute onEnter={handlePath}>
处理程序看起来像这样,userIsAutheticaed
被适当的代码替换:
function handlePath(route, replace) {
if (userIsAuthenticated) {
replace('/dashboard');
} else {
replace('/');
}
}
所以在您的更新代码中,问题是您 return
<Route {...more} render={props => {
所以本质上发生的是 render
传递给 WithMainLayout
组件的 {...more}
组件被自定义组件覆盖,因此 isLoggedIn
从未被调用。
解决方法很简单,你可以互换 {...more}
和 render={props => {}}
并用 WithMainLayout
包装你的 Home 组件,这样它就不会错过 Layout
你的代码看起来像
const WithMainLayout = ({component: Component, ...more}) => {
return <Route render={props => {
return (
<MainLayout {...props}>
<Component {...props} />
</MainLayout>
);
}} {...more} />;
};
const isLoggedIn = () => {
console.log('do it')
return true;
};
....
<WithMainLayout exact path="/" component={Home} render={() => (
isLoggedIn() ? (
<Redirect to="/dashboard" />
) : (
<WithMainLayout component={Home} />
)
)}/>
使用 React-Router-4 如何以编程方式设置索引路由 /
例如,如果用户未通过身份验证,则应触发:
<Route path="/" component={LandingPage}>
如果用户通过身份验证:
<PrivateRoute path="/dashboard" component={Dashboard} />
有关 PrivateRoute
的信息更新尝试
const WithMainLayout = ({component: Component, ...more}) => {
return <Route {...more} render={props => {
return (
<MainLayout {...props}>
<Component {...props} />
</MainLayout>
);
}}/>;
};
const isLoggedIn = () => {
console.log('do it')
return true;
};
....
<WithMainLayout exact path="/" component={Home} render={() => (
isLoggedIn() ? (
<Redirect to="/dashboard" />
) : (
<Home />
)
)}/>
看到上面的尝试,由于某种原因,console.log
没有在 isLoggedIn 函数中输出任何内容。
您使用 history
道具。您可以在这里阅读:https://reacttraining.com/react-router/web/api/history
本质上,您将组件包装在 withRouter
HOC 中,它会将 history
属性传递给您的组件,您将在此处看到:https://reacttraining.com/react-router/web/api/withRouter。它与 React Recompose 融合得很好。我修改了 react router 文档的 "basic example" 作为这里使用 withRouter 和 history
prop
// create-react-app test && cd test && npm i && npm install react-router-dom
// replace contents of App.js then `npm run start`
import React, { Component } from 'react';
import { withRouter } from 'react-router'
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom'
class BasicExample extends Component {
render() {
return(
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<hr/>
<Route exact path="/" component={withRouter(Home)}/>
<Route path="/about" component={About}/>
</div>
</Router>
)
}
}
class Home extends Component {
render() {
const {history} = this.props;
const handleClick = (e) => {
history.push("/about")
}
console.log(history)
return (
<div>
<h2>Home</h2>
<button onClick={handleClick}>To about</button>
</div>
)
}
}
const About = () => (
<div>
<h2>About</h2>
</div>
)
export default BasicExample;
如果您在 JSX 中创建 link,请使用 Link
组件,它看起来像这样
<Link to="/">...</Link>
如果您在 PrivateRoute
组件内部执行此操作,我认为您想要的更像是 Redirect
组件:https://reacttraining.com/react-router/web/api/Redirect
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
props.isAuthorized ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/',
state: { from: props.location }
}}/>
)
)}/>)
我会在 IndexRoute
上使用 onEnter
方法,并根据需要以编程方式将用户发送到正确的位置:
<IndexRoute onEnter={handlePath}>
处理程序看起来像这样,userIsAutheticaed
被适当的代码替换:
function handlePath(route, replace) {
if (userIsAuthenticated) {
replace('/dashboard');
} else {
replace('/');
}
}
所以在您的更新代码中,问题是您 return
<Route {...more} render={props => {
所以本质上发生的是 render
传递给 WithMainLayout
组件的 {...more}
组件被自定义组件覆盖,因此 isLoggedIn
从未被调用。
解决方法很简单,你可以互换 {...more}
和 render={props => {}}
并用 WithMainLayout
包装你的 Home 组件,这样它就不会错过 Layout
你的代码看起来像
const WithMainLayout = ({component: Component, ...more}) => {
return <Route render={props => {
return (
<MainLayout {...props}>
<Component {...props} />
</MainLayout>
);
}} {...more} />;
};
const isLoggedIn = () => {
console.log('do it')
return true;
};
....
<WithMainLayout exact path="/" component={Home} render={() => (
isLoggedIn() ? (
<Redirect to="/dashboard" />
) : (
<WithMainLayout component={Home} />
)
)}/>