Rediscovering Frontend Fundamentals
Tags: frontend, react, opensource, webdev
Published: 2023-04-24 10:40:45

It's often said that skilled hands can achieve almost anything. However, recent observations in the industry have led me to believe that amidst the plethora of trends, paradigms, and novelties, we have lost sight of the core principles of frontend development.

In this piece, I will share several code snippets from a recent project and attempt to elucidate my thoughts on them. So without further ado, let's dive in!

## Table of Contents

1. The Labyrinth of Complexity
2. Blunders of the Past
3. The Double-edged Sword
4. A Handful of Crucial Suggestions

### The Labyrinth of Complexity

Consider this elementary `CardComponent` with an optional `heading` attribute. If this attribute is present, it is rendered within a wrapping `div` with a specific class.

```
const CardComponent = ({ content, heading }) => {
  return (
    <div className="card">
      {heading && <div className="card__heading">{heading}</div>}
      {content}
    </div>
  );
};
```

Simple scenarios work as intended. If the `heading` is dynamic and can return either content or `null`, our condition `{heading && <div />}` fails to recognize it and renders an empty `div`.

To tackle this issue, a developer came up with the following solution:

```
const CardComponent = ({ content, heading }) => {
  const headingRef = useRef();

  useEffect(() => {
    const containsContent = headingRef.current?.childNodes.length > 0;
    headingRef.current.style.display = containsContent ? "block" : "none";
  });

  return (
    <div className="card">
      {heading && (
        <div ref={headingRef} className="card__heading">
          {heading}
        </div>
      )}
      {content}
    </div>
  );
};
```

However, this code only works on the initial render. If the footer updates asynchronously, `useEffect` won't be invoked. After much deliberation, developers decided to explore the `MutationObserver`.

When asked for advice, I offered a simpler solution that only required basic CSS:

```
.card__heading:empty {
  display: none;
}
```

Developers often overcomplicate tasks without exploring basic CSS capabilities.

### Blunders of the Past

In a previous project, we needed a side panel widget that would stretch to its full height without overlapping the header and footer. The basic formula looked like this: `100% - headerHeight - footerHeight`.

The solution worked smoothly on all pages, except one. On that page, `footerHeight` was equal to 0. The developer who faced this bug discovered that `document.querySelector('footer')` returned `null`, even though the footer was still rendered on the page. They resorted to using `MutationObserver`.

Upon closer inspection, I found an alternative solution by simply rearranging a few lines of code:

```
<html>
<head></head>
<body>
  <header></header>
  <main id="root"></main>
  <script src="index.js"></script>
  <footer></footer>
</body>
</html>
```

Somehow, the `<script />` tag appeared on the page before the footer. The `<script />` tag is invoked synchronously, and the footer doesn't exist at that moment, so it's impossible to measure its height. By swapping the lines, everything started to work as intended.

Nowadays, developers rely heavily on modern tools like webpack-plugin, causing them to struggle when writing basic HTML.

### The Double-edged Sword

React hooks are both a blessing and a curse. While they offer flexibility and an elegant way to handle state, they also significantly increase code complexity and the likelihood of making errors.

The main culprit is the `useEffect` hook. When the code is not carefully managed, it can easily result in infinite loops or multiple component renders.

To avoid such problems, it is crucial to learn the intricacies of hooks and pay attention to their dependencies.

### A Handful of Crucial Suggestions

To help regain focus on frontend fundamentals, I offer the following suggestions:

1. Take a step back and re-evaluate your knowledge of HTML, CSS, and JavaScript. Make an effort to master the basics before diving into advanced frameworks and libraries.
2. Keep your code DRY (Don't Repeat Yourself) and follow the KISS (Keep It Simple, Stupid) principle. It will not only make your code more readable but also easier to maintain.
3. Be cautious when using modern frameworks and tools. While they can be helpful, they may also introduce unnecessary complexity.
4. Understand the pros and cons of the tools you use. This will allow you to make informed decisions and prevent issues down the road.

In conclusion, while frontend development continues to evolve, it is essential not to lose sight of the basics. By revisiting the core principles and focusing on simplicity, we can create more efficient, maintainable, and scalable solutions.