How to navigate to a new page react router v4

2019-04-15 20:13发布

问题:

I'm building a crypto currency market app as an to practice reactjs. When app starts list of currencies with some properties will be shown as a list. I need to navigate to a different page (new page - Currency component) without loading the component on the bottom of current page. At the moment I was able to render it in the bottom of the page. But that's not what I need.

Is there any other way than which is mentioned in Route to different page[react-router v4] ? Because I need to pass the clicked object (currency) to the new component (Currency)

Here's my CryptoList component currency_main.js

import React, { Component } from 'react';
import {
  Table,
  TableBody,
  TableHeader,
  TableHeaderColumn,
  TableRow,
  TableRowColumn,
} from 'material-ui/Table';
import Currency from './currency';
import {
  BrowserRouter as Router,
  Link,
  Route
} from 'react-router-dom'

class CryptoList extends Component {
  constructor(props){
    super(props);
    this.state = {
      currencyList : [],
      showCheckboxes : false,
      selected : [],
      adjustForCheckbox : false
    }
  };

  componentWillMount(){
    fetch('/getcurrencylist',
    {
        headers: {
          'Content-Type': 'application/json',
          'Accept':'application/json'
        },
        method: "get",
        dataType: 'json',
    })
    .then((res) => res.json())
    .then((data) => {
      var currencyList = [];
      for(var i=0; i< data.length; i++){
        var currency = data[i];
        currencyList.push(currency);
      }
      console.log(currencyList);
      this.setState({currencyList})
      console.log(this.state.currencyList);
    })
    .catch(err => console.log(err))
  }

  render(){
    return (
      <Router>
        <div>
          <Table>
           <TableHeader
             displaySelectAll={this.state.showCheckboxes}
             adjustForCheckbox={this.state.showCheckboxes}>
             <TableRow>
               <TableHeaderColumn>Rank</TableHeaderColumn>
               <TableHeaderColumn>Coin</TableHeaderColumn>
               <TableHeaderColumn>Price</TableHeaderColumn>
               <TableHeaderColumn>Change</TableHeaderColumn>
             </TableRow>
           </TableHeader>
           <TableBody displayRowCheckbox={this.state.showCheckboxes}>
             {this.state.currencyList.map( currency => (
               <TableRow key={currency.rank}>
                 <TableRowColumn>{currency.rank}</TableRowColumn>
                 <TableRowColumn><Link to='/currency'>{currency.name}</Link></TableRowColumn>
                 <TableRowColumn>{currency.price_btc}</TableRowColumn>
                 <TableRowColumn>{currency.percent_change_1h}</TableRowColumn>
               </TableRow>
             ))}
           </TableBody>
         </Table>
         <div>
           <Route path='/currency' component={Currency} />
         </div>
        </div>
      </Router>
    );
  }

}

export default CryptoList;

And here's my Currency component currency.js

import React, { Component } from 'react';

class Currency extends Component {

  componentWillMount(){
    console.log(this.props.params);
  }

  render(){
    return (
      <div>
        <h3>
          This is Currency Page !
        </h3>
      </div>
    );
  }
}

export default Currency;

And here's the currency component which I need to render into a new page when I click currency name in the currency_main component (Which is in second <TableRowColumn>).

I'm bit new to react and tried react-router in a tutorial only and it was rendering a page as a part of currenct page only.

So how can I go to a new page using react-router v4 ?

P.S : I've uploaded the image. As an example if click on Ethereum I need to render the Currency component as a new page.

And this should be resulted as the output when I click on Ethereum (as an example) instead of rendering This is Currency Page ! on the same component CryptoList.

回答1:

You already had the imports in this.

import {
  BrowserRouter as Router,
  Link,
  Route
} from 'react-router-dom'

However, I would remove all of the routings in your CyptoList page and just make that CyptoList a component.

Now, you want to use those Links in your code to navigate between pages you need to make a place that you want to display the links in.

const Header = () => (
    <nav>
        <ul>
            <li><Link to='/'>CryptoList</Link></li>
            <li><Link to='/currency'>Currency</Link></li>
        </ul>
    </nav>
)

If in your CyptoList page you can just put the header in there like this <Header />

Now, the next part, the Router, you might want to make a new Router.js file or separate it. Or you could do something like this.

// Routes.js
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import CryptoList from './CryptoList';  // or whatever the location is
import Currency from './Currency'; // or whatever the location is

export default () => (
<BrowserRouter>
    <Switch>
      <Route exact path="/" component={CryptoList}/>
      <Route path="/currency" component={Currency}/>
    </Switch>
</BrowserRouter>
);

Then when you want to include your Routes as you saved it in the Routes.js file you can just do this.

import Routes from './Routes';

and use it by doing this...

<Routes />

You can always refer to this example on medium with a link to a CodeSandbox and CodePen. https://medium.com/@pshrmn/a-simple-react-router-v4-tutorial-7f23ff27adf



回答2:

I encountered the same problem.

Your <Route /> is located in App.js. This is why every time you navigate to currency component you can still see original view in App.js.

Here is the solution:

You just need to move <Route /> to index.js not in App.js. Because in index.js there is nothing. when you navigate to <Currency /> you will go to a completely new page. You will never see views in App.js