我正在尝试创建一个自定义钩子,而无限循环有问题。
在我的页面上有实现自定义钩子的代码:
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'
})这是我的定制钩子:
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上复制和粘贴重定向。
谢谢!
发布于 2019-09-23 20:38:18
问题在于对象引用,这意味着您要将{nameToFilter: nameFilter, page}作为params传递,但是每次组件呈现一个新的对象引用时,都要与===进行比较,因此如果您在控制台中运行此代码
var params1 = { name: 'mike', age: 29 };
var params2 = { name: 'mike', age: 29 };
console.log(params1 === params2); // it will console false这是因为当对象的键/值对相同时,对象声明不是相同的事件。
因此,为了避免无限循环进入钩子,您应该使用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将避免在组件的每个呈现阶段重新创建对象刷新
请阅读此帖子以了解值与参考值比较之间的差异。
https://stackoverflow.com/questions/58069712
复制相似问题