0

Im new to react. I want to redirect to a different component along with some parameters. As of now, Im rendering a Hook Component from App Component with

App.tsx

<Hook region={this.state.region} loginUser={this.state.user.username}/>

But now I've a homePage.tsx, where I've a material ui component CardActionArea, I want to make the whole card component clickable & navigate to Hook component with " /userinfo " url Path and props data (But the param's should be visible in URL) after clicking the Card component.

So in App.tsx , I have

 <HomePage />

In HomePage.tsx,

      <Card className={classes.root}>
            <CardActionArea>

              <CardContent>
              UserInfo
              </CardContent>
            </CardActionArea>
      </Card>

Now how to Call Hook Component after clicking card component in HomePage.tsx with url="/userinfo" and data region & username . (Note: these data(region , username) should not be visible in Url path)

aishu8333
  • 41
  • 1
  • 10

2 Answers2

0

Redirection based on Url works with React Router library (run npm install react-router-dom to install). This should work:

App.ts

function App() {
  // Wrap your HomePage inside a router to access history context
  return (
    <Router>
      <Route path="/" component={HomePage}/>
    </Router>
  );
}

HomePage.tsx

import {withRouter} from 'react-router-dom';


function HomePage(props) {
  const goTo: Function = (url: string) => {
    props.history.push(url);
  };

  return (
    <div>
      <Card className={classes.root} onClick={() => goTo("/userInfo")}>
        <CardActionArea>
          <CardContent>
            UserInfo
          </CardContent>
        </CardActionArea>
      </Card>

      <Router>
        <Route 
          path="/userInfo" 
          render={props => <Hook {...props} foo="bar"/>}
        />
      </Router>
    </div>
  );
}

// instead of export default HomePage;
export default withRouter(HomePage);

Some explaination :

Router component will basically iterate through every child Route. Each time the current URL matches a path prop, it will render the given component. Some route context will automatically be passed to child components afterwards. This allow the given child component to change URL and re-render the Routes, if needed.

HomePage is wrapped in Router, so it can manipulate URL and update render. Since you didn't specified any history context, all the Routers will use the same default one. Now let's say your user is located on the root URL "/". HomePage is rendered and visible, and so is the Card component, but Hook is not.

The onClick method will trigger the goTo local function, which will basically push a new entry into your browser history (this update the URL and refresh the render). Now both "/" and "/userInfo" match current URL (a match occurs when the current URL starts with the one given by the path).

If you want to pass hidden props, and this props are accessible by the parent component, then use render prop instead of component. This allows you to pass a functional component to Route, to which you can freely add and/or remove props.

So in this example, I just added the foo prop to Hook, but you can do pretty much whatever you want here.

EDIT

If you don't want your HomePage and your Hook to render simultaneously, then either set HomePage path to something different (like "/home") or add the exact prop like so :

App.ts

function App() {
  // Wrap your HomePage inside a router to access history context
  return (
    <Router>
      <Route path="/" exact component={HomePage}/>
    </Router>
  );
}

This will force an exact match, aka it won't render if the URL is not exactly "/"

KawaLo
  • 1,783
  • 3
  • 16
  • 34
  • Thank you for the clear explanation. I got stuck here with error "Cannot read property 'push' of undefined ". My versions : "react-router-dom": "^5.1.2", "react-router": "^5.1.2" . Also followed https://stackoverflow.com/questions/39184049/react-router-cannot-read-property-push-of-undefined But didnt help me to solve the issue – aishu8333 May 09 '20 at 19:08
  • UserInfo } /> this is just changing the url but not rendering the Hook Component – aishu8333 May 09 '20 at 21:00
  • @aishu8333 My bad, I had done things slighly differently in my code and didn't notice the error ! I just made an edit which should work, in any case I made two little additions to the `HomePage.tsx` (on import and export) – KawaLo May 09 '20 at 21:29
  • @aishu8333 For your second comment, please refer to https://stackoverflow.com/a/51713320/9021186, Link components should be rendered inside the router to work – KawaLo May 09 '20 at 21:38
  • Thanks a lot. Finally it worked. But the home component & Hook component are rendering simultaneously . So to avoid that , adding exact in App.tsx & rendering Hook in Home.tsx didnt work for me. So i did a slight modification. That I've mentioned in Answer Section above. Once again, Thank you. – aishu8333 May 10 '20 at 08:14
0

App.tsx:

 <Router>
  <Route exact path="/"  component={HomePage} />

   <Route path="/userinfo"  render={props => <Hook {...this.props}  region={this.state.region} loginUser={this.state.user.username}/>} />

 </Router>

HomePage.tsx

<Link   to="/userinfo">
      <Card className={classes.root} >
            <CardActionArea>

              <CardContent>
              UserInfo
              </CardContent>
            </CardActionArea>
      </Card>
      </Link> 
aishu8333
  • 41
  • 1
  • 10