manipulating/filtering 对象的道具来自 API 带有展开运算符

manipulating/filtering objects' props from an API with spread operator

在做 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 的扩展操作来使这段代码更短,并且减少字数。 但我担心这种方法会对性能、可读性、代码可维护性/测试以及所有这些os 产生任何影响。 因为这看起来并不难想出,所以如果老师不这样做,我可能会遇到一些问题吧?!

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

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


这里有行注释,如果它有助于理解它的意思:

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

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

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

还有一点要注意,如果您只想 return 第一个示例中列出的 9 个属性,那么如果 episode 有更多属性,那么您的第二个示例可能无法正常工作(首先你将它们散布到 ...rest 中,然后用 ...rest 解构回来)。但如果是故意的,那么这种做法完全没问题。