简体   繁体   English

如何在 React 中操作来自 api 调用的数据?

[英]How can i manipulate data from api call in React?

I make an api call to openWeatherapi but the issue is the data is "undefined" until it has resolved.我对 openWeatherapi 进行了 api 调用,但问题是数据在解决之前是“未定义的”。 So when i make the api call in ComponentDidMount and set the data to state, state is undefined for a bit until the data comes in. The issue is that in the meantime if i try to do anything with the data i get cannot "Dosomething" of propriety of undefined and the whole thing crashes. So when i make the api call in ComponentDidMount and set the data to state, state is undefined for a bit until the data comes in. The issue is that in the meantime if i try to do anything with the data i get cannot "Dosomething"未定义的适当性,整个事情都崩溃了。 How do i get around this?我该如何解决这个问题?

I have a weatherwidget and i want to pass the weather data from the api call.我有一个天气小部件,我想传递来自 api 调用的天气数据。 The city name includes the continent, so if i want to do.split() on it, i get an error because the value is undefined at first.城市名称包括大陆,所以如果我想对其进行 do.split() 操作,我会收到一个错误,因为该值一开始是未定义的。

Here's the dashboard code这是仪表板代码

import React, { PureComponent } from 'react';
import axios from 'axios';
import PropTypes from 'prop-types';
import brand from 'dan-api/dummy/brand';
import { Helmet } from 'react-helmet';
import { withStyles } from '@material-ui/core/styles';
import Hidden from '@material-ui/core/Hidden';
import Grid from '@material-ui/core/Grid';
import moment from 'moment';
import Divider from '@material-ui/core/Divider';
import {
  SliderWidget,
  CounterIconsWidget,
  PerformanceChartWidget,
  DateWidget,
  TaskWidget,
  WeatherWidget,
  ContactWidget,
  TimelineWidget,
  FilesWidget,
} from 'dan-components';
import ScrollableTabs from '../UiElements/demos/Tabs/ScrollTabs';
import styles from './dashboard-jss';

class PersonalDashboard extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      scheduleToday: [],
      scheduleTomorrow: [],
      weather: {},
    };
  }

  fetchTodaySchedule = () => {
    axios
      .get(`/api/total/schedule/?day=${moment().format('llll')}`)
      .then(response => {
        this.setState({
          scheduleToday: response.data[0].result,
        });
      })
      .catch(error => {
        console.log(error);
      });
  };

  fetchTomorrowSchedule = () => {
    axios
      .get(
        `api/total/schedule/?day=${moment()
          .add(1, 'days')
          .format('llll')}`,
      )
      .then(response => {
        this.setState({
          scheduleTomorrow: response.data[0].result,
        });
      })
      .catch(error => {
        console.log(error);
      });
  };

  fetchWeather = async () => {
    axios
      .get(`api/total/weather`)
      .then(response => {
        this.setState({
          weather: response.data,
        });
      })
      .catch(error => {
        console.log(error);
      });
  };

  async componentWillMount() {
    await this.fetchWeather();
    this.fetchTodaySchedule();
    this.fetchTomorrowSchedule();
  }

  render() {
    const title = brand.name + ' - Personal Dashboard';
    const description = brand.desc;
    const { classes } = this.props;
    return (
      <div>
        <Helmet>
          <title>{title}</title>
          <meta name="description" content={description} />
          <meta property="og:title" content={title} />
          <meta property="og:description" content={description} />
          <meta property="twitter:title" content={title} />
          <meta property="twitter:description" content={description} />
        </Helmet>
        {/* 1st Section */}
        <Grid container spacing={3} className={classes.root}>
          <Grid item md={6} xs={12}>
            <CounterIconsWidget />
          </Grid>
          <Grid item md={6} sm={12} xs={12}>
            <div className={classes.sliderWrap}>
              <SliderWidget />
            </div>
          </Grid>
        </Grid>
        <Divider className={classes.divider} />
        {/* 2nd Section */}
        <Grid container spacing={2} className={classes.root}>
          <Grid item xs={12}>
            <PerformanceChartWidget />
          </Grid>
        </Grid>
        {/* 3rd Section */}
        <Grid container spacing={3} className={classes.root}>
          <Grid item md={6} xs={12}>
            <Divider className={classes.divider} />
            {/* <ScrollableTabs /> */}
            <ContactWidget />
            <Divider className={classes.divider} />
            <TaskWidget />
          </Grid>
          <Grid item md={6} xs={12}>
            <Hidden mdDown>
              <Divider className={classes.divider} />
            </Hidden>
            <WeatherWidget weatherData={this.state.weather} />
            <Divider className={classes.divider} />
            <DateWidget />
            <Divider className={classes.divider} />
            <TimelineWidget />
          </Grid>
        </Grid>
        <Divider className={classes.divider} />
        <FilesWidget />
      </div>
    );
  }
}

