是否可以在组件中使用React Router的值路径?

时间:2017-10-22 12:07:06

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

我使用React.js和React-router-dom来创建一个简单的应用程序。

  • 使用ReactRouter有三个链接。
  • 三个链接连接到相同的组件包括API。
  • 应更改API URL取决于ReactRouter路径的值。

例如,如果你选择' Vincent'在链接中,API URL应为

https://www.rijksmuseum.nl/api/en/collection?key=apiKey&format=json&q=Vincent

如果您选择' Rambrandt'在链接中,API URL应为

https://www.rijksmuseum.nl/api/en/collection?key=apiKey&format=json&q=Rambrandt

我努力传递路径的值来更改组件中的API URL。我怎样才能做到这一点?

路由器

const Main = () => (
<main>
 <Switch>
  <Route exact path='/' component={Home} />
  <Route path='/Vincent' component={Collection} />
  <Route path='/Vermer' component={Collection} />
   <Route path='/Rembrandt' component={Collection} />
 </Switch>
</main>)

const Header = () => (
<header>
<nav>
<ul>
    <li className="Vincent"><Link to='/Vincent'>Vincent</Link></li>
    <li className="Vermer"><Link to='/Vermer'>Vermer</Link></li>
    <li className="Rembrandt"><Link to='/Rembrandt'>Rembranbt</Link></li>
  </ul>
</nav>
</header>
 )

收藏组件

let name;

if(route path == "Rambrandt") {
name = "Rambrandt";
} else if (route path == "Vincent") {
name ="Vincent"
}

const url = `https://www.rijksmuseum.nl/api/en/collection?
key=apikey&format=json&q=${name}`;

export default class Collection extends Component {

constructor(props){
   super(props);
   this.state = {
       data : []
   }
   this.handleClick = this.handleClick.bind(this);
   }
componentDidMount(){
    console.log(url)
    fetch(url)
     .then(response => response.json())
     .then(json => {
        this.setState({
            data: json.artObjects
        });
     });
}
render(){
    let titles;
    if (this.state.data.length) {
        titles = this.state.data.map(

            (obj) => (
                <div>
                <a href={obj.links.web}><h2>{obj.title}</h2></a>
                 </div>
                )); 

        return <div>
         {titles}
         </div>
    }
    return(
        <div>{titles}</div>
        );
}
}

1 个答案:

答案 0 :(得分:2)

如果您将艺术家的名字视为参数,那么您不应该像对待这样做那样对路线进行硬编码,而是依赖路线参数:

const Main = () => {
  return (
    <main>
     <Switch>
       <Route exact path='/' component={Home} />
       <Route path='/:artist' component={Collection} />
     </Switch>
   </main>
  );
}

const Header = () => {
  return (
    <header>
      <nav>
        <ul>
          <li className="Vincent"><Link to='/Vincent'>Vincent</Link></li>
          <li className="Vermer"><Link to='/Vermer'>Vermer</Link></li>
          <li className="Rembrandt"><Link to='/Rembrandt'>Rembranbt</Link</li>
        </ul>
      </nav>
    </header>
  );
}

然后在您的Collection组件中

const baseUrl = "https://www.rijksmuseum.nl/api/en/collection?key=apikey&format=json&q=";

export default class Collection extends Component {
  constructor(props) {
    super(props);
      this.state = {
        data : []
    }
    this.handleClick = this.handleClick.bind(this);
  }
  getCollection(artist) {
    const url = `${baseUrl}${artist}`;
    console.log(url);
    fetch(url)
      .then(response => response.json())
      .then(json => {
        this.setState({
          data: json.artObjects
        });
      });
  }
  componentDidMount() {
    // this.props.match.params.artist will contain
    // the value of the :artist param as defined in your Route
    this.getCollection(this.props.match.params.artist);
  }

  // since your artist is passed as a prop (by the routing), it is important
  // to make sure to fetch artist data again when the URL changes
  componentWillReceiveProps(nextProps) {
    if (nextProps.match.params.artist !== this.props.match.params.artist) {
      this.getCollection(nextProps.match.params.artist);
    }
  }
  render(){
    ...rendering the collection...
  }
}

最后,请注意参数匹配非常自由。匹配/:artist之类的路线几乎与所有内容相匹配,因此为了理智,您应该将组件移至/collection/:artist(并相应地调整您的链接,即{ {1}}。

出于同样的原因,您可能希望在Collection组件中(例如,在数组中)拥有可用艺术家的列表,并且只有在路线中的艺术家参数与您的任何艺术家匹配时才渲染该组件。数组,否则重定向到根页。