反应 useEffect 比较对象 [英] react useEffect comparing objects

查看:71
本文介绍了反应 useEffect 比较对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 react useEffect 钩子并检查对象是否已更改,然后再次运行钩子.

我的代码看起来像这样.

const useExample = (apiOptions) =>{const [数据,更新数据] = useState([]);useEffect(() => {const [data, updateData] = useState([]);doSomethingCool(apiOptions).then(res => {更新数据(响应.数据);})}, [apiOptions]);返回 {数据};};

不幸的是,它继续运行,因为对象不被识别为相同.

我相信以下是原因的一个例子.

const objA = {方法:'获取'}常量对象B = {方法:'获取'}console.log(objA === objB)

也许运行 JSON.stringify(apiOptions) 有效?

解决方案

使用 apiOptions 作为状态值

我不确定您是如何使用自定义钩子的,但是通过使用 useState 使 apiOptions 成为状态值应该可以正常工作.通过这种方式,您可以将其作为状态值提供给您的自定义钩子,如下所示:

const [apiOptions, setApiOptions] = useState({ a: 1 })const { 数据 } = useExample(apiOptions)

这样它只会在你使用 setApiOptions 时改变.

示例 #1

import { useState, useEffect } from 'react';const useExample = (apiOptions) =>{const [数据,更新数据] = useState([]);useEffect(() => {console.log('效果触发')}, [apiOptions]);返回 {数据};}导出默认函数 App() {const [apiOptions, setApiOptions] = useState({ a: 1 })const { 数据 } = useExample(apiOptions);const [somethingElse, setSomethingElse] = useState('默认状态')返回 

<button onClick={() =>{ setApiOptions({ a: 1 }) }}>更改 apiOptions</button><button onClick={() =>{ setSomethingElse('state') }}>更改其他内容以强制重新渲染

;}

或者

您可以按照这里:

function deepCompareEquals(a, b){//TODO:在这里实现深度比较//类似于 lodash//返回 _.isEqual(a, b);}函数 useDeepCompareMemoize(value) {const ref = useRef()//也可以使用 useMemo 来完成//但 useRef 更简洁更容易如果 (!deepCompareEquals(value, ref.current)) {ref.current = 值}返回参考电流}函数 useDeepCompareEffect(回调,依赖项){使用效果(打回来,依赖关系.map(useDeepCompareMemoize))}

您可以像使用 useEffect 一样使用它.

I am using react useEffect hooks and checking if an object has changed and only then run the hook again.

My code looks like this.

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)

Perhaps running JSON.stringify(apiOptions) works?

解决方案

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)

This way it's going to change only when you use setApiOptions.

Example #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>;
}

Alternatively

You could write a deep comparable useEffect as described here:

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)
  )
}

You can use it like you'd use useEffect.

这篇关于反应 useEffect 比较对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