【问题标题】:React - Cannot read property 'title' of undefinedReact - 无法读取未定义的属性“标题”
【发布时间】:2020-10-24 13:38:09
【问题描述】:

我收到此错误:尝试加载我的页面时无法读取未定义的属性“标题”。

这是我的代码:

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

还有我想使用的组件之一:

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

这是我的数据文件:

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

仅调用 Header 组件时它可以工作,但是当我添加 Treatment 组件时它不再工作了。我从 App 检查状态,看起来很满足:

这是我的依赖:

"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"
  }

我不知道我做错了什么,非常感谢您的帮助。

【问题讨论】:

    标签: reactjs react-props


    【解决方案1】:

    你在这里访问 resumeDataFr.treatment

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

    在第一次渲染时它是未定义的,当 handleLoadResumeData 运行时它就会有数据。

    所以当你访问它时

    const Treatment = ({ data }) => {
    

    当你说 data.title 你调用一个未定义对象的标题

    你可以像下面这样解决

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

    或者您可以执行以下操作

    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>
        )
      }
    }
    

    【讨论】:

    • 所以实际上这并不是一个真正的“问题”,这是正确的反应行为吗?我还在学习它,所以谢谢你的帮助,它解决了我的问题。
    • 这是行为,基本上它会渲染一次,componentdidmount 会触发,所以你的默认状态值会被渲染,所以你应该处理它,这就是想法
    【解决方案2】:

    当您执行({ data }) 时,您正在解构该函数的输入参数(即从该对象获取数据属性。我认为您可能想要这样做:

    const Treatment = (data) => {
    

    并保持其他所有内容相同(例如引用 data.title)或可能使用解构来获取您想要使用的属性,如标题:

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

    【讨论】:

    • 在加载数据之前,您可能还需要有一个默认状态或捕获空状态,但我认为我上面所说的是您的问题之一。
    猜你喜欢
    • 2020-12-05
    • 2021-09-04
    • 2019-12-05
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多