【问题标题】:Component Exception : undefined is not an object (evaluating 'this.state.results.response.map') react native组件异常:未定义不是对象(评估“this.state.results.response.map”)反应原生
【发布时间】:2021-10-28 23:08:20
【问题描述】:

我想迭代将重复卡片的数组。我收到了回复

{
  "get":"statistics"
  "parameters":{...}
  "errors":[]
  "results":1
  "response":[...]
}

我想迭代响应并在response 内部尝试显示population

响应数组(内部)

"response":[
  {
    "continent":"Oceania"
    "country":"Australia"
    "population":25842408
    "cases":{...}
    "deaths":{...}
    "tests":{...}
    "day":"2021-08-30"
    "time":"2021-08-30T06:45:03+00:00"
  }
]

当我尝试在控制台中显示它时它可以工作并显示人口但是当我使用map() 函数重复卡片时它会给出未定义不是对象的错误 我在哪里做错了

我的班级

export default class Covidscreen extends React.Component{
      
  constructor(props){
    super(props)
    this.state = {
      results :{},
      namee:'fahad',
    };
  }

  static navigationOptions = {
    title: 'Loginscreen',
    //Sets Header text of Status Bar
    headerStyle: {
      backgroundColor: '#f4511e',
      //Sets Header color
    },
    headerTintColor: '#fff',
      //Sets Header text color
      headerTitleStyle: {
        fontWeight: 'bold',
        //Sets Header text style
      },
  };
    
  getCovidData = () => {        
    const options = {
      method: 'GET',
      params: {country: 'australia'},
      url: 'https://covid-193.p.rapidapi.com/statistics',
      headers: {
        'x-rapidapi-host': 'covid-193.p.rapidapi.com',
        'x-rapidapi-key': 'e4b2e7d44bmsh5427dd9c7fb16dbp15d226jsn1fdf62e5a45e'
      }
    };
            
    axios.request(options)
    .then((response) => {
      this.setState({results:response.data});
    })
    .catch(function (error) {
      console.error(error);
    });
  }
         
  componentDidMount() {
    this.getCovidData()
  }

  render() {
    const { navigate } = this.props.navigation;    
    return (
      <View >
        { this.state.results.response.map(row => (          
          <Card > 
            <Card.Title>{row.population}</Card.Title>
            <Card.Divider/>
          </Card>
        ))}
      </View>
    )
  }
}

我正在使用基于类的组件,并且我已经记录了响应,并且它在我尝试循环和访问人口时在那里工作

【问题讨论】:

    标签: javascript reactjs react-native axios


    【解决方案1】:

    在初始状态下,results 是一个内部没有属性response 的对象。这就是您收到错误 Component Exception : undefined is not an object (evaluating 'this.state.results.response.map') 的原因。

    在初始渲染期间,预计results 对象有一个名为response 的属性,并且预计它是一个数组(因为您在其上调用map 函数)。

    您可以通过多种不同方式解决此问题,

    1. 添加加载指示器状态(基于此状态和 API 响应,呈现列表)
    2. results 状态最初设为一个数组,然后将响应分配给它。
    3. 使 results 对象最初具有键 response 并使用数组对其进行初始化。

    这个列表可以继续下去......

    下面的代码解释了第二种方法

    export default class Covidscreen extends React.Component{
          
      constructor(props){
        super(props)
        this.state = {
          results: [], // changed the object to an array
          name: 'fahad',
        };
      }
    
      static navigationOptions = {
        title: 'Loginscreen',
        //Sets Header text of Status Bar
        headerStyle: {
          backgroundColor: '#f4511e',
          //Sets Header color
        },
        headerTintColor: '#fff',
          //Sets Header text color
          headerTitleStyle: {
            fontWeight: 'bold',
            //Sets Header text style
          },
      };
        
      getCovidData = () => {        
        const options = {
          method: 'GET',
          params: {country: 'australia'},
          url: 'https://covid-193.p.rapidapi.com/statistics',
          headers: {
            'x-rapidapi-host': 'covid-193.p.rapidapi.com',
            'x-rapidapi-key': 'e4b2e7d44bmsh5427dd9c7fb16dbp15d226jsn1fdf62e5a45e'
          }
        };
                
        axios.request(options)
        .then((response) => {
          this.setState({ results: response.data.response });
          // set the response array to the results state
        })
        .catch(function (error) {
          console.error(error);
        });
      }
             
      componentDidMount() {
        this.getCovidData()
      }
    
      render() {
        const { navigate } = this.props.navigation;    
        return (
          <View >
            { this.state.results.map(row => (          
              <Card > 
                <Card.Title>{row?.population ?? ''}</Card.Title> // added optional chaining. if the row doesn't have a population inside it, it will render an empty string.
                <Card.Divider/>
              </Card>
            ))}
          </View>
        )
      }
    }
    

    另外,完全不同的是,最好不要在代码中硬编码 API 密钥。

    【讨论】:

    • 它具有数组形式的响应属性
    • @MohammadFahad 是的,这就是我们将results 设置为response.data.response 的原因。现在results 状态将拥有来自 API 的新更新数组。
    【解决方案2】:

    在您的第一次渲染中,您的状态没有响应属性, 因此,在您从服务器接收数据之前,React 会尝试映射未定义的 state.results.response。

    所以我建议你这样定义你的初始状态:

       this.state = {
          results :{response:[]},
          namee:'fahad',
        };
    

    【讨论】:

    • 我已经尝试过了,但没有工作,我得到同样的错误它是数组名称
    【解决方案3】:

    在 getCovidData 返回响应数据之前调用 map 函数。 这就是为什么您需要确保 this.state.results.response 充满数据。

    this.state.results.response.map
    

    你可以用一个空数组来初始化你的状态:

      constructor(props){
        super(props)
        this.state = {
          results :{
            response:[]
          },
          name:'fahad', //Fix typo
        };
      }
    

    或者检查响应是否已经填写:

    this.state.results.response && this.state.results.response.map
    

    【讨论】:

    • 我如何填充它或让它更新,因为我“必须”在安装组件时调用它
    • 这不是必须的,当axios请求返回数据并调用setState时,会触发带数据的重新渲染
    【解决方案4】:

    我在设置状态时通过调用 abck 函数解决了这个问题

     this.setState({results:response.data},()=>{
                this.setCovid(this.state)
              });
    
      setCovid = (response) => {
            console.log(response);
    
          }
    

    因为它是异步的

    【讨论】:

      【解决方案5】:

      将结果对象声明为数组,因为您的 API 提供数组数据

      this.state = {
            results :[],
            namee:'fahad',
       };
      

      更新循环

      {this.state.results.map(row=>(
      <Card > 
        <Card.Title>{row.population}</Card.Title>
        <Card.Divider/>
      </Card>
        ))}
      

      你可以试试这个吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-22
        • 2018-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多