简体   繁体   中英

React-Router V4 - Passing Props to Render function in Route Component to generate new component

I can't get my head around how to render a child component of <Route> that will check a prop boolean from a parent to see if the state is authorized. I want to be able to pass other props using spread to future proof it. Could someone help me to try and unscrew this?

Here is my code for the Private Route I am trying to create:

import React, { Component } from 'react';
import { Route, Redirect } from 'react-router-dom';
import { app } from '../Base'



export const PrivateRoute = (props) => (
  <Route {...props} render={(props.authenticated) => (
    {props.authenticated} === true
      ? <Component {...props} />
      : <Redirect to='/' />
  )}/>
)

And my App.js

class App extends Component {
  constructor () {
    super();
    this.state = {
      authenticated: false,
      loading: true
    };
  }

  componentWillMount() {
        this.removeAuthListener = app.auth().onAuthStateChanged((user) => {
          if (user) {
            this.setState({
              authenticated: true,
              loading: false
            })
          } else {
            this.setState({
              authenticated: false,
              loading: false
            })
          }
        })
  }




  componentWillUnmount () {
      this.removeAuthListener();
  }

  render() {
    if (this.state.loading === true){
      return (
      <div style={{ textAlign: "center", position: "absolute", top: "25%", left: "50%"}}>
        <h3>Loading</h3>
      </div>
    )} else{
    return (
      <div style= { sectionStyle } className="App">
        <div className="Jumbotron">
            <Header authenticated={this.state.authenticated}/>
            <Switch> 
                <Route exact path="/" render={() => {

                }}component={Jumbo}/>
                <Route exact path="/login" component={Login}/>
                <Route exact path="/logout" component={Logout}/>
                <PrivateRoute path="/dashboard" component={Dashboard} authenticated={this.state.authenticated}/>
                <Route component={NotFound}/>
            </Switch>
        </div>
      </div>
    )}
  }
}

export default App;

In the inline function you pass to render , you have access to props so you could do something like this:

export const PrivateRoute = (props) => (
  <Route to={props.path} render={() => {
    if(props.authenticated) {
        return <Component {...props} />;
    }

    return <Redirect to="/" />;
  }}/>
);

Not sure, but I think this should be written like

export const PrivateRoute = (props) => (
  <Route {...props} render={({...props}) => (
    {props.authenticated ? <Component {...props} /> : <Redirect to='/' />
  }/>
)

And make sure authenticate is well passed through your top component.

 const PrivateRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={props => (Meteor.userId() ? ( <Component {...props} /> ) : ( <Redirect to={{ pathname: '/', state: { from: props.location }, }} /> )) } /> ); export const renderRoutes = () => ( <Router history={browserHistory}> <div> <Route exact path="/" component={props => <Dashboard {...props} data={{ main: Promotions }} />} /> <Switch> <Route path="/coin/:coin/:address" component={props => <Dashboard {...props} data={{ main: Wallet }} />} /> </Switch> </div> </Router> ); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM