开发者问题收集

如何修复错误 TypeError: 无法读取未定义的属性“map”

2020-01-15
302

错误出现在我的 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

3个回答
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
    }
}
Ismael Padilla
2020-01-15

您应该知道的第一件事是 componentDidMount 在 render 方法之后运行。因此,在第一次渲染中,您的 customer 参数仍然是 [] ,即使您在 componentDidMount 中编写了一个简单的 console.log() ,它也会在 render 方法之后运行。

您可以通过运行以下代码来了解发生了什么:

    class Test extends React.Component {
        constructor(props){
           console.log('constructor')
        }
        render(){
          console.log('render')
        }
        componentDidMount(){
          console.log('componentDidMount')
        }
    }

结果将如下所示:

constructor

render

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

如果有帮助,请投票给我:)

Meisam Nazari
2020-01-15

您的问题是,在使用中您使用的是 this.state.costumers ,而您的定义状态是 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 方法将停止失败。希望这能有所帮助。此致。

Alberto Perez
2020-01-15