【问题标题】:React / Axios prevent fetch API call get multiple timesReact / Axios 防止 fetch API 调用 get 多次
【发布时间】:2020-10-14 18:04:51
【问题描述】:

我是编程世界和 reactjs 的新手。

我创建了一个反应应用程序。在我的主页组件中,它的目的是从服务器获取数据,然后将这些数据传递给相应的组件。

我使用 jsonplaceholder 作为我在代码框中显示的假 api。 https://codesandbox.io/s/intelligent-antonelli-ju56k

当我 console.log 数据时,我得到 2 个结果:

[]
[]
-> actual data get back
-> actual data get back

如何防止那些空取?处理这个问题的最佳方法是什么?

这是我的 jsx 代码:

import React, { Component } from "react";
import "./Homepage.css";

import Hero from "../components/Hero/Hero";
import ImageGallery from "../components/ImageGallery/ImageGallery";

import Axios from "axios";

export class Homepage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: []
    };
  }

  async componentDidMount() {
    try {
      await Axios.get("https://jsonplaceholder.typicode.com/todos")
        .then((res) => {
          this.setState({ data: res.data });
        })
        .catch((error) => {
          alert(error);
        });
    } catch (error) {
      alert(error);
    }
  }

  render() {
    const data = this.state;
    console.log(data, "hi");
    return (
      <>
        <Hero jsondata={data} />
        <ImageGallery jsondata={data} />
      </>
    );
  }
}

export default Homepage;

【问题讨论】:

  • 如果您的目标是在未获取数据之前不渲染组件,那么您应该使用条件渲染。例如仅当数据存在时才呈现组件。
  • 感谢您的建议。在条件渲染之后,我修改了代码框中的代码。 [codesandbox.io/s/intelligent-antonelli-ju56k]。但发生了另一个问题。我的子组件在从父组件传递后收到未定义。这样传递数据是否正确?
  • 这是因为您没有使用正确的状态变量。我可以看到三种不同的状态来保持从 api 获取的数据。在 Axios 调用后,获取的数据在 aftherFetchingData 中设置,渲染使用 jsonData 并在构造函数中使用 data 初始化状态。请在整个组件中保持相同。

标签: reactjs axios


【解决方案1】:

很遗憾,你不能。这些不是空的获取,而是console.log 在实际检索到data 之前的结果。根据组件的 React 生命周期:组件被挂载,render 方法首先执行(这就是为什么你得到一个空的console.log)。在此之后componentDidMount 方法触发,启动代码来获取您的数据。您可以在此处了解有关 React 生命周期的更多信息:React lifecycle

此机制确保您的视图已加载到页面中,向用户显示某些内容,同时异步检索数据。数据到达后,组件将使用数据重新渲染。

但是,您可以决定以同步方式检索数据,阻止第一个组件呈现,直到数据完全可用,但这是一种反模式。

如果您想在数据到达后立即显示某些内容,您可以考虑条件渲染。那就是在某些情况发生时渲染组件。这里是官方文档conditional rendering

父组件向子组件传递数据的机制是props的机制。

将孩子定义为:

function Child(props) {
    console.log(props.myData)
    console.log(props.prop2)
}

然后:

<Parent>
    <Child myData={data} prop2={"just another prop"}></Child>
</Parent>

【讨论】:

  • 感谢您的建议。我在代码框里修改了我的代码。 [codesandbox.io/s/intelligent-antonelli-ju56k]。但发生了另一个问题。我的子组件在从父组件传递后收到未定义。这样传递数据是否正确?
  • 你快到了,我修改了你的沙盒并更新了这个答案。
  • 请注意,要解构对象,您需要变量具有相同的名称。 this.state = { data: [], isLoading : false }const {data, isLoading} = this.state
  • 这里是工作沙箱:codesandbox.io/s/laughing-keldysh-rq27v
【解决方案2】:

这实际上不是一个需要担心的问题,在 react js 中是完全正常的。 该组件首先呈现自己,因此第一个 console.log 就是为此。然后当你对 componentDidMount 生命周期方法进行 axios 调用时,它会再次重新渲染自己。

当 state 或 props 改变时重新渲染是 react js 的特性。你可能想使用 react 的 PureComponent 。您可以在react's own documenttaion website中找到所有相关文档

【讨论】:

    猜你喜欢
    • 2022-10-14
    • 2021-10-13
    • 1970-01-01
    • 2018-01-27
    • 2018-04-12
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多