反应图不是函数

时间:2018-10-23 15:52:21

标签: javascript reactjs

伙计们,遇到错误“ contacts.map不是函数”,不确定为什么吗?刚开始反应可能会丢失一些明显的东西。控制台日志一切正常时,我正在获取数据。 下面的代码:

import React, { Component } from 'react'
import axios from 'axios';


class Contacts extends Component {
 constructor(){
 super();

 this.state = {
    contacts: [],
 }

}


componentDidMount(){
    axios.get('url')
    .then(response => {
    this.setState({ contacts: response.data });
    })
    .catch(function (error) {
    console.log(error);
    })
}


render() {
    const { contacts } = this.state 
    return(
    <div>
        {contacts.map(contact => (
            <h1>contact.hello</h1>
        ))}

    </div>
    )
}
}

export default Contacts;

显然它是一个对象,而不是数组...

那我该如何渲染该对象?

它目前具有一个属性,但是稍后将有更多:尝试过JSON.stringify(obj)

{hello: "test"}

4 个答案:

答案 0 :(得分:5)

问题在于您将contacts设置为response.data,这显然不是数组。

componentDidMount在组件安装后触发,并尝试获取字符串'url'。更新状态后,将重绘该组件并给出错误。

答案 1 :(得分:3)

由于联系人是对象,所以我建议您先执行Object.keys,然后在其上进行.map,以便获取对象键及其值。

还有另外一件事情,当您迭代数据数组或类似下面的对象时,别忘了向父jsx元素添加唯一键。

 <div>
    {Object.keys(contacts).map((name, index) => (
        <h1 key={'Key'+index}>{contacts[name]}</h1>
    ))}

</div>

答案 2 :(得分:2)

来自react docs:

  

注意:

     

这些方法被认为是旧方法,您应该在新代码中avoid them

    
          
  • UNSAFE_componentWillMount()
  •     

要包装对象时,只需将其包装在方括号中

class Contacts extends Component {
  constructor() {
    super();

    this.state = {
      contacts: [],
    }
  }

  componentDidMount() {
    axios.get('url')
      .then(({ data }) => {
        this.setState({ contacts: [data] });
      })
      .catch((error) => {
        console.log(error);
      });
  }

  render() {
    const { contacts } = this.state;
    return (
      <div>
        {contacts.map(contact => (
          <h1 key={/* unique key */}>contact.hello</h1>
        ))}
      </div>
    );
  }
}

答案 3 :(得分:0)

在安装组件之前,使用async等待来获取响应

import React, { Component } from 'react'
import axios from 'axios';


class Contacts extends Component {
  constructor(){
   super();

   this.state = {
      contacts: [],
   }
  }

  async componentWillMount(){
    const response = await axios.get('url')
    this.setState({ contacts: response.data })
  }

  render() {
      const { contacts } = this.state
      return(
      <div>
          {contacts.map(contact => (
              <h1>contact.hello</h1>
          ))}

      </div>
      )
   }
}

export default Contacts;