Search code examples
reactjsecmascript-6react-routerthemoviedb-api

React Router sharing data between components


I have a dynamic route set up in my react application, when a user clicks the image it navigates to a new route with url /details/:id:

<div className='App'>
      <Switch>
        <Route path='/' exact component={Home} />
        <Route exact path='/details/:id' component={ItemDetails} />
      </Switch>
 </div>

It comes from my functional component:

const headerImages = (props) => {
  const imageResults = props.trending.slice(0, 5).map(r => ( // Grab firt 5 array objects
    <Link key={r.id} to={`/details/${r.id}`}>
      <div key={r.id}>
        <img key={r.id} src={`https://image.tmdb.org/t/p/w1280${r.backdrop_path}`} alt={r.title} className='header-image' />
        <h1 className='now-playing'>Latest</h1>
        <h1 className='header-title'>{r.title}</h1>
        <h4 className='header-details'>{r.overview}</h4>
      </div>
    </Link>
  ))
  return <div className='header-images'>
    <Carousel infinite autoPlay={4500}>{imageResults}</Carousel>
  </div>
}

export default headerImages

ItemDetails is a class based component that has an API call, How do I get r.id value from my functional component into my Api call?

class ItemDetails extends Component {
  constructor (props) {
    super(props)
    this.state = { selectedItem: null }
  }

  fetchItemDetails = () => {
    axios.get('https://api.themoviedb.org/3/movie/${this.props.r.id}?api_key=40d60badd3d50dea05d2a0e053cc96c3&language=en-US')
    .then((res) => {
      console.log(res.data.results)
    })
  }

  componentDidMount(){
    this.fetchItemDetails()
  }
  
  render () {
    return <h1>test</h1>
  }
}

Currently the API call returns undefined, but as you can see, I'm trying to pass a dynamic id into the call.

Updated solution:

class ItemDetails extends Component {
  constructor (props) {
    super(props)
    this.fetchItemDetails = this.fetchItemDetails.bind(this)
  }
  

  fetchItemDetails = (itemId = this.props.match.params.id) => {
    axios.get('https://api.themoviedb.org/3/movie/${itemId}?api_key=40d60badd3d50dea05d2a0e053cc96c3&language=en-US')
    .then((res) => {
      console.log(res.data.results)
    })
  }

  componentDidMount(){
    this.fetchItemDetails()
  }
  
  render () {
    return <h1>test</h1>
  }
}

export default ItemDetails

Solution

  • This is because you haven't bound this to the function trying to access the props.

    Add in the constructor:

    this.fetchItemDetails = this.fetchItemDetails.bind(this);
    

    and the url should use template literal ` instead of quote '

    `https://api.themoviedb.org/3/movie/${itemId}?api_key=40d60badd3d50dea05d2a0e053cc96c3&language=en-US`