是否有一个默认函数可以用来与 React.memo 进行比较?

发布于 2025-01-10 03:58:03 字数 2240 浏览 2 评论 0原文

我有一个 组件,它有一个对象作为道具;就像

const myData = {
   "location"      : ["http://example.com/1.ogg", "http://example.com/2.mp3"],
   "identifier"    : ["http://example.com/1/", "http://example.com/2/"],
   "title"         : "Track title",
   "creator"       : "Artist name",
   "annotation"    : "Some text",
   "info"          : "http://example.com/",
   "image"         : "http://example.com/",
   "album"         : "Album name",
   "trackNum"      : 1,
   "duration"      : 0,
   "link"          : [
     {"http://example.com/rel/1/" : "http://example.com/body/1/"},
     {"http://example.com/rel/2/" : "http://example.com/body/2/"}
   ],
   "meta"          : [
     {"http://example.com/rel/1/" : "my meta 14"},
     {"http://example.com/rel/2/" : "345"}
   ],
   "extension"     : {
     "http://example.com/app/1/" : [ARBITRARY_EXTENSION_BODY, ARBITRARY_EXTENSION_BODY],
     "http://example.com/app/2/" : [ARBITRARY_EXTENSION_BODY]
   }
 }

时使用的

<Track track={myData} onClick={handleClick}/>

在当我更新 myData

那样,我创建了一个新对象,这使得 React 重新渲染我的组件,即使它的 props 具有相同的值。我查看了 React.memo,它可以帮助避免使用自定义函数重新渲染,例如

export default React.memo(Track,isEqualTrack);

我将 JSON.stringify() 来检查我的数据equal :

function isEqualProp(key,prev,next){
  switch(key){
    case 'track':
      return (JSON.stringify(prev)===JSON.stringify(next))
    break;
  }
}

function isEqualTrack(prevTrackProps, nextTrackProps) {

  const props = Object.keys(nextTrackProps);

  //find the first prop that has changed
  const changedProp = props.find(function(prop){
    const prevValue = prevTrackProps[prop];
    const nextValue = nextTrackProps[prop];
    return !isEqualProp(prop,prevValue,nextValue);
  })

  if (changedProp){
    return false;
  }

  return true;

}

但我需要一个默认函数来比较我不想进行特殊检查的道具。

function isEqualProp(key,prev,next){
  switch(key){
    case 'track':
      return (JSON.stringify(prev)===JSON.stringify(next))
    break;
    default:
      //I NEED A DEFAULT FUNCTION HERE
  }
}

那存在吗? 或者您有其他解决方案来不重新渲染我的组件吗? 如您所见,数据是嵌套的,因此我无法将其拆分为几个“简单”道具。

非常感谢!

I have a <Track/> component that have an object as prop; like

const myData = {
   "location"      : ["http://example.com/1.ogg", "http://example.com/2.mp3"],
   "identifier"    : ["http://example.com/1/", "http://example.com/2/"],
   "title"         : "Track title",
   "creator"       : "Artist name",
   "annotation"    : "Some text",
   "info"          : "http://example.com/",
   "image"         : "http://example.com/",
   "album"         : "Album name",
   "trackNum"      : 1,
   "duration"      : 0,
   "link"          : [
     {"http://example.com/rel/1/" : "http://example.com/body/1/"},
     {"http://example.com/rel/2/" : "http://example.com/body/2/"}
   ],
   "meta"          : [
     {"http://example.com/rel/1/" : "my meta 14"},
     {"http://example.com/rel/2/" : "345"}
   ],
   "extension"     : {
     "http://example.com/app/1/" : [ARBITRARY_EXTENSION_BODY, ARBITRARY_EXTENSION_BODY],
     "http://example.com/app/2/" : [ARBITRARY_EXTENSION_BODY]
   }
 }

Used in

<Track track={myData} onClick={handleClick}/>

When I update myData, I create a new object, which makes React re-render my component, even if its props have equal values.

I've looked at React.memo, which could help to avoid re-rendering with a custom function, like

export default React.memo(Track,isEqualTrack);

Where I would JSON.stringify() to check my data for equality :

function isEqualProp(key,prev,next){
  switch(key){
    case 'track':
      return (JSON.stringify(prev)===JSON.stringify(next))
    break;
  }
}

function isEqualTrack(prevTrackProps, nextTrackProps) {

  const props = Object.keys(nextTrackProps);

  //find the first prop that has changed
  const changedProp = props.find(function(prop){
    const prevValue = prevTrackProps[prop];
    const nextValue = nextTrackProps[prop];
    return !isEqualProp(prop,prevValue,nextValue);
  })

  if (changedProp){
    return false;
  }

  return true;

}

But I would need a default function to compare the props I don't want a special check on.

function isEqualProp(key,prev,next){
  switch(key){
    case 'track':
      return (JSON.stringify(prev)===JSON.stringify(next))
    break;
    default:
      //I NEED A DEFAULT FUNCTION HERE
  }
}

Does that exists ?
Or do you have another solution to not re-render my component ?
As you see, the data is nested so I can't split it into several "simple" props.

Thanjs a lot !!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ら栖息 2025-01-17 03:58:03

来自 https://reactjs.org/docs/react-api.html#reactmemo

此方法仅作为性能优化而存在。不要依赖它来“阻止”渲染,因为这可能会导致错误。

您应该使用 useMemo 来避免为 myData 对象创建新的引用。这样,react 内置的浅比较就足够了

From https://reactjs.org/docs/react-api.html#reactmemo

This method only exists as a performance optimization. Do not rely on it to “prevent” a render, as this can lead to bugs.

You should use useMemo to avoid creating a new reference for your myData object instead. That way react's built in shallow comparison would be enough

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文