Несколько запросов на выборку для получения URL-адресов изображений - PullRequest
1 голос
/ 16 марта 2020

Я пытаюсь получить изображения по их идентификаторам. Архитектура серверной части выглядит следующим образом: БД хранит изображения в двоичном виде, и есть еще одна таблица, в которой хранятся идентификаторы изображений.

Я использую клиент apollo на внешнем интерфейсе, чтобы предварительно выбирать идентификаторы изображений, а затем отправлять другой набор запросов на выборку. К сожалению, я получаю Error: Too many re-renders. React limits the number of renders to prevent an infinite loop. Может ли кто-нибудь помочь мне 1) выяснить, почему это происходит. Я вижу, что в стеке есть куча ожидающих обещаний. и 2) как его можно реорганизовать для улучшения архитектуры.

import React, {useState} from 'react'
import {useQuery} from "@apollo/react-hooks";
import {gql} from 'apollo-boost';

const apiEndpoint = 'http://localhost:9211';

const getProductImage = function (id) {
  return gql`
  {
    productById(id: "${id}") {
      images {
        imageId
      }
    }
  }`
};

const fetchImage = (imageUrl, allImgsArr) => {
  return fetch(imageUrl)
    .then(res => res.blob())
    .then(img => allImgsArr.push(URL.createObjectURL(img)))
};

const ItemPage = (props) => {
  const [id] = useState(props.match.params.id);
  const {data} = useQuery(getProductImage(id));
  let imagesIds = [];
  if (data) {
    data.productById.images.forEach(image => {
      imagesIds.push(image.imageId)
    });
  }
  const [imagesUrls, setImagesUrl] = useState([]);

// MULTIPE FETCH RETRIEVALS START

  for (let imId of imagesIds) {
    setImagesUrl(imagesUrls => [...imagesUrls, fetchImage(`${apiEndpoint}/image/${imId}`, imagesUrls)]);
  }

// MULTIPE FETCH RETRIEVALS END 

  return (
    <>
      <div>
        <div>
          <img src={imagesUrls[0] ? imagesUrls[0] : ''} alt="main item 1 photo"/>
        </div>
        <div>
          <div>
            <img src={imagesUrls[1] ? imagesUrls[1] : ''} alt="Additional item 1 photo"/>
          </div>
        </div>
      </div>
    </>
  )
};

export default ItemPage;

1 Ответ

1 голос
/ 16 марта 2020

Ваш запрос должен быть константой, а не функцией.

const GET_PRODUCT_IMAGE = gql`
  query getProduct($id:String!) { 
   productById(id: $id) {
      images {
        imageId
      }
    }
  }
}`

// pass variables like this 
 const {data} = useQuery(GET_PRODUCT_IMAGE, { variables: { id },
 });

Подробнее: https://www.apollographql.com/docs/react/data/queries/

...