使用React-Router-4,如何以编程方式设置索引路由`/`

时间:2017-06-26 14:19:02

标签: reactjs react-router react-router-v4

使用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函数中输出任何内容。

3 个答案:

答案 0 :(得分:2)

因此,在您的更新代码中,问题是您返回

<Route {...more} render={props => {

所以实际上发生的事情是render传递给WithMainLayout组件的{...more}道具可以被isLoggedIn覆盖,但是你的自定义道具会被覆盖,因此{...more}永远不会调用。

解决方案很简单,您只需要交换render={props => {}}WithMainLayout,并使用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} /> ) )}/> 包装您的Home组件,这样就不会错过布局

您的代码看起来像

{{1}}

答案 1 :(得分:1)

您使用history道具。您可以在此处阅读:https://reacttraining.com/react-router/web/api/history

基本上,您将组件包装在withRouter HOC中,它会将history道具传递给您在此处看到的组件:https://reacttraining.com/react-router/web/api/withRouter。它与React Recompose很好地融合在一起。我修改了&#34;基本示例&#34;作为一个例子,反应路由器文档使用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 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 }
        }}/>
      )
    )}/>)

答案 2 :(得分:1)

我会在onEnter上放置IndexRoute方法,并根据需要以编程方式将用户发送到正确的位置:

<IndexRoute onEnter={handlePath}>

处理程序看起来像这样,userIsAutheticaed替换为相应的代码:

function handlePath(route, replace) {
   if (userIsAuthenticated) {
          replace('/dashboard');
   } else {
          replace('/');
   }
}