【问题标题】:API call with ReactJs Component doesnt work使用 ReactJs 组件的 API 调用不起作用
【发布时间】:2021-03-08 08:27:58
【问题描述】:

我对反应真的很陌生,我不了解一些事情(也在重新思考之后)。因此,我将在这里提出我的问题。在此之前,我想为我糟糕的英语和可能愚蠢的问题道歉。

我有一个 js 类,在其中调用我的 API 和一个 Component 类,它应该代表数据。我导出函数,它调用 API 和数据并将其导入“index.js”,并将其作为我的 Component 类作为道具。

我的第一个问题是,我的 API 的函数返回正确的值(一个数组),但是当我在组件中调用此函数时,它返回未定义。

API.js:

const BASE_URL = "https://ghibliapi.herokuapp.com";
const encodeSpaces = (text) => text.replace(/ /g, "%20");
let cache;

function getMovies2() {
  fetch(`${BASE_URL}/films`).then(response =>  response.json())
  .then(movies => {
    cache = movies;
    console.log(movies);
    return movies;
  }).catch((e) => {
    console.log("Api Call failed");
  });
 // return movies;
}

//copied and not written by me
function getMovies() {
if (cache !== undefined) return Promise.resolve(cache);

  return fetch(`${BASE_URL}/films`)
    .then((response) => response.json())
    .then((movies) =>
      movies.map((movie) => {
        movie.urlEncodedTitle = encodeSpaces(movie.title);
       return movie;
      })
    )
    .then((movies) => {
      cache = movies;
      return movies;
    });
}

//copied and not written by me
function getMovieByTitle(title) {
  if (cache !== undefined)
    return Promise.resolve(cache.find((movie) => movie.title === title));

  title = encodeSpaces(title);

  return fetch(`${BASE_URL}/films?title=${title}`)
    .then((response) => response.json())
    .then((data) => data[0])
    .then((movie) => {
      movie.urlEncodedTitle = encodeSpaces(title);
      return movie;
    });
}

export { BASE_URL, getMovies, getMovieByTitle, getMovies2};

Index.js:(里面有组件)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {Container} from 'react-bootstrap';
import {getMovies2} from './API/callAPI';
import reactDom from 'react-dom';
import { isCompositeComponentWithType } from 'react-dom/test-utils';


class RenderMovies extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    var renderedOutput = [];
    Promise.resolve(this.props.movie).then(()=>  {
        console.log(this.props.movie);
    });
    // if(movie===undefined) {
    //   console.log("nix");
    //   return  <div><p>API Fheler!</p></div>;
    // } else{
    //   console.log(movie);
    // }
    // Promise.resolve(movie).then((movie) =>{
      // console.log("Hello");
      // renderedOutput = movie.map((item) => {
      //   console.log(item.title);
      // return <div>{item.title}</div>;
      // });
    // });
  
    return(
      <div><p>{renderedOutput}</p></div>
    );
  }
}

ReactDOM.render(
  <RenderMovies movies={getMovies2()}/>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
reportWebVitals();

(注释掉的代码只是测试)。 此外,我有 2 个问题。第一:为什么我的 getMovies2() 的返回类型是 void(当你将鼠标悬停在函数上时你可以看到它)第二:正如你看到的 getMovies() 函数返回一个 Promise,我的问题是,什么值当我解决 Promise 时,我会在调用函数时得到。

【问题讨论】:

    标签: javascript reactjs api rest


    【解决方案1】:

    为什么我的 getMovies2() 的返回类型是 void

    这是一个无效的返回,因为你没有从函数返回任何东西。如果您返回 fetch 调用,那么它将返回 Promise fetch 返回。

    function getMovies2() {
      return fetch(`${BASE_URL}/films`) // <-- return Promise chain
        .then(response =>  response.json())
        .then(movies => {
          cache = movies;
          console.log(movies);
          return movies;
        }).catch((e) => {
          console.log("Api Call failed");
        });
    }
    

    如您所见,getMovies() 函数返回一个 Promise 和我的问题 是,当我解决 Promise 时,调用时我会得到什么值 函数

    您没有解决 Promise,它会被解决(或被拒绝)。如果它解析了,那么您应该收到解析后的值,然后您可以从中链接。

    给定:

    function getMovies() {
      if (cache !== undefined) return Promise.resolve(cache);
    
      return fetch(`${BASE_URL}/films`)
        .then((response) => response.json())
        .then((movies) =>
          movies.map((movie) => {
            movie.urlEncodedTitle = encodeSpaces(movie.title);
           return movie;
          })
        )
        .then((movies) => {
          cache = movies;
          return movies; // <-- returned resolved value!
        });
    }
    

    getMovies 解析时,您将收到movies 数组。

    您可以链接thenable

    getMovies()
      .then(movies => { ..... })
      .catch(error => {
        // handle promise rejections/processing errors.
      });
    

    或者您可以定义一个async 函数并等待解析的值

    const myFunc = async () => {
      try {
        const movies = await getMovies();
        ...
      } catch(error) {
        // handle promise rejections/processing errors.
      }
    };
    

    此外,您不应该在 render 方法中获取数据或任何其他类型的异步逻辑,因为这是一个没有副作用的纯函数,这就是 componentDidMountcomponentDidUpdate生命周期方法适用于。

    【讨论】:

    • 那么我是否理解正确,如果我想从 API 调用返回任何内容,我必须通过 fetch 函数返回这个值?
    • @Niklas 我不太理解你的问题,但是如果“通过 fetch 函数返回这个值”你的意思是“返回 fetch 函数的结果”,那么是的。 fetch 返回一个 Promise,因此如果您想最终处理任何已解决/拒绝的值,则需要返回 that Promise。
    猜你喜欢
    • 2018-04-18
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多