【问题标题】:Apollo: Loading state between re-renders of the componentApollo:组件重新渲染之间的加载状态
【发布时间】:2019-11-03 03:10:05
【问题描述】:

我有以下组件。

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. 获取数据后,更新表

在我使用来自 apollo 的 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;

【问题讨论】:

  • 您之前是如何使用查询组件的?因为这里 loading 会在重新获取时设置为 true 并且if (loading) return &lt;div&gt;Loading&lt;/div&gt;; 会返回正在加载的 div
  • 我用该信息更新了问题
  • 不确定这是否可行,但您可以尝试 { notifyOnNetworkStatusChange: false } 作为 useQuery 挂钩的第二个参数。
  • 不,这没有解决任何问题
  • 我使用if (loading &amp;&amp; !data.myData)更新了问题,这很有意义,但问题仍然存在

标签: reactjs apollo react-apollo react-hooks


【解决方案1】:

我之前在使用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>

【讨论】:

  • 如果我使用if (loading &amp;&amp; !data.myData) return &lt;div&gt;Loading&lt;/div&gt;;,我仍然会遇到同样的问题。似乎data 每次重新获取时都会重置为{}
  • 是的数据被重置为{} ...所以我上面的解决方案是使用useState钩子在本地缓存它。仅当数据 isnt {}. 时才更新该本地缓存
  • 我最终制作了一个自定义钩子来处理它,给你gist.github.com/jedrichards/c02af3496f4e304b720a9624db647dfb
  • 哇...哦,太好了
猜你喜欢
  • 2019-11-09
  • 2021-03-07
  • 2019-01-19
  • 2020-02-18
  • 2018-06-05
  • 2023-03-09
  • 2019-10-06
  • 2017-08-30
相关资源
最近更新 更多