【问题标题】:render api response array object on react在 react 上渲染 api 响应数组对象
【发布时间】:2018-09-15 04:19:49
【问题描述】:

我正在尝试从 API 中获取一些数据,并遍历解析的响应内容并呈现它们。

但是我收到了警告

webpackHotDevClient.js:138 ./src/App.js

Line 20:  Expected an assignment or function call and instead saw an expression  no-unused-expressions

这是我的App.js:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import './Api.css';

class App extends Component {

  render() {
    var request = new XMLHttpRequest();
    var listItems;
    request.open('GET', 'https://ghibliapi.herokuapp.com/films', true);
    request.onload = function () {

      // Begin accessing JSON data here
      var data = JSON.parse(this.response);

      if (request.status >= 200 && request.status < 400) 
      {
            listItems = data.forEach(movie => {
                <div className="card">
                    <h1>{movie.title}</h1>
                    <p>{movie.description}</p>
                </div>
            });
      } 
      else {
        console.log('error');
      }
    }

    request.send();

    return (
    <div className="App">
        <img src={logo} className="App-logo" alt="logo" />
        <div className="container">
            {listItems}
        </div>
    </div>
    );
  }
}

export default App;

当我在request.send() 之后尝试console.log(listItems) 时,我得到undefined。

我认为undefined 问题可能是因为asynchronous 行为。 如何渲染这些元素?

【问题讨论】:

    标签: javascript reactjs api


    【解决方案1】:

    render 方法不适合进行异步请求。您应该在componentDidMount 等合适的生命周期方法中移动获取代码,或者使用一个函数然后从componentDidmount 调用它。然后,使用组件状态,您需要将此获取的数据放入您的状态。

    警告来自 linter。您正在使用 forEach 和 forEach 不返回任何内容。这就是为什么警告说它需要在那里进行赋值或函数调用的原因。您应该使用 map 而不是 forEach 来创建 JSX 元素。

    对于undefined 部分,您猜对了。您的请求是异步的,并且您的渲染方法不会等待异步请求完成其工作,想要立即渲染 listItems 但还没有 listItems :) 这就是我们使用 React 最好的部分之一的原因:状态和生命周期方法。

    class App extends React.Component {
      state = { movies: [] };
    
      componentDidMount() {
        this.getItems();
      }
    
      getItems = () => {
        const that = this;
        const request = new XMLHttpRequest();
        request.open("GET", "https://ghibliapi.herokuapp.com/films", true);
        request.onload = function get() {
          const data = JSON.parse(this.response);
    
          if (request.status >= 200 && request.status < 400) {
            that.setState({ movies: data });
          } else {
            console.log("error");
          }
        };
    
        request.send();
      };
    
      listItems = () =>
        this.state.movies.map(movie => (
          <div className="card">
            <h1>{movie.title}</h1>
            <p>{movie.description}</p>
          </div>
        ));
    
      render() {
        return (
          <div className="App">
            <div className="container">{this.listItems()}</div>
          </div>
        );
      }
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="root"></div>

    【讨论】:

    • 欢迎您@Azima。我已经稍微更新了我的答案。我认为现在更清楚了。
    • 还有一件事,你为什么用componentDidMount而不是componentWillMount?因为componentDidMount 钩子仅在渲染方法之后被调用。
    • 有两个原因。 1.render 方法不等待componentWillMount。因此,使用componentDidMount 或它没有区别。 2. componentWillMount 将在未来的版本中被弃用:) reactjs.org/docs/react-component.html#unsafe_componentwillmount
    • listItems = () => return this.state.movi​​es.map(movie => (

      {movie.title}

      {movie.description}

      ));应该退掉,否则不行。
    • @KarthikRajan,它是一个箭头函数并且有一个隐式返回。如果你使用return,那么你应该在那里使用一个主体块。 See for more.
    猜你喜欢
    • 2019-11-15
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    • 2015-11-16
    • 1970-01-01
    • 2019-03-19
    相关资源
    最近更新 更多