使用扩展运算符从 API 操作/过滤对象的道具

Posted

技术标签:

【中文标题】使用扩展运算符从 API 操作/过滤对象的道具【英文标题】:manipulating/filtering objects' props from an API with spread operator 【发布时间】:2021-07-16 00:16:38 【问题描述】:

在做一个 React/Next 课程时,有一刻我们必须获取一个返回对象列表的 API,其中包含填充页面的数据。

它是在 Next 的 getStaticProps 上完成的,并作为 props 传递给前端,操纵一些数据以最适合,并忽略一些数据。 但是要传入一堆未被触及的 os 道具,需要额外输入:

data.map(episode=>
    return 
      id: episode.id,
      title: episode.title,
      thumbnail: episode.thumbnail,
      members: episode.title,
      description: episode.description,
      url: episode.file.url,

      publishedAt: format( parseISO(episode.published_at), 'd MMM yy', locale: ptBR  ),
      duration: Number(episode.file.duration),
      durationAsString: convertDurationToTimeString( Number(episode.file.duration) ),
    ;
)

所以我想使用 JS 的扩展操作来使这段代码更短,并且更少的单词饿。 但我担心这种方法会对性能、可读性、代码可维护性/测试以及所有这些事情产生任何影响。 因为这看起来并不难,所以如果老师不这样做,我可能有问题吧?!

所以请看一下这段代码,如果确实是一个更好的解决方案,那里面就有问题:

const episodes = data.map(episode=>
    const 
      file,
      published_at: publishedAt,
      ...rest

     = episode;

    return 
      ...rest,
      url: file.url,
      duration: Number(file.duration),
      publishedAt: format( parseISO(publishedAt), 'd MMM yy', locale: ptBR  ),
      durationAsString: convertDurationToTimeString( Number(file.duration) ),
    



如果它有助于理解它的含义,这里是使用 line cmets:

const episodes = data.map(episode=>

    // filter out the data
    const 
      // attrs to remove from final
      file,

      // . to rename
      published_at: publishedAt,

      // to keep as is
      ...rest

     = episode;

    // threat/manipulate and add data
    return 
      ...rest,
      url: file.url,
      duration: Number(file.duration),
      publishedAt: format( parseISO(publishedAt), 'd MMM yy', locale: ptBR  ),
      durationAsString: convertDurationToTimeString( Number(file.duration) ),
    


【问题讨论】:

【参考方案1】:
const episodes = data.map(( file, published_at: publishedAt, ...rest ) => (
  ...rest,
  url: file.url,
  duration: Number(file.duration),
  publishedAt: format(parseISO(publishedAt), 'd MMM yy',  locale: ptBR ),
  durationAsString: convertDurationToTimeString(Number(file.duration)),
));

这是我可以建议的最简洁的方法,但您自己的代码足够可读,据我所知,传播对象没有性能成本。

【讨论】:

You returned publishedAt at the end which results in having both publishedAt and published_at 为什么两者都有? ...rest 中没有 published_at 好的,我明白你在论点上直接解构的观点,以及箭头函数的“直接”返回。确实需要更少的打字。我选择将它分开,以便一目了然。所以最终的方法是一样的。 其实我做了,做了一点console.Time测试。传播似乎有一些微小的惩罚:没有传播:纱线开始时:4.384ms、3.789ms、5.31ms 页面重新加载:1.147ms、1.212ms、1.175ms 传播:纱线开始时:4.869ms、7.21ms、5.951ms页面重载:2.325ms、1.633ms、1.771ms【参考方案2】:

还有一点需要注意的是,如果您只想返回第一个示例中列出的 9 个属性,那么如果 episode 有更多属性(起初您将它们分散到 @ 987654322@ 然后用...rest 解构回来)。但如果是故意的,那么这种做事方式是完全可以的。

【讨论】:

我不确定我是否理解。我以这些为例,但考虑一个更通用的情况:获取 API 响应;传递一些,而不是全部;重命名摔倒;操作所需的任何数据。 .这些操作或对象没有具体数量。 假设episode 具有rating 属性,并且您不想将其传递给前端。第一个示例不会保留它,并且将在没有它的情况下返回新对象。您的第二个示例将保留它,最后您将获得具有 rating 属性的对象。 嗯,我的想法是明确删除和重命名,并以隐含的方式保持不变。因为在这种情况下,“不碰”占多数。第一个肯定更适合拿几个。

以上是关于使用扩展运算符从 API 操作/过滤对象的道具的主要内容,如果未能解决你的问题,请参考以下文章

使用 ES6 扩展运算符反应道具语法 [重复]

React 扩展运算符未知的支柱警告

对象扩展符号变换如何反应 redux 道具?

使用扩展运算符从 ES6 中的对象中删除目标参数

如何使用 Typescript 扩展 Material-UI 组件的道具?

在过滤器数组上使用扩展运算符创建 Firestore 查询