State Management Without Global Stores
Detail-obsessed front-end developer focused on transforming static designs into smooth, interactive experiences. I care deeply about aesthetics, performance, and clean code.
Hook: The Challenge of Complexity
While building my dev-portfolio, I initially relied on global state for almost everything: 3D skill orbit, interactive cards, hidden terminal quest, and mini micro-interactions.
At first, it seemed convenient. But as I added more features, issues began to surface:
Unnecessary re-renders across unrelated components
Hard-to-track bugs when one module updated its state
Components tightly coupled, making the portfolio harder to maintain
It became clear: I needed a more modular and maintainable approach to state management, without losing interactivity.
Exploring Alternatives
I considered several options:
Redux or Zustand – overkill for portfolio-level interactions.
Context API – caused nested re-renders and reduced flexibility.
Local component state + custom hooks – lightweight, modular, and perfect for interactive portfolios.
I chose custom hooks + local state, allowing each component to manage its own state while exposing controlled interfaces for communication between modules.
Implementing Localized State
For example, the hidden terminal quest state is fully managed locally:
const useQuestState = (initialStage = 1) => {
const [stage, setStage] = useState(initialStage);
const [inventory, setInventory] = useState([]);
const [integrity, setIntegrity] = useState(100);
const processCommand = (cmd) => {
switch(stage) {
case 1:
if(cmd === "key") {
setStage(2);
setInventory([...inventory, "Key"]);
} else {
setIntegrity(integrity - 10);
}
break;
// Further stages...
}
};
return { stage, inventory, integrity, processCommand };
};
Now each module in the portfolio manages its own state without cluttering a global store, and communicates with other modules through props or callbacks only when necessary.
Benefits of This Approach
Performance: Components re-render only when their own state changes.
Maintainability: Each portfolio feature is self-contained and easier to debug.
Reusability: Hooks can be reused for future projects or experiments.
Lessons Learned
Global state isn’t always the answer: Only use it for truly shared, cross-cutting data.
Custom hooks simplify logic: Encapsulate complex interactions cleanly.
Performance is critical: Localized state avoids unnecessary re-renders in interactive, animation-heavy portfolios.
Takeaway:
Managing state efficiently is both an engineering and design decision. Using local state with custom hooks allowed my portfolio to stay interactive, scalable, and maintainable, while still showcasing complex UI and 3D experiments.
