首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有UseEffect自定义钩子的无限循环

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

Stack Overflow用户
提问于 2019-09-23 20:24:02
回答 1查看 194关注 0票数 0

我正在尝试创建一个自定义钩子,而无限循环有问题。

在我的页面上有实现自定义钩子的代码:

代码语言:javascript
复制
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'
  })

这是我的定制钩子:

代码语言:javascript
复制
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
}

这样,useEffect就会一次又一次地发布,而不是将params考虑在内。我为params添加了一个console.log,并且总是收到相同的消息。

我在没有自定义钩子的情况下正确地使用了这个useCase,所以这不是问题。

我希望使用这个自定义钩子来避免在所有项目页面的所有UseEffects上复制和粘贴重定向。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-23 20:38:18

问题在于对象引用,这意味着您要将{nameToFilter: nameFilter, page}作为params传递,但是每次组件呈现一个新的对象引用时,都要与===进行比较,因此如果您在控制台中运行此代码

代码语言:javascript
复制
var params1 = { name: 'mike', age: 29 };
var params2 = { name: 'mike', age: 29 };
console.log(params1 === params2); // it will console false

这是因为当对象的键/值对相同时,对象声明不是相同的事件。

因此,为了避免无限循环进入钩子,您应该使用useMemo来避免这种情况,因此尝试如下

代码语言:javascript
复制
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将避免在组件的每个呈现阶段重新创建对象刷新

请阅读useMemo对官方文件作出反应

请阅读此帖子以了解值与参考值比较之间的差异。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58069712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档