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

Is it possible to use the value path of React Router in the component?

我正在使用 React.js 和 React-router-dom 制作一个简单的应用程序。

例如,如果您在链接中选择 '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>
        );
}
}

如果你将艺术家的名字作为参数,那么你不应该像你正在做的那样硬编码路由,而是依赖路由参数:

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 (并相应地调整你的链接,即 /collection/Vermeer.

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