如何修复 TypeError: Cannot read property 'map' of undefined 错误

4

我的map函数出错了。

我正在跟随一个reactjs教程学习,当我将一个组件状态的值传递到另一个组件时,我不断遇到问题。 我使用axios.get()连接后端。

export default class Viewcustomer extends React.Component{

  constructor(props) {
    super(props)

    this.state = {
      Id:"",
      name:"",
      fax:"",    
      NIC: "",
      type: "",
      email: "",
      website: "",
      address: "",
      phoneNo: "",
      DOB: "",
      note: "",
      customer:[]  
    }    
  }

  onChange = (e) => {
    this.setState({[e.target.name]: e.target.value})
  }

  componentDidMount() {
    axios.get(`http://localhost:5001/customer/view`)
      .then(res => {
         const customers = res.data;
         this.setState({ customers });
      })
  }

  render(){
    return(
      <table width="100%">
        <tr>
          <th>Id</th>
          <th>name</th>
          <th>fax</th>
          <th>NIC</th>
          <th>type</th>
          <th>email</th>
          <th>address</th>
          <th>phoneNo</th>
          <th>DOB</th>
          <th>note</th>

        </tr>
        //Error raised by this line of code
        { this.state.customers.map(customer =>
          <tr>
            <td>{customer.Id}</td>
            <td>{customer.name}</td>
            <td>{customer.fax}</td>
            <td>{customer.NIC}</td>
            <td>{customer.type}</td>
            <td>{customer.email}</td>
            <td>{customer.address}</td>
            <td>{customer.phoneNo}</td>
            <td>{customer.DOB}</td>
            <td>{customer.note}</td>
          </tr>)}
      </table>
    )
  }
}

错误信息截图

编辑

错误与引号标记的行有关,由map()函数引发的问题,但根本问题是this.state.customersundefined


2
在你声明 this.state 的时候,你打错了字,customer 应该是 customers - Ian Kemp
这个回答解决了你的问题吗?Cannot read property 'map' of undefined - SuleymanSah
4个回答

1
this.state.customers.map(...

问题是 this.state.customers 在组件挂载时设置,只有在axios的异步调用返回后才会设置。这意味着在组件首次渲染时,this.state.customers 将尚未被设置。

可能的解决方案

要么在使用前检查 this.state.customers 是否存在,或者将其初始化为空数组。我注意到您正在将一个customer(单数)初始化为空数组,这是一个错误吗?

constructor(props) {
    super(props)

    this.state = {
        Id:"",
        name:"",
        fax:"",    
        NIC: "",
        type: "",
        email: "",
        website: "",
        address: "",
        phoneNo: "",
        DOB: "",
        note: "",
        customers:[] // initialize customers, this.state.customers is now defined
    }
}

1
你需要知道的第一件事是,componentDidMount在渲染方法之后运行。因此,在第一次渲染中,你的customer参数仍然是[],即使你在componentDidMount中写了一个简单的console.log(),它也会在渲染方法之后运行。
你可以通过运行下面的代码来理解发生了什么:
    class Test extends React.Component {
        constructor(props){
           console.log('constructor')
        }
        render(){
          console.log('render')
        }
        componentDidMount(){
          console.log('componentDidMount')
        }
    }

结果将会是这样的:

构造函数

渲染

componentDidMount

但是为了解决你的问题,你应该在等待axios响应时显示一个旋转图标或类似的东西。你的组件可能是这样的:

export default class Viewcustomer extends React.Component{

  constructor(props) {
    super(props)

    this.state = {
      Id:"",
      name:"",
      fax:"",    
      NIC: "",
      type: "",
      email: "",
      website: "",
      address: "",
      phoneNo: "",
      DOB: "",
      note: "",
      customer:[]  
    }    
  }

  onChange = (e) => {
    this.setState({[e.target.name]: e.target.value})
  }

  componentDidMount() {
    axios.get(`http://localhost:5001/customer/view`)
      .then(res => {
         const customers = res.data;
         this.setState({ customers });
      })
  }

  render(){
    if(this.state.customers.length===0){
    return(
     <div>Loading...</div>
    )
    }
    else{
    return(
      <table width="100%">
        <tr>
          <th>Id</th>
          <th>name</th>
          <th>fax</th>
          <th>NIC</th>
          <th>type</th>
          <th>email</th>
          <th>address</th>
          <th>phoneNo</th>
          <th>DOB</th>
          <th>note</th>

        </tr>
        //Error raised by this line of code
        { this.state.customers.map(customer =>
          <tr>
            <td>{customer.Id}</td>
            <td>{customer.name}</td>
            <td>{customer.fax}</td>
            <td>{customer.NIC}</td>
            <td>{customer.type}</td>
            <td>{customer.email}</td>
            <td>{customer.address}</td>
            <td>{customer.phoneNo}</td>
            <td>{customer.DOB}</td>
            <td>{customer.note}</td>
          </tr>)}
      </table>
    )
    }
  }
}

请投票支持我,如果这篇文章对您有帮助 :)

0

正如其他答案中所指出的那样,this.state.customersundefined,导致了错误。这是因为在构造函数中最初初始化了单数的customer而不是复数的customers,快速更改即可解决。

我可以推荐一下,既然您正在学习教程,React Hooks是一种非常强大和直观的使用“无状态”(它们仍然保持状态)功能组件而不是类组件的方式。它们极大地简化了组件的编码,并使处理状态变得更加容易。


0

你的问题在于你使用了 this.state.costumers,而你定义的 state 是 customer

export default class Viewcustomer extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            Id: "",
            name: "",
            fax: "",
            NIC: "",
            type: "",
            email: "",
            website: "",
            address: "",
            phoneNo: "",
            DOB: "",
            note: "",
            customers: []


        }

    }

    onChange = (e) => {
        this.setState(
            { [e.target.name]: e.target.value }
        )
    }
    componentDidMount() {
        axios.get(`http://localhost:5001/customer/view`)
            .then(res => {
                const customers = res.data;
                this.setState({ customers });
            })
    }


    render() {
        const { costumers } = this.state:
        return (
            <table width="100%">
                <tr>
                    <th>Id</th>
                    <th>name</th>
                    <th>fax</th>
                    <th>NIC</th>
                    <th>type</th>
                    <th>email</th>
                    <th>address</th>
                    <th>phoneNo</th>
                    <th>DOB</th>
                    <th>note</th>

                </tr>
                {customers.map(customer =>
                    <tr>
                        <td>{customer.Id}</td>
                        <td>{customer.name}</td>
                        <td>{customer.fax}</td>
                        <td>{customer.NIC}</td>
                        <td>{customer.type}</td>
                        <td>{customer.email}</td>
                        <td>{customer.address}</td>
                        <td>{customer.phoneNo}</td>
                        <td>{customer.DOB}</td>

                        <td>{customer.note}</td>
                    </tr>)}
            </table>


        )
    }
}

这就是整个问题所在,因为当您将costumers状态初始化为空数组时,map方法将停止失败。希望这可以帮助您。最好的问候。


1
谢谢,这有助于修复。感谢您的解释。 - Lakma Chehani
如果我的回答对您有帮助,您可以投票支持一下吗?谢谢。祝好!@ChehaniLakshika - Alberto Perez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接