Home > Mobile >  Combine two switch/case statements in React component
Combine two switch/case statements in React component

Time:03-26

I am creating a (SocialLink) React component and wondering if this is the best / clean approach.

const SocialLink = ({ url, type, title }: Props) => {

  const renderIcon = () => {
    let icon;

    switch (type) {
      case 'email':
        icon = <EmailIcon />;
        break;
      case 'twitter':
        icon = <TwitterIcon />;
        break;
      case 'facebook':
        icon = <FacebookIcon />;
        break;
      case 'whatsapp':
        icon = <WhatsAppIcon />;
        break;
      default:
    }
    return icon;
  };

  const renderUrl = () => {
    let socialUrl;

    switch (type) {
      case 'email':
        socialUrl = `mailto:?subject=${title} &body=${url}`;
        break;
      case 'twitter':
        socialUrl = `https://twitter.com/share?text=${title}&url=${url}`;
        break;
      case 'facebook':
        socialUrl = `http://www.facebook.com/sharer.php?u=${url}&t=${title}`;
        break;
      case 'whatsapp':
        socialUrl = `whatsapp://send?text=${title}  ${url}`;
        break;
      default:
    }
    return socialUrl;
  };

  return (
    <a href={renderUrl()} target="_blank" rel="noopener noreferrer" title={title}>
      {renderIcon}
    </a>
  );
};

As you can see I have two switch/case statements. Is there somehow a smart way to combine those into one?

CodePudding user response:

How about:

const SocialLink = ({ url, type, title }: Props) => {
  let icon;
  let socialUrl;
  switch (type) {
    case 'email':
      icon = <EmailIcon />
      socialUrl = `mailto:?subject=${title} &body=${url}`;
      break;
    case 'twitter':
      // etc
  }

  return (
    <a href={socialUrl} /* ... */>
      {icon}
    </a>
  )
}

CodePudding user response:

I think we can define a constant value because this could be a static one. It will be more readable and maintainable.

const socialLinks = {
    email: {
        icon: <EmailIcon />,
        socialUrl: `mailto:?subject=${title} &body=${url}` 
    },
    twitter: {
        icon: <TwitterIcon />,
        socialUrl: `https://twitter.com/share?text=${title}&url=${url}`
    },
    ....
};

const SocialLink = ({ url, type, title }: Props) => {
  return (
    <a href={socialLinks[type].socialUrl} target="_blank" rel="noopener noreferrer" title={title}>
      {socialLinks[type].icon}
    </a>
  );
};

CodePudding user response:

What do you think about this approach ?

of course the data variable can be imported from a CONSTANTS folder or something, this way everything will be clear

const data = {
  email: {
    icon: <EmailIcon />,
    socialUrl: (title, url) => {
      return `mailto:?subject=${title} &body=${url}`;
    }
  },
  twitter: {
    icon: <TwitterIcon />,
    socialUrl: (title, url) => {
      return `https://twitter.com/share?text=${title}&url=${url}`;
    }
  },
  facebook: {
    icon: <FacebookIcon />,
    socialUrl: (title, url) => {
      return `http://www.facebook.com/sharer.php?u=${url}&t=${title}`;
    }
  },
  whatsapp: {
    icon: <WhatsAppIcon />,
    socialUrl: (title, url) => {
      return `whatsapp://send?text=${title}  ${url}`;
    }
  }
};

export const SocialLink = ({ url, type, title }) => {
  return (
    <a
      href={data[type].socialUrl(title, url)}
      target="_blank"
      rel="noopener noreferrer"
      title={title}
    >
      {data[type].icon}
    </a>
  );
};
  • Related