Search code examples
reactjsreact-props

React - Cannot read property 'title' of undefined


I'm getting this error: Cannot read property 'title' of undefined when trying to load of my page.

Here's my code :

import resumeDataFr from './data/resumeDataFr'

class App extends Component {
  state = {
    resumeDataFr: {}
  }

  componentDidMount () {
    this.handleLoadResumeData()
  }

  handleLoadResumeData () {
    this.setState({ resumeDataFr: resumeDataFr })
  }

  render () {
    return (
      <div>
        <Header data={this.state.resumeDataFr.header} />
        <Treatment data={this.state.resumeDataFr.treatment} />
      </div>
    )
  }
}

App.propTypes = {
  data: PropTypes.object.isRequired
}

export default App

And one of components I want to use:

import React from 'react'

const Treatment = ({ data }) => {
  return (
    <div id='treatments' className='text-center'>
      <div className='container'>
        <div className='col-md-10 col-md-offset-1 section-title'>
          <h2>{data.title}</h2>
        </div>
      </div>
    </div>
  )
}

export default Treatment

Here's my data file :

const resumeDataFr = {
  navigation: {
    title: 'T',
    items: {
      item0: 'A',
      ...
    }
  },
  header: {
    title: 'AM',
    paragraph: 'I',
    button: 'B'
  },
  team: {
    ...
  },
  treatment: {
    title: 'Title treatments',
    treatments: {
      treatment0: {
        icon: 'Icon',
        title: 'Title',
        text: 'Text'
      },
      ...
    }
  },
  contact: {
    ...
  }
}

export default resumeDataFr

It's working when there is only Header component called, but when I add Treatment component it does not work anymore. I check the state from App and looks like fulfilled :

State from App component

And this is my depencencies :

"dependencies": {
    "@testing-library/jest-dom": "^5.11.5",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "prop-types": "^15.7.2",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.0",
    "web-vitals": "^0.2.4"
  }

I cannot figure what I am doing wrong, thanks a lot for your help.


Solution

  • Here you are accessing resumeDataFr.treatment

    <Treatment data={this.state.resumeDataFr.treatment} />
    

    On the first render it is undefined, when handleLoadResumeData runs it will have the data.

    so when you access it from

    const Treatment = ({ data }) => {
    

    when you say data.title you call title of an undefined object

    You can solve like below

    <h2>{data?.title}</h2>
    

    Or you can do something like below

    class App extends Component {
      state = {
        resumeDataFr: null
      }
    
      componentDidMount () {
        this.handleLoadResumeData()
      }
    
      handleLoadResumeData () {
        this.setState({ resumeDataFr: resumeDataFr })
      }
    
      render () {
        if(this.state.resumeDataFr)
           return null; // or show some loading
        return (
          <div>
            <Header data={this.state.resumeDataFr.header} />
            <Treatment data={this.state.resumeDataFr.treatment} />
          </div>
        )
      }
    }