简体   繁体   中英

TypeError: Cannot read property '0' of undefined. React Redux App

I am getting this error in my code. I am able to read the correct state from my Redux Chrome extension though. I don't know where is the error coming from. I think it comes from.

TopTracks.propTypes = {
  getHashParams: PropTypes.func.isRequired,
  getMyTopTracks: PropTypes.func.isRequired,      
  myTopTracks: PropTypes.arrayOf(PropTypes.object),
}

const mapStateToProps = state => ({
  myTopTracks: state.music.myTopTracks
})

Have I managed the mapStateToProps and PropTypes correctly? Because there is no sign of its object content: myTopTrackName and myTopTrackImage

Here is the full code:

class TopTracks extends Component{
  componentWillMount(){
    this.props.getMyTopTracks(getHashParams())
  }
  render(){
    let link = `${ window.location.href }`
    link = `/prueba/${link.substring(link.indexOf('#'))}`
    return(
      <div className="TopTracks">
          Now Playing: { this.props.myTopTracks[0].myTopTrackName }
          <img src={ this.props.myTopTracks[0].myTopTrackImage } alt="Top Track Album" style={{ width: 300 }} />
          <Button href={ link }>Continue</Button>
      </div>
    )
  }
}

TopTracks.propTypes = {
  getHashParams: PropTypes.func.isRequired,
  getMyTopTracks: PropTypes.func.isRequired,      
  myTopTracks: PropTypes.arrayOf(PropTypes.object),
}

const mapStateToProps = state => ({
  myTopTracks: state.music.myTopTracks
})

export default connect(mapStateToProps, { getHashParams, getMyTopTracks } )( TopTracks )

If the error is coming from the code shown, it means that this.props.myTopTracks is undefined , which in turns means that state.music.myTopTracks is undefined .

The real problem is in your app's initial state. Look in your redux reducers and make sure that your initial state sets myTopTracks to an empty array, [] . This is a common, safe way to initialize the app state before you fetch the real list from the server.

You'll also still need to change your view code to account for an empty list, because myTopTracks[0] will be undefined if the list is empty. One way to solve that is by creating a safe default first object in the list, which would be replaced by incoming data from the fetch, such as:

{
  myTopTracks: [{
    myTopTrackName: 'Loading...',
    myTopTrackImage: ''
  }]
}

Another method is to check the length of the list, and if it's empty, render something else, like a spinner. It really depends on the design requirements for your app at that point. But those are two options.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM