当组件渲染时,我得到“无法读取属性”参数”

时间:2018-08-30 09:01:33

标签: reactjs

我很头疼..我不知道我在这里做错了什么。当我的Podcast.js组件呈现时,出现“无法读取未定义的属性'params'...

有人可以指引我正确的方向吗?

这是Podcast的父组件:

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import NavLinks from './components/NavLinks';
import Home from './components/Home';
import Podcast from './components/Podcast';
import './App.css';

class App extends Component {
  render() {
    return (
      <Router>
        <div className="App">
        <NavLinks />
          <Route exact path='/' component={Home} />
          <Route path='/podcast/:podID' component={Podcast} />
        </div>
      </Router>
    );
  }
}

export default App;

这是我的主要组件(播客):

import React, { Component } from 'react';
import PodcastList from './PodcastList';

class Podcast extends Component {

  constructor(props) {
    super(props); 
    this.state = {
      podcast: []
    };
  }

  // Fetches podID from props.match
  fetchPodcast () {
    const podID = this.props.match.params.podID

    fetch(`https://itunes.apple.com/search?term=podcast&country=${podID}&media=podcast&entity=podcast&limit=20`)
      .then(response => response.json())
      .then(data => this.setState({ podcast: data.results }));
  }

  componentDidMount () {
    this.fetchPodcast()
  }

  // Check if new props is not the same as prevProps
  componentDidUpdate (prevProps) {
    // respond to parameter change
    let oldId = prevProps.match.params.podID
    let newId = this.props.match.params.podID
    if (newId !== oldId)
      this.fetchPodcast()
  }

  render() {
    return (
      <div>
        <PodcastList />
      </div>
    )
  }
}

export default Podcast;

这是列表所有播客的组成部分:

import React, { Component } from 'react';

class PodcastList extends Component {
    render() {
        return (
            <div>
                <h2>Country ({this.props.match.params.podID}) </h2>
                <ul>
                {this.state.podcast.map(podcast =>
                    <li key={podcast.collectionId}>
                    <a
                    href={podcast.collectionId}>
                    {podcast.collectionName}</a>
                    </li>
                )}
                </ul>
            </div>
        )
    }
}

export default PodcastList;

2 个答案:

答案 0 :(得分:0)

错误来自哪里?播客还是PodcastList?也许是因为您没有将道具传递给PodcastList吗?

尝试:

<PodcastList {...this.props} {...this.state} />

此外,在子组件(PodcastList)中使用this.props而不是this.state

答案 1 :(得分:-1)

我猜您正在使用react-router。要使用React Router的match道具,您必须通过模块的withRouter装饰者对其进行装饰

import React, { Component } from 'react';
import { withRouter } from 'react-router';

class PodcastList extends Component {
    render() {
        return (
            <div>
                <h2>Country ({this.props.match.params.podID}) </h2>
                <ul>
                {this.state.podcast.map(podcast =>
                    <li key={podcast.collectionId}>
                    <a
                    href={podcast.collectionId}>
                    {podcast.collectionName}</a>
                    </li>
                )}
                </ul>
            </div>
        )
    }
}

export default withRouter(PodcastList);

更新:

podcast中如何处理PodcastList道具的方法之一。该解决方案符合所有React建议和最佳实践。

import React, { PureComponent } from 'react';
import PodcastItem from './PodcastItem';

class Podcast extends PureComponent { // PureComponent is preferred here instead of Component

  constructor(props) {
    super(props); 

    this.state = {
      podcast: []
    };
  }

  // Fetches podID from props.match
  fetchPodcast () {
    const podID = this.props.match.params.podID

    fetch(`https://itunes.apple.com/search?term=podcast&country=${podID}&media=podcast&entity=podcast&limit=20`)
      .then(response => response.json())
      .then(data => this.setState({ podcast: data.results }));
  }

  componentDidMount () {
    this.fetchPodcast()
  }

  // Check if new props is not the same as prevProps
  componentDidUpdate (prevProps) {
    // respond to parameter change
    let oldId = prevProps.match.params.podID
    let newId = this.props.match.params.podID
    if (newId !== oldId)
      this.fetchPodcast()
  }

  render() {
    return (
      <div>
        <h2>Country ({this.props.match.params.podID}) </h2>
        <ul>
          {this.state.podcast.map(podcast => (
            <PodcastItem key={podcast.collectionId}> podcast={podcast} />
          ))}
        </ul>
      </div>
    )
  }
}

export default Podcast;
import React from 'react';

// Here Stateless function is enough
const PodcastItem = ({ podcast }) => (
  <li key={podcast.collectionId}>
    <a href={podcast.collectionId}>{podcast.collectionName}</a>
  </li>
);

export default PodcastItem;