AI App Development from Zero Knowledge – 1000 Hours #16

#16: Chaos Triggered by a Misaligned Design

Summary:
In this episode, I dive into a major issue caused by confusion in state management. Specifically, I recount how mixing up local and global responsibilities and overlooking existing architectural rules led to a wave of bugs. Through back-and-forth with ChatGPT, I reconstructed the code structure, addressing a critical beginner mistake: the hidden danger of code that “kind of works.”

my app

…But before we dive in, take a look at this—this is the app I spent 1,000 hours building from scratch. I started with zero knowledge, and I want to share with you how I got here!

One day, I was revising the screen structure of my app. Something felt off. But I couldn’t explain what.

State updates weren’t reflected, data randomly reset, and level-up logic would stop midway. I suspected a misplacement in code responsibility, so I asked ChatGPT:

"You said localStorage operations should be handled in App.js, so why did you insert them inside TaskManager.js?"

That question sparked a long road of refactoring.


The Rules Were There—But I Didn't Follow Them

I had originally defined clear architectural rules, like this:

{
"Routing": "App.js",
"Globally Shared State": "App.js",
"Local State": "TaskManager.js",
"LocalStorage Operations": "App.js (centralized management)",
"Page-Specific Logic": "TaskManager.js"
}

But in practice, my TaskManager.js was doing things like:

useEffect(() => {
const savedTasks = JSON.parse(localStorage.getItem('tasks')) || [];
setTasks(savedTasks);
}, []);

This broke the separation. I had no idea whether the correct task data lived in App.js or TaskManager.js.


Redefining Responsibility: What Is Global?

ChatGPT posed a crucial question:

“If different screens show different data, do you even need to share the state globally?”

The answer: No.

In my app, coins only appeared on the detail screen. Status only appeared in the punishment screen. If each piece of data only lived in one screen, there was no need to centralize it in App.js.


Why I Moved Everything Back to TaskManager.js

Here’s the conclusion I reached:

  • Manage local state in TaskManager.js
  • Place save/load logic also in TaskManager.js

Why?
Keeping it in App.js bloated the code and made prop passing more complex. When a screen is the only user of a state, it’s best to keep the logic self-contained.


Design Issues Can’t Be Fixed “After the Fact”

Even if the code “works,” it’s dangerous when it’s working without understanding.

When the avatar didn’t change, the level didn’t update, or localStorage got initialized with the wrong value—it all traced back to a flawed design.


Closing Words: When in Doubt, Ask “Which Screen Uses It?”

ChatGPT once said something I still remember:

“Whether it should be global depends on whether multiple screens use it.”

Since then, my code structure has become much clearer.

If you’re unsure about “architecture,” just ask yourself:

Where, and by whom, is this data used?

That question alone can untangle the chaos.

●NEXT
AI App Development from Zero Knowledge – 1000 Hours #17
(👉#1)

●My HP
Check Out the Website I Built Using My 1000 Hours of App Development Experience!

It may look like a game, but it’s actually a website I built after 1,800 hours of development. It was tough, but I gained the skills to build anything.

This site is designed to help people around the world pursue their dreams—using Japanese-style diligence and five key pillars: learning, exercise, sleep, nutrition, and time. I’m living this lifestyle too.

One day, I hope to team up with users who reach their dreams here and take on world-changing projects together.

So—want to chase a big dream with me?

コメント