
Frameworks vs. Fundamentos: como a dependência excessiva de ferramentas pode prejudicar seu crescimento como desenvolvedor
Introdução: O Poder dos Fundamentos
Apesar de estar envolvido em projetos modernos usando ferramentas como Next.js, tenho dedicado um tempo para explorar conceitos de programação funcional, como monads. Fora do escopo de desenvolvimento web, às vezes paro para estudar assuntos que não estão nos holofotes. Atualmente, o foco está em programação funcional e seus famigerados (malditos e complexos) monads.
Você pode se perguntar: “Por que isso é importante pra você, David?”, “Monads pagam bem?” Sinceramente, acho que não mas no mundo da programação, nunca se sabe. Mesmo que programação funcional não esteja entre os assuntos mais hypados do momento, ela traz conceitos fundamentais que são essenciais para qualquer desenvolvedor. Ao entender os fundamentos e aplicar esses princípios em diferentes contextos, consigo melhorar a qualidade do meu código, seja em novos projetos ou em sistemas legados.
A Armadilha das Stacks "Mágicas"
O mundo da tecnologia se fascina por stacks mágicas (Next.js, React, Tailwind) e novas ferramentas que surgem a cada segundo (enquanto você lê isso, provavelmente um novo framework JS já apareceu no GitHub). Mas focar demais nas tendências pode criar um conhecimento frágil. Sem princípios sólidos de programação, estamos só empilhando blocos de LEGO sem entender os tijolos.
Imagine herdar um bom e velho sistema legado: alguns hacks aqui, um código colado com fita crepe ali. Um dev que depende só das abstrações modernas estaria perdido. Conceitos funcionais como imutabilidade ou funções puras não são teóricos, são habilidades de sobrevivência pra quem precisa desembaraçar código espaguete, independente da stack.
Frameworks vêm e vão, mas arquitetura limpa, design modular e lógica de resolução de problemas permanecem. Investir nos fundamentos não é correr atrás do hype, é construir uma base adaptável que sobrevive às ferramentas do momento.
Exemplo 1: Projeto Moderno com React Hooks
Aqui está um exemplo simples de uma aplicação de lista de tarefas (o clássico "todo list") usando React e Next.js:
1"use client";
2import { useState, useEffect } from 'react';
3
4export default function TodoApp() {
5 const [todos, setTodos] = useState([]);
6
7 useEffect(() => {
8 fetch('/api/todos')
9 .then(response => response.json())
10 .then(data => setTodos(data))
11 .catch(error => console.error('Error fetching todos:', error));
12 }, []);
13
14 const addTodo = (newTodo) => {
15 setTodos((prevTodos) => [...prevTodos, newTodo]);
16 };
17
18 return (
19 <div>
20 <h1>My Todo List</h1>
21 <ul>
22 {todos.map((todo, index) => (
23 <li key={index}>{todo}</li>
24 ))}
25 </ul>
26 <button onClick={() => addTodo('New Task')}>Add Task</button>
27 </div>
28 );
29}
30
Abordagem Moderna
Uso de Hooks: O uso de
useState
euseEffect
permite um gerenciamento de estado reativo e bem estruturado.Imutabilidade e Boas Práticas: O estado é atualizado de forma imutável, um princípio vindo da programação funcional.
Este código é elegante e eficiente. Mas sem entender conceitos como imutabilidade, funções puras e controle de estado, você pode estar apenas seguindo uma “receita” sem entender o “porquê” de cada passo.
Exemplo 2: Projeto Legado com Manipulação Imperativa
Agora, veja como um código mais antigo, sem abstrações modernas, poderia resolver o mesmo problema:
1<!DOCTYPE html>
2<html>
3 <body>
4 <div id="app"></div>
5 <script>
6 function TodoApp(container) {
7 let todos = [];
8 function fetchTodos(callback) {
9 fetch('/api/todos')
10 .then(response => response.json())
11 .then(data => callback(data))
12 .catch(error => console.error('Error fetching todos:', error));
13 }
14 function render() {
15 const todoList = container.querySelector('#todo-list');
16 todoList.innerHTML = '';
17 todos.forEach((todo) => {
18 const li = document.createElement('li');
19 li.textContent = todo;
20 todoList.appendChild(li);
21 });
22 }
23 function addTodo(newTodo) {
24 todos.push(newTodo);
25 render();
26 }
27 container.innerHTML = `
28 <h1>My Todo List</h1>
29 <ul id="todo-list"></ul>
30 <button id="add-task">Add Task</button>
31 `;
32 container.querySelector('#add-task').addEventListener('click', () => {
33 addTodo('New Task');
34 });
35 fetchTodos((data) => {
36 todos = data;
37 render();
38 });
39 }
40 TodoApp(document.getElementById('app'));
41 </script>
42 </body>
43</html>
44
Abordagem Legada
Manipulação direta de estado e DOM: O estado (
todos
) é modificado diretamente, e o DOM é atualizado “na unha”.Desafios do legado: A ausência de abstrações torna o código mais difícil de manter, mas oferece uma visão direta do que realmente está acontecendo.
Comparando os Dois Exemplos
Código Moderno: Mais legível e com abstrações úteis, mas pode esconder os detalhes para quem depende apenas dos frameworks.
Código Legado: Exige mais esforço para entender e trabalhar, mas revela os fundamentos por trás dos frameworks modernos.
Equilibrando o Moderno com o Clássico
A verdadeira habilidade de um dev não está em se prender a uma única tecnologia, mas sim em navegar com confiança entre diferentes paradigmas e estilos de código.
Algumas recomendações:
Entenda os conceitos por trás das ferramentas: Por que usamos hooks? Como o estado funciona em diferentes paradigmas?
Pratique com diversidade: Trabalhe com frameworks modernos, mas também explore linguagens diferentes e códigos legados.
Aprenda com o legado: Projetos legados são verdadeiras minas de ouro para quem quer aprender, pois expõem desafios que as ferramentas modernas tentam abstrair.
Conclusão: Domine o Presente, Estude o Passado
Projetos legados frequentemente apresentam desafios que não estão nos manuais dos frameworks modernos. Eles exigem uma compreensão mais profunda do que acontece por trás dos panos. Por outro lado, projetos modernos, mesmo com toda a sua sofisticação, também se beneficiam (e muito) de uma base sólida de fundamentos.
Frameworks como o Next.js não são vilões. Pelo contrário, são aliados poderosos quando usados com sabedoria. Mas, para dominar de verdade a programação, é preciso ir além das ferramentas e explorar os conceitos que sustentam tudo isso.
Programar não é escolher entre o moderno e o clássico. É encontrar força no equilíbrio e entender que os fundamentos são as raízes de tudo o que construímos, seja uma aplicação de ponta ou a manutenção de um sistema legado.