解决组件的多个渲染。 useEffect,useState和Axios

时间:2020-07-13 17:47:33

标签: javascript reactjs axios react-hooks use-state

我有一个React功能组件,它正在进行axios调用,并将其设置为state,并将在渲染器中使用该数据。

当前代码:

WeatherPanel.jsx

import React, { useEffect, useState } from "react";
import getLocationData from "../api/getLocationData";

const WeatherPanel = () => {
  const [locationData, setLocationData] = useState();

  useEffect(() => {
    async function populateLocationData() {
      const data = await getLocationData();
      setLocationData(data);
    }
    populateLocationData();
  }, []);

  return locationData ? (
    <>
      <div>Hello {locationData.woeid}</div>
    </>
  ) : (
    <>Loading</>
  );
};

export default WeatherPanel;

getLocationData.js

import axios from "axios";

const getLocationData = async () => {
  const response = await axios.get("/api/location/44418/");
  return response.data;
};

export default getLocationData;

问题:

似乎我必须在渲染上有locationData ? (保护,因此在我的LoadE部分中,如果没有它,它会在useEffect中的useState完成之前尝试渲染,从而导致locationData.woeid不确定并破坏。

这是处理此问题的正确/最佳方法吗?尝试第一个渲染之前,功能组件是否可以完成某些工作?

(我知道<>Loading</>应该由加载屏幕或微调器等代替,更多地询问代码结构)。

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以保持加载状态并按以下方式处理它:

import React, { useEffect, useState } from 'react';
import getLocationData from '../api/getLocationData';

const WeatherPanel = () => {
  const [locationData, setLocationData] = useState();
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    async function populateLocationData() {
      setIsLoading(true);
      try {
        const data = await getLocationData();
        setLocationData(data);
        setIsLoading(false);
      } catch (error) {
        console.log(error);
        setIsLoading(false);
      }
    }
    populateLocationData();
  }, []);

  function renderWeahter() {
    if (isLoading) return <div>Loading...</div>;
    return <div>Hello {locationData.woeid}</div>;
  }

  return <div>{renderWeahter()}</div>;
};

export default WeatherPanel;