Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs TypeScript React/MobX“;“重新渲染过多”;关于组件禁用回调_Reactjs_Typescript_React Hooks_Mobx_Mobx React - Fatal编程技术网

Reactjs TypeScript React/MobX“;“重新渲染过多”;关于组件禁用回调

Reactjs TypeScript React/MobX“;“重新渲染过多”;关于组件禁用回调,reactjs,typescript,react-hooks,mobx,mobx-react,Reactjs,Typescript,React Hooks,Mobx,Mobx React,我有一个submit按钮,它是一个依赖于以下计算MobX函数的表单 @computed isSurveySubmitEnabled=():布尔=>{ 让问题验证=[]; 开关(此.surveyType){ “预先”一案:{ 问题验证=调查前的问题; } “事后调查”案例:{ 问题验证=调查后问题; } 案例“后测试”:{ 问题验证=测试后问题; } } 运行不活动(()=>{ this.isValidated=true; }); 问题验证。forEach((qObj:any)=>{ qObj.v

我有一个submit按钮,它是一个依赖于以下计算MobX函数的表单

@computed
isSurveySubmitEnabled=():布尔=>{
让问题验证=[];
开关(此.surveyType){
“预先”一案:{
问题验证=调查前的问题;
}
“事后调查”案例:{
问题验证=调查后问题;
}
案例“后测试”:{
问题验证=测试后问题;
}
}
运行不活动(()=>{
this.isValidated=true;
});
问题验证。forEach((qObj:any)=>{
qObj.value.forEach((qVal:any)=>{
如果(qVal.type==“日期”){
if(!this.entryPostParams[qVal.entrydyear]){
运行不活动(()=>{
this.isValidated=false;
});
}
}否则{
如果(!this.entryPostParams[qVal.entryId]){
运行不活动(()=>{
this.isValidated=false;
});
}
}
});
});
返回此文件。已验证;
};
回调在按钮上的
disabled
属性中使用,如下所示

 <Button disabled={!isSurveySubmitEnabled()} style={{ marginTop: '5%' }} onClick={() => { doSubmitForm(); incrementActivityIndex() }}>Submit</Button>

根据堆栈跟踪,不清楚问题出在哪里。这个回调不应该只在可观察对象发生更改时执行吗?

不建议在计算getter中运行操作,这可能是导致太多重渲染器的原因。每个runInAction都有可能导致观察器的重新触发,显然,当计算getter的基础观察器发生更改时,计算值本身也可能发生更改。也就是说,使用所述计算值的观察者还必须被通知有变化并重新触发。你可以在这里看到无限循环的潜力

您还应该收集更改的可观察对象,并尝试通过一个操作将所有更改推送到一个批次中,以最小化重新提交。mobx中最外层的操作决定事务是否结束以及观察者是否得到更新。这意味着动作中的动作不会单独通知观察者,但计算的getter不是动作。在您的案例中单独运行的每个runInAction都会引起一个反应


TL;DR:不要在计算getter中运行操作,也不要在runInAction上循环。

这是否意味着在计算getter中不应该更改可观察的对象?我之前尝试过的一件事是将作用域仅验证到该函数,但计算结果仅在第一次渲染时运行,尽管entryPostParams是可观察的。计算getter的要点是它们缓存结果。从概念上讲,它们是自己可以观察到的。您只需计算isValidated,而无需保存它,就可以完成它。仅当entryPostParams或surveyType发生更改时,才会重新计算它。我不知道这对于您的情况是否足够,但是类似这样的方法应该是计算getter的方法。是的,最理想的情况是,您不会更改计算getter中的观察值。即使删除操作,计算结果也似乎只在组件加载时运行,而且我确信entryPostParams正在更改。这和我在这个上下文中观察entryPostParams有什么关系吗?如果你能给我一个stackblitz url或一个最小的repo,我可以帮你调试它。
The above error occurred in the <GoogleForm> component:
    in GoogleForm (at PageContent.tsx:32)
    in PageContent (at Continue.tsx:52)
    in Continue (at App.tsx:12)
    in Route (at App.tsx:12)
    in App (created by Context.Consumer)
    in withRouter(App) (at src/index.tsx:12)
    in Router (at src/index.tsx:11)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit [url] to learn more about error boundaries.
console.<computed> @ index.js:1
Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
    at renderWithHooks (react-dom.development.js:14815)
    at updateFunctionComponent (react-dom.development.js:17034)
    at updateSimpleMemoComponent (react-dom.development.js:16972)
    at beginWork (react-dom.development.js:18687)
    at HTMLUnknownElement.callCallback (react-dom.development.js:188)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
    at invokeGuardedCallback (react-dom.development.js:292)
    at beginWork$1 (react-dom.development.js:23203)
    at performUnitOfWork (react-dom.development.js:22154)
    at workLoopSync (react-dom.development.js:22130)
    at performSyncWorkOnRoot (react-dom.development.js:21756)
    at react-dom.development.js:11089
    at unstable_runWithPriority (scheduler.development.js:653)
    at runWithPriority$1 (react-dom.development.js:11039)
    at flushSyncCallbackQueueImpl (react-dom.development.js:11084)
    at flushSyncCallbackQueue (react-dom.development.js:11072)
    at flushPassiveEffectsImpl (react-dom.development.js:22883)
    at unstable_runWithPriority (scheduler.development.js:653)
    at runWithPriority$1 (react-dom.development.js:11039)
    at flushPassiveEffects (react-dom.development.js:22820)
    at react-dom.development.js:22699
    at workLoop (scheduler.development.js:597)
    at flushWork (scheduler.development.js:552)
    at MessagePort.performWorkUntilDeadline (scheduler.development.js:164)