React Apollo:未捕获(承诺中)TypeError:无法读取未定义的属性'refetch'

问题描述 投票:0回答:1

我有一个正在运行一个promise链的函数,但这不重要。

[当我运行某个突变的refetch时,它给了我Uncaught (in promise) TypeError: Cannot read property 'refetch' of undefined

奇怪的是,如果我删除了一个突变,它将起作用。所以这是代码:

Promise.all(this.props.questionnaireData.map(({ kind, id }): Promise<any> => {
    const responses = this.props.formData[kind];
    return this.props.updateQuestionnaire(id, responses);
})).then(() => {
    this.props.finishAssessment(this.props.assessmentId)
        .then(() => {
            track('Assessment -- Finished', {
                'Assessment Kind' : this.props.assessmentKind,
                'Assessment Id'   : this.props.assessmentId,
            });
            if (this.props.assessmentKind === 'INITIAL_ASSESSMENT') {
                this.props.getCompletedInitialAssessment.refetch().then(() => {
                    Router.replace(routes.LoadingAssessmentResults.to, routes.LoadingAssessmentResults.as);
                });

                this.submitEmailNotifications();
            } else if(this.props.assessmentKind === 'GOAL_CHECK_IN') {
                Router.replace(routes.MemberProgressDashboard.to, routes.MemberProgressDashboard.as);
            } else {
                Router.replace(routes.MemberDashboard.to, routes.MemberDashboard.as);
            }
        });
});

错误发生在this.props.getCompletedInitialAssessment.refetch(),我不知道为什么。但是,当我删除this.props.finishAssessment(this.props.assessmentId)时,仅重新引用将起作用。

基本上:

Promise.all(this.props.questionnaireData.map(({ kind, id }): Promise<any> => {
    const responses = this.props.formData[kind];
    return this.props.updateQuestionnaire(id, responses);
})).then(() => {
        track('Assessment -- Finished', {
            'Assessment Kind' : this.props.assessmentKind,
            'Assessment Id'   : this.props.assessmentId,
        });
        if (this.props.assessmentKind === 'INITIAL_ASSESSMENT') {
            this.props.getCompletedInitialAssessment.refetch().then(() => {
            Router.replace(routes.LoadingAssessmentResults.to, routes.LoadingAssessmentResults.as);
            });

            this.submitEmailNotifications();
        } else if(this.props.assessmentKind === 'GOAL_CHECK_IN') {
            Router.replace(routes.MemberProgressDashboard.to, routes.MemberProgressDashboard.as);
        } else {
            Router.replace(routes.MemberDashboard.to, routes.MemberDashboard.as);
        }
});

将使重新引用工作。否则,它会抱怨它不知道什么是refetch。

对于Apollo,我正在使用graphql HOC,它看起来像这样:

graphql(getCompletedInitialAssessment, {
    name    : 'getCompletedInitialAssessment',
    options : { variables: { status: ['Finished'], limit: 1 } },
}),
graphql(updateQuestionnaire, {
    props: ({ mutate }) => ({
        updateQuestionnaire: (id, responses) => {
            let normalized = {};

                for (let res in responses) {
                    let num = +responses[res];
                    // If the value is a stringified numuber, turn it into a num
                    // otherwise, keep it a string.
                    normalized[res] = Number.isNaN(num) ? responses[res] : num;
                }

                const input = {
                    id,
                    patch: { responses: JSON.stringify(normalized) },
                };

                return mutate({
                    variables: { input },
                });
            },
        }),
    }),
graphql(finishAssessment, {
    props: ({ mutate }) => ({
        finishAssessment: (id) => {
            const input = { id };

            return mutate({
                variables      : { input },
                refetchQueries : ['getMemberInfo'],
            });
        },
    }),
}),

我尝试过的甚至重写了它以使用异步/等待,但是问题仍然发生:

try {
    await Promise.all(this.props.questionnaireData.map(({ kind, id }): Promise<any> => {
        const responses = this.props.formData[kind];
        return this.props.updateQuestionnaire(id, responses);
    }));
    const finishAssessmentRes = await this.props.finishAssessment(this.props.assessmentId);
    console.log(finishAssessmentRes)

    if (this.props.assessmentKind === 'INITIAL_ASSESSMENT') {
        const res = await this.props.getCompletedInitialAssessment.refetch();
        console.log(res);
        this.submitEmailNotifications();
        Router.replace(routes.LoadingAssessmentResults.to, routes.LoadingAssessmentResults.as);
    } else if(this.props.assessmentKind === 'GOAL_CHECK_IN') {
        Router.replace(routes.MemberProgressDashboard.to, routes.MemberProgressDashboard.as);
    } else {
        Router.replace(routes.MemberDashboard.to, routes.MemberDashboard.as);
    }
} catch (error) {
    console.error(error);
}

老实说,我不知道发生了什么或为什么重新引用不起作用。重构成钩子会有帮助吗?有人知道吗?

javascript reactjs graphql react-apollo
1个回答
0
投票

来自the docs

config.props属性允许您定义一个映射函数,该函数接受由graphql()函数(用于查询的props.data和用于变异的props.mutate)添加的props ...,并允许您计算新的props。 ..对象将提供给graphql()包装的组件的对象

要访问graphql()功能未添加的道具,请使用ownProps关键字。

通过使用props函数,您告诉HOC哪些道具向下传递到下一个HOC或组件本身。如果您在道具内部返回的物品中不包含已经传递给它的道具,则不会将其传递给组件。您需要对每个props函数执行以下操作:

props: ({ mutate, ownProps }) => ({
  finishAssessment: (id) => {
    //
  },
  ...ownProps,
}),

组成HOC令人痛苦,并且无论如何都赞成使用钩子,graphql HOC被弃用了。我强烈建议迁移到hooks API。

© www.soinside.com 2019 - 2024. All rights reserved.