简体   繁体   English

用于 API 功能的 useEffect 或 useMemo?

[英]useEffect or useMemo for API functions?

which is the best hook for dispatching API calls in a component.这是在组件中调度 API 调用的最佳挂钩。 Usually I use useMemo for calling the API on the first render, and useEffect if I need extra side effects, is this correct?通常我在第一次渲染时使用 useMemo 来调用 API,如果我需要额外的副作用,则使用 useEffect,这是正确的吗? Becouse sometimes I get the following error:因为有时我会收到以下错误:

'''index.js:1 Warning: Cannot update a component ( Inscriptions ) while rendering a different component ( PaySummary ). '''index.js:1 警告:在渲染不同的组件( PaySummary )时无法更新组件( Inscriptions )。 To locate the bad setState() call inside PaySummary , follow the stack trace as described in...''''要在PaySummary中找到错误的 setState() 调用,请按照...''''中所述的堆栈跟踪

That happens when I route to a component and rapidly change to another one, it doesn't "affect" the general behaivour becouse if i go back to the previous component it renders as expected correctly.当我路由到一个组件并快速更改到另一个组件时会发生这种情况,它不会“影响”一般行为,因为如果我 go 回到它按预期正确呈现的前一个组件。 So how should I do it?那么我该怎么做呢?

Calling an API is a side effect and you should be using useEffect , not useMemo调用 API 是一个副作用,你应该使用useEffect ,而不是useMemo

Per the React docs for useEffect :根据useEffect的 React 文档

Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects.在 React 组件中获取数据、设置订阅和手动更改 DOM 都是副作用的示例。 Whether or not you're used to calling these operations “side effects” (or just “effects”), you've likely performed them in your components before.无论您是否习惯将这些操作称为“副作用”(或仅称为“效果”),您之前都可能在组件中执行过它们。

Per the React docs for useMemo :根据useMemo的 React 文档

Remember that the function passed to useMemo runs during rendering.请记住,传递给 useMemo 的 function 在渲染期间运行。 Don't do anything there that you wouldn't normally do while rendering.不要在那里做任何你在渲染时通常不会做的事情。 For example, side effects belong in useEffect, not useMemo.例如,副作用属于 useEffect,而不是 useMemo。

Performing those side effects (and modifying state) during rendering or with useMemo is the reason you encounter the errors you mention.在渲染期间或使用useMemo执行这些副作用(和修改状态)是您遇到您提到的错误的原因。

basically I rather to use useEffect in componentDidMount manner, with no dependency like below基本上我宁愿以componentDidMount方式使用useEffect ,没有像下面这样的依赖


useEffect(() => {

  // Api call , or redux async action here...

}, [])

for calling api's at component mount state.用于在组件安装 state 处调用 api。 most of the time i find my self using useMemo for memoising the data at functional Component render level, for preventing the variable re-creation and persist the created data between renders except the dependency changes.大多数时候,我发现自己使用useMemo在功能组件渲染级别存储数据,以防止变量重新创建并在渲染之间保留创建的数据,但依赖项更改除外。

but for the context of your question, there is a hook called useLayoutEffect which is primarily used for actions to happen before painting the DOM, but as i said basically most of the time in projects i find calling apis in a simple useEffect with no dependencies aka, the did mount of your component, in order to load the required data for component!但是对于您的问题的上下文,有一个名为useLayoutEffect的钩子,它主要用于在绘制 DOM 之前发生的操作,但正如我所说的,基本上大部分时间在项目中我发现在没有依赖关系的简单useEffect中调用 apis ,你的组件的确实挂载,以便加载组件所需的数据!

A bit late but, while everything mentioned above is completely true;有点晚了,虽然上面提到的一切都是真的; the error错误

'''index.js:1 Warning: Cannot update a component (Inscriptions) while rendering a different component (PaySummary). '''index.js:1 警告:在渲染不同的组件(PaySummary)时无法更新组件(Inscriptions)。 To locate the bad setState() call inside PaySummary, follow the stack trace as described in...''''要在 PaySummary 中找到错误的 setState() 调用,请按照...''''中所述的堆栈跟踪

Has to do with the fact that the API call is Asynchronous and when you rapidly change the pages, the set state call (for updating the data returned from the API call I assume) is still waiting to be called after the data is returned from the API.与以下事实有关API。 So, you have to always clean up your Async functions in useEffect to avoid this error.因此,您必须始终清理 useEffect 中的 Async 函数以避免此错误。

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

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