Prefer duplication over code that depends on if-else
Tags: html, frontend, react, javascript
Published: 2021-07-11 09:03:48

Back in 2018, when i had just begun coding, it was during the rise of JavaScript frameworks like React, Vue, and others like them. Those frameworks redefined frontend code and development as we know of, from the days of jquery. 

One thing that stood out to me and really liked was the idea Components, the idea that you can nest some html code into a component and reuse it anywhere you liked, it stood out to me, i really liked to keep my code DRY. Not knowing of the other SOLID principle, the SRP(Single Responsibility principle) which states, an object, class, file, code needs to do one thing, and it needs to do it well. I was so fascinated by components that i tricked myself into violating the SRP while i was creating my components.

How? well, a component's purpose is to encapsulate some code and behaviour, and to be used on a location/s.

Let's illustrate that with an example, consider this `Card` component

```javascript
import React from "react"

const card = (props) => {
  // return some html code here
}

export default card;
```

now this is really handy, we can use this in our `Profile` page by simply doing these two lines 

```javascript
import Card from "./components/card"

<Card ...props />
```

Now, all logic and UI design of a card is enacpsulated in one single source of truth(file), which allows us to change only in one place and all `Card` elements will be changed, really powerful, or is it?

Now, requirement's change, we need to display some UI from card depending on a state of it's Consumer(the place where it's rendered). We want to show an admin badge next to the user icon if they are an admin, pretty easy to add, let's update the code

```javascript
const card = (props) => {
   
  if(props.isAdmin) {
    // render admin badge here
    // other elements for admin
  }
  // return some html code here
}

export default card;
```
and we can simply pass it to the component where we need it 

```javascript
<Card isAdmin={admin value} />
```
Now, requirements change again, aside from supporting admin elements like badge, we need to set the `border` of the element based if the user has been a long time user (they have been created more than one month ago). Let's update the code once more

```javascript
const card = (props) => {
   
  if(props.isAdmin) {
    // render admin badge here
    // other elements for admin
  }
 
  if(props.isUserActive) {
     // change border of the card element
  }
  
   // return some html code here
}

export default card;
```
Yet again, requirement change, we need to render a different icon for a user type moderator, let's update the code once more

```javascript
const card = (props) => {
   
  if(props.isAdmin) {
    // render admin badge here
    // other elements for admin
  }

  if(props.isModerator) {
     // update UI elements for moderator
     // a border and specific icon
  }
 
  if(props.isUserActive) {
     // change border of the card element
  }
  
   // return some html code here
}

export default card;
```

Now, you can see the pattern. whenever we want the card to support a specific use-case we need to add another `if` statement. I've been guilty of this, i've had components perform multiple checks and multiple control props just to determine how i'm going to render the component.

### Solution
you can break the `if` statements by placing each `if` in it's own file, we would end up with three components

```javascript
//components/cards/admin.js

import React from "react"

const adminCard = (props) => {
  // all admin properties 
  // admin icon
  // admin badge
  
  // returns html for an admin card.
}

export default adminCard;
```

```javascript
//components/cards/moderator.js

import React from "react"

const moderatorCard = (props) => {
  // all moderator properties 
  // moderator icon
  // moderator badge
  
  // returns html for an moderator card.
}

export default moderatorCard;
```


```javascript
//components/cards/activeUser.js

import React from "react"

const activeUserCard = (props) => {
  // all active user properties 
  // active user icon
  // active user badge
  
  // returns html for an moderator card.
}

export default activeUserCard;
```

### what did we do
we breaked  the file into multiple files each with it's own properties, now we have three different card elements

```javascript
<AdminCard isAdmin={admin value} />

<ActiveUserCard ...props />

<ModeratorCard ...props />
```
**However**, we have some code duplication here, some code from all three files are duplicated, it's all a matter of trade-offs here, we removed `if` controlled code into a file with standalone purpose, but we ended up copy-pasting the code into three different files. 

It's okay for a component to have a couple of if related code there, but if you see yourself passing more and more control variables, this is usually a sign that your component is attempting to do a-lot of stuff at once, your solution would be dividing the code into separated files.

Happy coding!.

Related links:

[Building Resilient Frontend Architecture](https://www.youtube.com/watch?v=TqfbAXCCVwE) by [Monica Lent](https://twitter.com/monicalent)

[SOLID](https://en.wikipedia.org/wiki/SOLID)