问题描述
我正在使用react useEffect
钩子,并检查对象是否已更改,然后才再次运行该钩子.
I am using react useEffect
hooks and checking if an object has changed and only then run the hook again.
我的代码如下.
const useExample = (apiOptions) => {
const [data, updateData] = useState([]);
useEffect(() => {
const [data, updateData] = useState<any>([]);
doSomethingCool(apiOptions).then(res => {
updateData(response.data);
})
}, [apiOptions]);
return {
data
};
};
不幸的是,由于无法识别出相同的对象,它一直在运行.
Unfortunately it keeps running as the objects are not being recognised as being the same.
我相信以下是一个示例.
I believe the following is an example of why.
const objA = {
method: 'GET'
}
const objB = {
method: 'GET'
}
console.log(objA === objB)
也许运行 JSON.stringify(apiOptions)
可行吗?
推荐答案
使用 apiOptions
作为状态值
我不确定您如何使用自定义钩子,但是通过使用 useState
将 apiOptions
设置为状态值应该可以正常工作.这样,您可以将其作为状态值提供给自定义钩子,如下所示:
Use apiOptions
as state value
I'm not sure how you are consuming the custom hook but making apiOptions
a state value by using useState
should work just fine. This way you can serve it to your custom hook as a state value like so:
const [apiOptions, setApiOptions] = useState({ a: 1 })
const { data } = useExample(apiOptions)
这样,仅当您使用 setApiOptions
时,它才会更改.
This way it's going to change only when you use setApiOptions
.
示例1
import { useState, useEffect } from 'react';
const useExample = (apiOptions) => {
const [data, updateData] = useState([]);
useEffect(() => {
console.log('effect triggered')
}, [apiOptions]);
return {
data
};
}
export default function App() {
const [apiOptions, setApiOptions] = useState({ a: 1 })
const { data } = useExample(apiOptions);
const [somethingElse, setSomethingElse] = useState('default state')
return <div>
<button onClick={() => { setApiOptions({ a: 1 }) }}>change apiOptions</button>
<button onClick={() => { setSomethingElse('state') }}>
change something else to force rerender
</button>
</div>;
}
您可以按照此处:
function deepCompareEquals(a, b){
// TODO: implement deep comparison here
// something like lodash
// return _.isEqual(a, b);
}
function useDeepCompareMemoize(value) {
const ref = useRef()
// it can be done by using useMemo as well
// but useRef is rather cleaner and easier
if (!deepCompareEquals(value, ref.current)) {
ref.current = value
}
return ref.current
}
function useDeepCompareEffect(callback, dependencies) {
useEffect(
callback,
dependencies.map(useDeepCompareMemoize)
)
}
您可以像使用 useEffect
一样使用它.
You can use it like you'd use useEffect
.
这篇关于反应useEffect比较对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!