HTTP在react.js中使用axios获取请求

时间:2020-05-04 07:45:39

标签: reactjs axios react-hooks

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 个答案:

答案 0 :(得分:1)

简短回答

您不能也不应尝试。首次加载时,您甚至没有数据来填充状态。因此,您无法做到这一点。

长期回答

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

此外,不必担心此行为。实际上,这对于任何实际应用都是很常见的。

希望有帮助。

答案 1 :(得分:0)

不可能

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

快速修复

阻止这种破坏的一种方法是确保您拥有默认值,就像已经拥有的一样。

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

如果配方默认设置为[],或者如果配方中填充了数据[{someText: 'text'}],则数据映射将不会中断。如果没有数据,您也可以选择不呈现组件

return recipe ? <Component /> : null

答案 2 :(得分:0)

请检查以下示例,了解如何使用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;