首页 > 解决方案 > 具有多个 API 调用的 React 函数

问题描述

在我的反应应用程序中的一个组件的代码下方。以下代码有多个问题并且效率非常低 - 我想讨论一下:

  1. 异步 API 调用彼此紧密耦合,这绝对不是最佳实践,那么如何改进呢?
  2. 如何在不使用 useEffect() 的情况下将userName传递给fetchSubs,或者我在这里以错误的方式使用 useEffect?
  3. 由于第二点的问题,我正在考虑使用经典的反应类是否更好,并且状态管理看起来不是很好。

在此先感谢,我很高兴与您讨论此代码。(我想,我做错了一些事情)

    import React, { useState, useEffect } from 'react';
    import { API,Auth, graphqlOperation } from 'aws-amplify';
    import * as queries from '../../graphql/queries';
    import * as subscriptionsgraph from '../../graphql/subscriptions'
    import { Grid, Table } from 'semantic-ui-react';


    function listReservations() {
      const [reservations, setReservations] = useState([]);
      const [userName, setUserName] = useState([]);

      useEffect(() => {
        fetchUser();
        fetchSubs(userName);
      },[userName]);

       // get username
       const fetchUser = async () => {
          await Auth.currentAuthenticatedUser()
          .then(user => {
            setUserName(user.username);
          }).catch(err => {
            console.log('error: ', err)
          });
        }

      // get subs
      const fetchSubs = async(userName) => {
        const limit = 100;
          API.graphql(graphqlOperation(queries.searchSubtos, {
            limit,
            input: { owner: userName }
          })).then(payload => {
            const data = payload.data.searchSubtos.items;
            fetchReservations(data); // get Reservations
          }).catch(err => {
              console.log('error: ', err)
            });
      } 

      // get Reservations
      const fetchReservations = async (data) => {
        const limit = 100; 

        data.forEach(async (item) => {
          console.log(item.location);
          await API.graphql(graphqlOperation(queries.searchReservations, {
            limit,
            sort: {
              field: 'startDate',
              direction: 'asc'
            },
            filter: {
              location: {
                eq: item.location
              }
            }
          }
          )).then(payload => {
            const data = payload.data.searchReservations.items
            setReservations(data);
          }).catch(err => {
            console.log('error: ', err)
          });
        });
        }

      return (
        <div>
          <Grid centered style={{ marginTop: '15px' }}>
            <Grid.Row>
              <Grid.Column width={12}>
                <Table celled striped>
                  <Table.Header>
                    <Table.Row>
                      <Table.HeaderCell colSpan="3">City </Table.HeaderCell>
                      <Table.HeaderCell colSpan="3">Location</Table.HeaderCell>
                    </Table.Row>
                  </Table.Header>
                  <Table.Body>
                    { reservations.map((rest, i) => (
                      <Table.Row key={i}>
                        <Table.Cell colSpan="3">{rest.city}</Table.Cell>
                        <Table.Cell colSpan="3">{rest.location}</Table.Cell>
                      </Table.Row>
                    ))
                    }
                  </Table.Body>
                </Table>
              </Grid.Column>
            </Grid.Row>
          </Grid>
        </div>
      );
    }
    export default listReservations;

标签: reactjsaws-amplify

解决方案


首先,如果您没有用户名数组,则更改用户名的初始值,例如:

const [userName, setUserName] = useState(null);

然后,使用它在页面加载时获取用户名:

useEffect(() => {
  fetchUser();
},[]);

再放 1 个useEffect函数,在获取有效用户名后获取潜艇

useEffect(() => {
  if (username) fetchSubs(username);
},[username]);

推荐阅读