简体   繁体   中英

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

Doing a React/Next course, in a momment we had to fetch an API returning a list of objects, with data to fill the page.

It is done on Next's getStaticProps, and passed to frontend as props, manipulating some of the data to best fit, and ignoring some too. But to pass in a bunch os props that was not touched, required some extra typing:

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

So i though of using JS's spread operation to make this code short, and less words hungry. But i'm afraid of this aproach having any impact on performance, readability, code maintainability / test, all of those things. Cause it doen't look a hard thing to come up with, so if the teacher didn'd do it, i may have some problem right?!

So please, take a look at this code, and say if is indeed a better solution, there's a problem in there:

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


Here it is with line comments if it helps unsderstant what it means:

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

This is the cleanest way I can suggest but your own code was readable enough and there is no performance cost in spreading objects as far as I know.

One more thing to note is that if you only want to return 9 properties that were listed in your first example, then your second example might not work that way if episode has more properties (at first you spread them into ...rest and then destructure back with ...rest ). But if it is intentional then this way of doing things is totally fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM