【问题标题】:How do you submit an API request from the front-end based on the result of a previous API request on an Apollo graphql server?如何根据 Apollo graphql 服务器上先前 API 请求的结果从前端提交 API 请求?
【发布时间】:2020-08-06 06:06:02
【问题描述】:

我正在使用两个 API 端点。第一个以字符串格式返回日期列表,其中数据可用。然后可以将日期添加到第二个端点并呈现其他数据。在 Graphql Playground 上,我已经能够完成所有工作。在前端,我有一个日期的选择选项下拉菜单,但是当我单击任何给定日期时,我无法触发第二个 API 调用。这是我第一次使用 graphql 突变,当我选择日期时,我无法获得第二个 API 请求以返回任何数据。谢谢。

前端代码:

app.tsx


import * as React from 'react'
import { useState } from 'react'
import { useMutation } from '@apollo/react-hooks'
import { IrriSatQuery } from '../../generated/graphql'
import { MAP_LAYER } from './query'

interface Props {
  data: IrriSatQuery;
}

const IrriSat: React.FC<Props> = ({ data }) => {
  const [option, setOption] = useState((data?.mapDates as any)[0].date!)
  const [getLayer] = useMutation(MAP_LAYER)

  return (
    <>

    <ContentWrapper>
      <select value={option} onChange={( e: React.ChangeEvent<HTMLSelectElement>, ): void => {setOption(e.target.value, getLayer(e.target.value)}} onSelect={() => getLayer({variables: {type: option}})}>
        {data?.mapDates?.slice(0,52).map(res => 
          <option key={res?.date!} value={res?.date!}>{res?.date}</option>
          )
        }
      </select>
    </ContentWrapper>
    </>
  )
}

export default IrriSat

query.ts


export const QUERY_IRR_SAT = gql`
 query IrriSat {
   mapDates {
     date
     dateurl
   }
 }
`

export const MAP_LAYER = gql`
  mutation MapLayer($date: String!) {
     mapDate(date: $date) {
       token
       mapid
       name
     }

   }
`

后端代码:

server.js

class IrriSatAPI extends RESTDataSource {
  constructor() {
    super();
    this.baseURL = 'https://irrisat-cloud.appspot.com/_ah/api/irrisat/v1/services/'
  }

  async getMapsDates() {
    const response = await this.get('maps/dates')
    return Array.isArray(response.items) ? response.items.map(response => this.mapsDatesReducer(response)) : []
  }

  mapsDatesReducer(response) {
    return {
      date: response.date,
      dateurl: response.dateurl,
    }
  }

  async getMapsLayer(date) {

    const response = await this.get(`maps/layers/${date}`)
    return Array.isArray(response.items) ? response.items.map(response => this.mapsLayerReducer(response)) : []
  }

  mapsLayerReducer(response) {
    return {
      token: response.token,
      mapid: response.mapid,
      name: response.name
    }
  }


  }
}

schema.js

  type MapDates {
    date: String
    dateurl: String
  }

  type Mutation {
    mapDate(date: String): [MapsLayers]
  }

  type Query {
    mapDates: [MapDates]

resolver.js

module.exports = {
  Query: {
    mapDates: (_, __, { dataSources }) => dataSources.irriSatAPI.getMapsDates(),
  },
  Mutation: {
    mapDate: (_, { date }, { dataSources }) => dataSources.irriSatAPI.getMapsLayer(date)
  }
}

【问题讨论】:

  • 根本没有被解雇?在循环中渲染链接/按钮(学习如何使用变量)-检查开发工具/网络(检查是否触发请求).....没有使用突变结果数据(您可以使用突变的'onCompleted'处理程序选项-使用另一个 setState - 为什么要从 props 覆盖数据?使用一些 'selectedDate'?) ...您可以使用 useEffectoption 更改 (效果依赖,效果在开始时触发并由setOption 强制执行,因为您没有更改远程数据...重新考虑您的数据状态和流程

标签: reactjs graphql apollo-server graphql-mutation


【解决方案1】:

onChange 函数存在一些问题。

你调用 getLayer 两次?您应该只需要调用一次,同时设置下拉列表的值。另外,据我所知,您实际上并不需要onSelect

import * as React from 'react';
import { useState } from 'react';
import { useMutation } from '@apollo/react-hooks';
import gql from 'graphql-tag';

const MAP_LAYER = gql`
    mutation MapLayer($date: String!) {
        mapDate(date: $date) {
            token
            mapid
            name
        }
    }
`;

const ContentWrapper = ({ children }) => <div>{...children}</div>;

const IrriSat: React.FC<any> = ({ data }) => {
    const [option, setOption] = useState((data?.mapDates as any)[0].date!);
    const [getLayer]: any = useMutation(MAP_LAYER);

    return (
        <ContentWrapper>
            <select
                value={option}
                onChange={(e: React.ChangeEvent<HTMLSelectElement>): void => {
                    setOption(e.target.value);
                    getLayer({ variables: { date: e.target.value } });
                }}
            >
                {data?.mapDates?.slice(0, 52).map(res => (
                    <option key={res?.date!} value={res?.date!}>
                        {res?.date}
                    </option>
                ))}
            </select>
        </ContentWrapper>
    );
};

export default IrriSat;

显然,我更改了一些内容以消除一些编辑器警告,但要特别注意 onChange 属性。

提示:您可能会遇到这些问题,因为您将所有这些逻辑压缩到其中的行的 极端 长度。安装“Prettier - Code formatter”VS Code 扩展。在保存选项中启用 VS Code 的格式。利润。

【讨论】:

  • 是的,我在提出问题时忘记删除 onSelect 了。我不是故意调用 getLayer 两次。无论如何,到目前为止,他们的关键是将 getLayer 变量设置为“日期”。我现在在 DevTools 中获取 GraphiQL 中的数据。我仍然需要弄清楚如何实际访问数据。非常感谢您的帮助。
猜你喜欢
  • 2020-03-04
  • 2020-10-23
  • 1970-01-01
  • 1970-01-01
  • 2020-01-23
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 2021-06-26
相关资源
最近更新 更多