React-router同样的url没有重新安装,试图弄清楚componentWillReceiveProps

时间:2017-04-14 04:01:31

标签: reactjs routing react-router

我正在使用我的第一个React应用程序并遇到一些路由问题,只是寻找一些指导。我发现这对许多人来说是一个特定的问题,但是在跟随其他答案时遇到了麻烦。

从我所知的其他答案中,人们正在为特定路线分配密钥,并检查componentWillReceiveProps(nextProps)中的密钥。我有点理解,虽然不知道从重新渲染/安装方面去哪里。

我只是尝试在网址/catalog/genre/:genre/catalog/genres之间进行转换。对不起凌乱的代码提前抱歉,只是想让它运转起来!

App.js包含主要路由,更具体地说是针对此问题:

<Route path="/catalog/genres" component={Genres}/>

Genres.js:

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

class Genre extends Component {
  constructor(props) {
    super(props);
    console.log(props);
    this.state = {
      data: [],
    };
  }

  componentDidMount() {
    fetch('http://localhost:3000/catalog/genre/58eacca74a0d2c105c68fbe9')
    .then(response => response.json())
    .then(json => {
      this.setState({
        data: json.genre_books
      });
    });
  }

  componentWillReceiveProps(newProps) {
    console.log(newProps.params);
  }

  render() {
    return (
      <div>
        <div>
          Genre:
          <label>
            <ul>
              {
                this.state.data.map((piece) =>
                  <Link key={piece._id} to={`${piece.url}`}>
                    <li>
                      {piece.title}
                    </li>
                  </Link>
                )
              }
            </ul>
          </label>
        </div>
      </div>
    );
  }
}

class AllGenres extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
    }
  }

  componentDidMount() {
    fetch('http://localhost:3000/catalog/genres')
    .then(response => response.json())
    .then(json => {
      this.setState({
        data: json.genres_list
      });
    });
  }

  render() {
    return (
      <div>
        All Genres:
        <label>
          <ul>
            {
              this.state.data.map((piece) =>
                <Link key={piece._id} to={`${piece.url}`}>
                  <li>
                    {piece.name}
                  </li>
                </Link>
              )
            }
          </ul>
        </label>
      </div>
    );
  }
}

class Genres extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
    }
  }

  componentDidMount() {
    fetch('http://localhost:3000/catalog/genres')
    .then(response => response.json())
    .then(json => {
      this.setState({
        data: json.genres_list
      });
    });
  }

  render() {
    return (
      <div>
        <Router>
          <div>
            <Route path="/catalog/genre/:genre" render={() => (
              <Genre testKey='1'/>
            )}/>
            <Route exact path="/catalog/genres" render={() => (
              <AllGenres testKey='2' />
            )}/>
          </div>
        </Router>
      </div>
    );
  }
}

export default Genres;

1 个答案:

答案 0 :(得分:0)

对于那些回到这个问题的人来说,虽然componentWillReceiveProps(nextProps)对其他情况很有用,但我通过以下方式找到了解决这个问题的方法。 guide

现在我可以根据网址参数genreId进行渲染。

以下是代码:

App.js导航组件

class Nav extends Component {
  constructor(props){
    super(props);

    this.state = {
      tap: 0,
    }

  }

  render() {
    return (
      <div >
        <Router>
            <div style={styles.mainContent}>
              <Drawer open="TRUE" title="My App">
                <MenuItem primaryText="Home" containerElement={<Link to="/catalog/home" />} />
                <MenuItem primaryText="All books" containerElement={<Link to="/catalog/books" />} />
                <MenuItem primaryText="All authors" containerElement={<Link to="/catalog/authors" />} />
                <MenuItem primaryText="All genres" containerElement={<Link to="/catalog/genres" />} />
                <MenuItem primaryText="All book-instances" containerElement={<Link to="/catalog/bookinstances" />} />
                <hr></hr>
                <MenuItem primaryText="Create new author" containerElement={<Link to="/catalog/author/create" />} />
                <MenuItem primaryText="Create new genre" containerElement={<Link to="/catalog/genre/create" />} />
                <MenuItem primaryText="Create new book" containerElement={<Link to="/catalog/book/create" />} />
                <MenuItem primaryText="Create new book instance (copy)" containerElement={<Link to="/catalog/bookinstance/create" />} />
                <hr></hr>
                <MenuItem primaryText="About" containerElement={<Link to="/about" />} />
                <MenuItem primaryText="Topics" containerElement={<Link to="/topics" />} />
              </Drawer>

              <Route path="/catalog/home" component={Home}/>
              <Route path="/catalog/books" component={Books}/>
              <Route path="/catalog/authors" component={Authors}/>
              <Route path="/catalog/genres" component={Genres}/>
              <Route path="/catalog/bookInstances" component={BookInstances}/>
              <Route path="/about" component={About}/>
              <Route path="/topics" component={Topics}/>
            </div>
        </Router>
      </div>
    );
  }
}

Genres.js

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

class GenreList extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: [],
    }
  }

  componentDidMount() {
    fetch('http://localhost:3000/catalog/genres')
    .then(response => response.json())
    .then(json => {
      this.setState({
        data: json.genres_list
      });
    });

  }

  render() {
    return (
      <div>
        All Genres:
        <label>
          <ul>
            {
              this.state.data.map((piece) =>
                <Link key={piece._id} to={`${piece.url}`}>
                  <li>
                    {piece.name}
                  </li>
                </Link>
              )
            }
          </ul>
        </label>

      </div>
    );
  }
}

const Genre = ({match}) => (
  <div>
    <h3>{match.params.genreId}</h3>
  </div>
)

const Genres = ({ match }) => {
  return (
    <div>
        <Route path={`${match.url}/:genreId`} component={Genre}/>

        <Route exact path={match.url} render={() => (
          <div>
            <GenreList url={match.url}/>
          </div>
        )}/>
    </div>
  );
}

export default Genres;

genre.js

var mongoose = require('mongoose');

var Schema = mongoose.Schema;

var GenreSchema = Schema({
 name: { type: String, required: true, min: 3, max: 100 },
}, {
   toObject: {
     virtuals: true
   },
   toJSON: {
     virtuals: true
   } //reference to the associated book
});

// Virtual for bookinstance's URL
GenreSchema
.virtual('url')
.get(function () {
  return '/catalog/genres/' + this._id;
});

//Export model
module.exports = mongoose.model('Genre', GenreSchema);