使用React Hooks多次获取数据axios

时间:2019-04-04 17:34:49

标签: reactjs axios react-hooks

我想从Github用户和他的仓库中获取全局信息(并获得固定的仓库会很棒)。我尝试通过异步等待来实现,但这是正确的吗?我有4次reRender(4次控制台日志)。提取所有数据后是否可以等待所有组件重新渲染?

function App() {
  const [data, setData] = useState(null);
  const [repos, setRepos] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const respGlobal = await axios(`https://api.github.com/users/${username}`);
      const respRepos = await axios(`https://api.github.com/users/${username}/repos`);

      setData(respGlobal.data);
      setRepos(respRepos.data);
    };

    fetchData()

  }, []);

  if (data) {
    console.log(data, repos);
  }

  return (<h1>Hello</h1>)
}

4 个答案:

答案 0 :(得分:0)

批处理多个状态更新,但仅当它从事件处理程序中同步发生而不是setTimeoutsasync-await wrapped methods时才进行批处理。

此行为类似于类,因为在您的情况下,由于发生了两个状态更新调用,因此它执行两个状态更新周期

因此,最初您有一个初始渲染,然后有两个状态更新,这就是组件渲染三次的原因。

由于案例中的两个状态是相关的,因此您可以创建一个对象并一起更新它们

function App() {
  const [resp, setGitData] = useState({ data: null, repos: null });

  useEffect(() => {
    const fetchData = async () => {
      const respGlobal = await axios(
        `https://api.github.com/users/${username}`
      );
      const respRepos = await axios(
        `https://api.github.com/users/${username}/repos`
      );

      setGitData({ data: respGlobal.data, repos: respGlobal.data });
    };

    fetchData();
  }, []);

  console.log('render');
  if (resp.data) {
    console.log("d", resp.data, resp.repos);
  }

  return <h1>Hello</h1>;
}

Working demo

答案 1 :(得分:0)

想通了,因为上面的答案很不错,但是我很喜欢清洁。

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

const Test = () => {
    const [data, setData] = useState([])

    useEffect(() => {
        (async () => {
            const data1 = await axios.get('https://jsonplaceholder.typicode.com/todos/1')
            const data2 = await axios.get('https://jsonplaceholder.typicode.com/todos/2')
            setData({data1, data2})
        })()
    }, [])

    return JSON.stringify(data)
}

export default Test

使用自调用函数会花费额外的步骤来调用useEffect中的函数,有时可能会在WebStorm和PHPStorm等IDE中引发Promise错误。

答案 2 :(得分:0)

对于其他研究人员(Live demo):

import React, { useEffect, useState } from "react";
import { CPromise, CanceledError } from "c-promise2";
import cpAxios from "cp-axios";

function MyComponent(props) {
  const [error, setError] = useState("");
  const [data, setData] = useState(null);
  const [repos, setRepos] = useState(null);

  useEffect(() => {
    console.log("mount");
    const promise = CPromise.from(function* () {
      try {
        console.log("fetch");
        const [respGlobal, respRepos] = [
          yield cpAxios(`https://api.github.com/users/${props.username}`),
          yield cpAxios(`https://api.github.com/users/${props.username}/repos`)
        ];

        setData(respGlobal.data);
        setRepos(respRepos.data);
      } catch (err) {
        console.warn(err);
        CanceledError.rethrow(err); //passthrough
        // handle other errors than CanceledError
        setError(err + "");
      }
    }, []);

    return () => {
      console.log("unmount");
      promise.cancel();
    };
  }, [props.username]);

  return (
    <div>
      {error ? (
        <span>{error}</span>
      ) : (
        <ul>
          <li>{JSON.stringify(data)}</li>
          <li>{JSON.stringify(repos)}</li>
        </ul>
      )}
    </div>
  );
}

答案 3 :(得分:-1)

function App() {
  const [resp, setGitData] = useState({ data: null, repos: null });

  useEffect(() => {
    const fetchData = async () => {
      const respGlobal = await axios(
        `https://api.github.com/users/${username}`
      );
      const respRepos = await axios(
        `https://api.github.com/users/${username}/repos`
      );

      setGitData({ data: respGlobal.data, repos: respGlobal.data });
    };

    fetchData();
  }, []);

  console.log('render');
  if (resp.data) {
    console.log("d", resp.data, resp.repos);
  }

  return <h1>Hello</h1>;
}

he made some mistake here:
setGitData({ data: respGlobal.data, repos: respGlobal.data(respRepos.data //it should be respRepos.data});