开发者问题收集

在 react.js 中使用 axios 进行 Http get 请求

2020-05-04
201

Temp.js

import React, {useEffect, useState} from 'react';
import axios from 'axios'
const Temp=()=> {
    const APP_ID='8232312'
    const APP_KEY='6a4e7c08d71463dada3b481f85a9b16'
    const [receipe, setReceipe] = useState([])


    useEffect(() => {
        console.log("use effect")
axios.get(`https://api.edamam.com/search?q=chicken&app_id=${APP_ID}&app_key=${APP_KEY}`)
        .then(response => {
          console.log('get receipe by promise', response)
          console.log("use state variable receipes")
          setReceipe(response.data)
          console.log("after use state receipe = " , receipe)
        })
        .catch(e => console.log(e))


    });

    return (

        <div>

        </div>
    )
}

export default Temp

App.js

import React from 'react';
import './App.css';

import Temp from './Component/Temp';

const App = ()=> {

  return (
<div className='App'> 
<Temp></Temp>
</div>
  );
}

export default App;

控制台输出-

use effect
Temp.js:13 get receipe by promise {data: {…}, status: 200, statusText: "", headers: {…}, config: {…}, …}
Temp.js:14 use state variable receipes
Temp.js:16 after use state receipe =  []
Temp.js:10 use effect
Temp.js:13 get receipe by promise {data: {…}, status: 200, statusText: "", headers: {…}, config: {…}, …}
Temp.js:14 use state variable receipes
Temp.js:16 after use state receipe =  {q: "chicken", from: 0, to: 10, more: true, count: 168106, …}
Temp.js:10 use effect
Temp.js:13 get receipe by promise {data: {…}, status: 200, statusText: "", headers: {…}, config: {…}, …}
Temp.js:14 use state variable receipes
Temp.js:16 after use state receipe =  {q: "chicken", from: 0, to: 10, more: true, count: 168106, …}
Temp.js:10 use effect
Temp.js:13 get receipe by promise {data: {…}, status: 200, statusText: "", headers: {…}, config: {…}, …}
Temp.js:14 use state variable receipes
Temp.js:16 after use state receipe =  {q: "chicken", from: 0, to: 10, more: true, count: 168106, …}


在控制台输出中,第一次,配方设置为空,而第二次配方设置为来自 HTTP 请求的响应。但我也需要 setReceipe(response.data) 来将 receipe 设置为 response.data

3个回答

简短回答

您不能也不应该尝试。首次加载时,您甚至没有数据来填充您的状态。因此,您无法执行此操作。

详细回答

HTTP 网络调用( axios GET/POST/PUT/DELETE 或使用任何其他库的任何其他网络调用)是异步的。加载组件(应用程序)时, XHR 调用将放入队列中等待执行。在此期间,您的 UI 呈现并将您的 state 初始化为某个默认值。一旦 XHR 调用成功完成,您实际上就会从服务器收到数据。现在,您可以使用 response.data 更新您的状态。

此外,不要担心这种行为。这对于任何实际存在的应用程序来说都很常见。

希望对您有所帮助。

Sandy
2020-05-04

这是不可能的

渲染和重新渲染是相继发生的。接收数据需要时间,因此您的初始数据将为空。

快速修复

阻止此中断的一种方法是确保您有一个默认值,就像您已经拥有的一样。

const [receipe, setReceipe] = useState([])
...
receipe.map((item) => <p>{item.someText}</p>)

如果配方默认为 [] 或其填充了数据 [{someText: 'text'}] ,则数据映射不会中断。如果没有数据,您还可以选择不渲染组件

return recipe ? <Component /> : null
Joe Lloyd
2020-05-04

请查看以下示例,了解如何使用 axios 通过 GET 请求调用 api:

import React, {useEffect, useState} from "react";
import axios from 'axios';

function PostListPage() {
    const [posts, setPost] = useState([]);
    let signal = axios.CancelToken.source();

    useEffect(() => {
        let isSubscribed = true;
        axios.get('https://jsonplaceholder.typicode.com/posts', {
            cancelToken: signal.token,
        })
            .then(res => {
                const posts = res.data;
                setPost(posts);
            }).catch(err => {
            console.log(err);
        });
        return function cleanup() {
            isSubscribed = false;
            signal.cancel('Api is being canceled');
        }
    }, []);

    return (
        <React.Fragment>
            <ul>
                {
                    posts.map(post => <li key={post.id}>{post.title}</li>)
                }
            </ul>
        </React.Fragment>
    );
}
export default PostListPage;
Khabir
2020-05-04