React useQuery 将数据传递给子组件而无需重新渲染

时间:2020-12-25 08:45:51

标签: reactjs graphql use-effect use-state

我是反应、钩子和 gql 的新手,遇到了这个问题 - 每次查询运行时我都会得到“正在加载...”和地图组件的重新渲染(地图消失,然后与新数据一起出现) .有没有办法将它直接传递给地图而无需 MapBox 组件重新渲染和“正在加载...”标志?我想我可以将 gql 放入 MapBox 组件并从那里运行查询,但是如果可以像我描述的那样做?谢谢

PS: 每次我单击“缩放”按钮时,MapProvider 都会更新查询并打印 Loading 并重新渲染地图 MapBox 组件。我想以某种方式将查询中的数据传递给 MapBox comp 并且不重新渲染 MapBox 组件

import { useQuery, gql } from "@apollo/client";
import { useState, useEffect } from "react";
import MapBox from "./map";

const MAP_QUERY = gql`
  query MapQuery($position: [[Float]]!, $zoom: Float!) {
    lines: linesByPosition(position: $position, zoom: $zoom) {
     return some lines geojson
    }
  }
`;
const MapProvider = () => {

  const [zoom, setZoom] = useState(5);
  const [position, setPosition] = useState([
    [47.61003115514454, 18.991722981667806],
    [47.60679062928742, 19.263634602761556],
    
  ])
  console.log('position', position);
  const { loading, error, data, refetch } = useQuery(MAP_QUERY, {
    variables: {
      zoom: 12, position: [
        [47.61003115514454, 18.991722981667806],
        [47.60679062928742, 19.263634602761556],
      ]
    },
  });

  useEffect(() => {
    console.log('REFETCH !!! zoom, positioin', zoom, position);
    refetch({ zoom, position });
  }, [zoom, position]);

  
  if (loading) return <p>Loading...</p>;
  if (error) return <div>Error: {error.message}</div >;
  const { lines } = data;

  return (<>
    <MapBox geojson={{ lines }} zoom={zoom} />
    <button onClick={
      () => setZoom(zoom + 1)
    }>Zoom</button>
  </>)
}

export default MapProvider;

1 个答案:

答案 0 :(得分:0)

只需检查数据是否可用并显示加载:

  if (!data && loading) return <p>Loading...</p>;
  if (!data && error) return <div>Error: {error.message}</div >;

但最好的方法应该是在屏幕上进行绝对加载以获得更好的用户体验或像这样禁用缩放按钮:

<button onClick={
  () => setZoom(zoom + 1)
} disable={loading}>Zoom</button>