PersonalDashboard.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(PersonalDashboard);

and this is the weatherwidget component这是天气小部件组件

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import 'dan-styles/vendors/react-weather/GenericWeather.css';
import classNames from 'classnames';
import styles from './widget-jss';

function WeatherWidget(props) {
  const { status, classes, temp, city, weatherData } = props;
  const cls = classNames('weather-icon', status);
  const bg = classNames(classes.weathercard, status === 'sun' ? classes.sun : classes.cloud);
  return (
    <div className={bg}>
      <div className="wheater-wrap">
        <div className={cls} />
        <h1>{temp}º</h1>
        <p>{weatherData.timezone}</p>
      </div>
    </div>
  );
}

WeatherWidget.propTypes = {
  classes: PropTypes.object.isRequired,
  city: PropTypes.string,
  temp: PropTypes.number,
  status: PropTypes.string,
};

WeatherWidget.defaultProps = {
  city: 'Bucharest',
  temp: 28,
  status: 'sun', // cloud and sun
};

export default withStyles(styles)(WeatherWidget);

在此处输入图像描述

async componentDidMount() {
  try {
    const [tickets, alerts, calls, weather, schedToday, schedTomorrow] = await Promise.all([
      axios.get('api/total/tickets'),
      axios.get('api/total/alerts'),
      axios.get('api/total/avaya/logs'),
      axios.get('api/total/weather'),
      axios.get(`/api/total/schedule/?day=${today}`),
      axios.get(`/api/total/schedule/?day=${tomorrow}`),
    ]);

    this.setState({
      tickets: tickets.data.tickets,
      alerts: alerts.data,
      calls: calls.data,
      weather: weather.data,
      scheduleToday: schedToday.data[0].result,
      scheduleTomorrow: schedTomorrow.data[0].result
    });
  } catch (err) {
    console.error(err);
  }
}

I ended up doing it this way and used async componentDidMount.我最终这样做并使用了异步 componentDidMount。

So far it seems to work fine.到目前为止,它似乎工作正常。

 async componentDidMount() {
    const ticketsPromise = await axios.get('api/total/tickets');
    const alertsPromise = await axios.get('api/total/alerts');
    const callsPromise = await axios.get('api/total/avaya/logs');
    const weatherPromise = await axios.get('api/total/weather');
    const scheduleTodayPromise = await axios.get(`/api/total/schedule/?day=${today}`);
    const scheduleTomorrowPromise = await axios.get(`/api/total/schedule/?day=${tomorrow}`);

    const resolves = await Promise.all([
      ticketsPromise.data,
      alertsPromise.data,
      callsPromise.data,
      weatherPromise.data,
      scheduleTodayPromise.data[0].result,
      scheduleTomorrowPromise.data[0].result,
    ]);

    const [ticketsData, alertsData, callsData, weatherData, schedTodayData, schedTomorrowData] =
      resolves || [];

    this.setState({ tickets: ticketsData.tickets });
    this.setState({ alerts: alertsData });
    this.setState({ calls: callsData });
    this.setState({ weather: weatherData });
    this.setState({ scheduleToday: schedTodayData });
    this.setState({ scheduleTomorrow: schedTomorrowData });
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM