Apollo:组件的重新渲染之间的加载状态

时间:2019-06-20 10:03:41

标签: reactjs apollo react-apollo react-hooks

我有以下内容。

import React from 'react';
import { useQuery } from 'react-apollo-hooks';

import Table from 'components/Table';
import { useQueryParams } from 'customHooks';
import { LOCATIONS } from 'graphql/queries';

const useLocations = ({ filters, max, sorting }) => {
    const variables = { max, filters, sorting };
    return useQuery(LOCATIONS, { variables, fetchPolicy: 'network-only' });
};

const Search = ({ filters, sorting }) => {
    // Gets the value for the parameter "max" from the URL, with default 100
    const { max, updateURLParam } = useQueryParams({ max: 100 });

    const { data, error, loading } = useLocations({ filters, sorting, max });

    if (loading && !data.myData) return <div>Loading</div>;

    if (error) return <div>Error</div>;

    // Update the URL parameter "max"
    // Example
    // Before: https://localhost:3000/table?max=100
    // After: https://localhost:3000/table?max=200
    const handleReachBottom = () => updateURLParam({ max: max + 100 });

    return <Table.Locations data={data} onReachBottom={handleReachBottom} />;
};

export default Search;

我期望的行为如下:

  1. 显示“正在加载”
  2. 显示包含数据的表
  3. 滚动到表格底部
  4. 在获取新数据时,表格仍在显示中
  5. 获取数据后,表将更新

在我使用阿波罗的Query component之前,它的工作原理完全一样。但是当我切换到react-apollo-hooks程序包时,其行为更改为:

  1. 显示“正在加载”
  2. 显示包含数据的表
  3. 滚动到表格底部
  4. 显示“正在加载”
  5. 获取数据后,表将更新

为什么会这样?

更新

这是我以前使用它的方式:

import React from 'react';
import { Query } from 'react-apollo';


import Table from 'components/Table';
import useQueryParams from 'customHooks/useQueryParams';

const Locations = ({ filters, max, sorting, children }) => {
    const variables = { max, sorting };

    return (
        <Query {...{ variables }} query={LOCATIONS} fetchPolicy='network-only'>
            {children}
        </Query>
    );
};


const Search = ({ filters, sorting }) => {
    const { max, updateURLParam } = useQueryParams({ max: 100 });

    return (
        <MyClient.Locations {...{ filters, sorting, max }}>
            {({ data, loading, error }) => {
                if (loading && !data.myData) return <div>Loading</div>;

                if (error) return <div>Error</div>;

                const handleReachBottom = () => updateURLParam({ max: max + 100 });


                return (
                    <Table.Locations
                        data={data}
                        onReachBottom={handleReachBottom}
                    />
                );
            }}
        </MyClient.Locations>
    );
};

export default Search;

1 个答案:

答案 0 :(得分:0)

我之前在react-apollo-hooks遇到过这个问题,我觉得重新获取,变量和fetchPolicy的行为与标准Apollo略有不同。我从来没有深入了解它。

我解决这个问题的方法是不使用loading道具,而是使用数据本身的存在来决定要做什么。这种方法在重新提取时有效

const [data, setData] = useState(null)

const res = useLocations({ filters, sorting, max });

useEffect(() => {
  if (Object.keys(res.data || {}).length > 0) {
    setData(res.data)
  }
}, [res.data])

if (!data) return <div>Loading</div>