简体   繁体   English

带有 UseEffect 的自定义钩子的无限循环

[英]Infinite loop with a custom hook with UseEffect

I'm trying to create a custom hook and I have problems with an infinite loop.我正在尝试创建一个自定义钩子,但我遇到了无限循环的问题。

There is the piece of code that implements the custom hook on my page:有一段代码在我的页面上实现了自定义钩子:

const handleOnFinish = response => {
    const {data} = response

    setIsLoading(false)
    setTableData(data)
    setPage(page)
  }

  const handleOnInit = () => setIsLoading(true)

  useEffectUseCaseTokenValidation({
    onFinish: handleOnFinish,
    onInit: handleOnInit,
    params: {nameToFilter: nameFilter, page},
    useCase: 'get_clients_use_case'
  })

And this is my custom hook:这是我的自定义钩子:

import {useContext, useEffect} from 'react'
import Context from '@s-ui/react-context'

const noop = () => {}

export function useEffectUseCaseTokenValidation({
  onFinish = noop,
  onInit = noop,
  params = {},
  useCase = ''
}) {
  const {domain} = useContext(Context)
  const config = domain.get('config')

  useEffect(() => {
    onInit()

    domain
      .get(useCase)
      .execute(params)
      .then(response => {
        const {error} = response

        if (error && error.message === 'INVALID_TOKEN') {
          window.location.replace(config.get('LOGIN_PAGE_URL'))
        }

        onFinish(response)
      })
  }, [params]) // eslint-disable-line
}

With this, the useEffect is released again and again, instead of taking params into account.有了这个, useEffect被一次又一次地释放,而不是考虑到 params。 I add a console.log for params and is always receiving the same.我为参数添加了一个console.log并且总是收到相同的。

I was using this useCase correctly without the custom hook, so that is not the problem.我在没有自定义钩子的情况下正确使用了这个用useCase ,所以这不是问题。

I want to use this custom hook to avoid to copy and paste the redirection on all UseEffects for all project pages.我想使用这个自定义钩子来避免在所有项目页面的所有 UseEffects 上复制和粘贴重定向。

Thank you!谢谢!

The problem is the object ref, that means that you are passing {nameToFilter: nameFilter, page} as params but each time the components renders a new object ref is creating so, react compare both with the === , so if you run this code in your console问题是 object ref,这意味着您将{nameToFilter: nameFilter, page}作为参数传递,但是每次组件呈现新的 object ref 时,都会创建这样的引用,因此请与===进行比较,所以如果您运行它控制台中的代码

var params1 = { name: 'mike', age: 29 };
var params2 = { name: 'mike', age: 29 };
console.log(params1 === params2); // it will console false

that's because object declaration are not the same event when its key/value pairs are the same.这是因为 object 声明在其键/值对相同时不是同一个事件。

So to avoid infinite loop into your hook, you should use useMemo to avoid that, so try this所以为了避免无限循环进入你的钩子,你应该使用useMemo来避免这种情况,所以试试这个

import { useMemo } from 'react';
const params = useMemo(() => ({ nameToFilter: nameFilter, page }), [nameFilter, page])

useEffectUseCaseTokenValidation({
  onFinish: handleOnFinish,
  onInit: handleOnInit,
  params: params,
  useCase: 'get_clients_use_case'
})

useMemo will avoid recreating object reft in each render phase of your component useMemo将避免在组件的每个渲染阶段重新创建 object reft

Please read the useMemo react official docs请阅读useMemo react 官方文档

Please read this post to know the differences between values VS references comparison请阅读这篇文章以了解值与参考比较之间的差异

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

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