使用Apollo客户端fetchMore Apollo客户端多次触发相同的查询并追加数据

时间:2020-11-05 16:07:42

标签: reactjs graphql react-apollo apollo-client

我将类组件转换为功能组件以使用React Hooks。 graphQl查询的调用方式如下:

const { data, error, loading, fetchMore } = useQuery(getAll, {
            variables: { 
                code: props.code,
                type: props.type,
                page: 0 
            }
        });
我正在寻找

fetchMore函数。我检查了几个教程,它们都在 onClick 触发器上实现了fetchMore功能。

我的问题是:

是否可以在不触发事件的情况下调用fetchMore?以便在设置变量时有条件地调用它?

更新1

根据建议,我尝试使用useEffect钩子。这是代码:

useEffect(() => {
        if(data != null) {
            const { nextLink } = data.list.nextLink;

            if(nextLink !== []){
                fetchMore({
                    variables: { 
                        code: props.code,
                        type: props.type,
                        page: page+1  
                    },
                    updateQuery: (prevResult, { fetchMoreResult }) => {
                      fetchMoreResult.list = [
                        ...prevResult.list,
                        ...fetchMoreResult.list
                      ];
                      return fetchMoreResult;
                    }
                });
            }
        }
    });

但是它只调用一次查询。如何在 nextLink 不为空之前多次触发该查询?然后更新结果?

更新2

完成一些工作后,我可以调用所有页面并获取数据。这就是我所做的。

我在后端查询中添加了 page 字段,该字段用作变量来回传递给查询调用。此外,此页面变量在每次调用时都会增加。另外,仅当 nextLink 为空时才调用fetchmore函数。但是,当前页面仅显示最后一页结果,因为新结果将替换旧数据。

代码如下:

let [hasNext, setHasNext] = useState(true);
    useEffect(() => {
            if(data != null) {
                const { nextLink, page } = data.list;
                let isNext = (nextLink !== "") ? true : false;
                setHasNext(isNext);
    
                if(hasNext){
                    const { data } = fetchMore({
                        variables: { 
                            code: props.code,
                            type: props.type,
                            page: parseInt(page)
                        },
                        updateQuery: (prevResult, { fetchMoreResult }) => {
                            fetchMoreResult = {
                                ...prevResult,
                                ...fetchMoreResult,
                            };
                            return fetchMoreResult;
                        }
                    });
                }
            }
        });

扩展运算符似乎不起作用。如何将获取的新数据附加到旧结果中?

1 个答案:

答案 0 :(得分:1)

经过一些尝试,这是我的解决方案。如评论中所建议,要多次触发相同的查询,我应该在fetchMore挂钩内使用useEffect

代码如下:

useEffect(() => {
        if(data != null) {
            if(data.list !== []){
                const { nextLink, page } = data.list;
                let isNext = (nextLink !== "") ? true : false;
                setHasNext(isNext);

                if(hasNext && page != null){
                    const { data } = fetchMore({
                        variables: { 
                            code: props.code,
                            type: props.type,
                            page: page
                        },
                        updateQuery: (prev, { fetchMoreResult }) => {
                            if (!fetchMoreResult) {
                                return prev;
                            }
                            return {
                                list: {
                                    ...prev.list,
                                    ...fetchMoreResult.list,
                                    array: [
                                        ...prev.list.array,
                                        ...fetchMoreResult.list.array,
                                    ],
                                },
                            };
                        }
                    });
                } else {
                    setLoadingState(false);
                }
            }
        }
    });

graphQL查询如下:

query($code: String, $type: Int, $page: Int) {
    list(code: $code, type: $type, page: $page) {
        array {
            ID
            title
            field_firstname
            field_lastname
        }
        nextLink
        page
    }
}