繁体   English   中英

React Apollo:未捕获(承诺)类型错误:无法读取未定义的属性“重新获取”

[英]React Apollo: Uncaught (in promise) TypeError: Cannot read property 'refetch' of undefined

我有一个函数,它有一些承诺链正在进行,但这不是重点。

当我运行某个突变的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'],
            });
        },
    }),
}),

我什至尝试过将其重写为使用 async/await,但问题仍然发生:

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);
}

老实说,我不知道发生了什么或者为什么 refetch 不起作用。 重构为钩子有帮助吗? 有谁有想法吗?

文档

config.props 属性允许你定义一个 map 函数,它接受由graphql()函数添加的道具......( props.data用于查询, props.mutate用于突变)并允许你计算新的道具......将提供给graphql()包装的组件的对象。

要访问不是由graphql()函数添加的道具,请使用ownProps关键字。

通过使用props函数,你告诉 HOC 哪些 props 传递给下一个 HOC 或组件本身。 如果你不将已经传递给它的 props 包含在你返回的 props 中,它不会被传递给组件。 你需要为每个props函数做这样的事情:

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

编写 HOC 是一件痛苦的graphql无论如何, graphql HOC 都被弃用了,取而代之的是 hooks。 我强烈建议迁移到 hooks API。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM