Take a look at these common questions and answers:
Q: Where should I put my state?
A: 2 options for putting it in React components. Or use Redux. Or Mobx. Or…
Q: Where should I put my logic?
A: Container components or actions creators or util libs or…
Q: How should I do testing?
A: You have 5 options for assertions, 4 for stubs, 3 for spies, 4 test runners…
See the pattern? For every problem you have a list of several idiomatic ways to solve the problem.
Which solution should you pick? Ideally you want just the one idiomatic way to solve your problem, but instead you get a long list of options without guidance on when to choose which one.
So you get confused. And then you get stuck.
And sometimes there doesn’t even exist an idiomatic way to solve the problems you are having. Even though they are common problems.
“What file structure should I use?” Do what you want.
“What is the minimum set of tools I need?” It depends…
That doesn’t help either…
All we want is one clear and simple by-the-book solution. But in the React ecosystem there isn’t one, so what should we do?
The question you ask yourself is important
So when you run into a problem you ask yourself the question “What’s the most correct/idiomatic way to solve this problem?“.
That question can many times help you solve the problem you have, or lead you in the right direction. But it can also be leading to more confusion than clarity.
Judge a man by his questions rather than by his answers. – Voltaire
The real world is complex, and finding a suitable solution requires that you look at the problem from more than one angle.
The way you do that is asking many kinds of questions. Here are some examples:
1. “What’s the simplest thing I can do?”
Sometimes it is necessary to create Redux Store and Actions with Thunk Middleware to do Ajax requests.
And sometimes a 4 line HTML form tag is enough.
Don’t always reach for the “correct” and fancy solution, but pause and reflect on what is the simplest thing you can implement to solve your problem. A simple solution is more maintainable, less risk for bugs, and usually most elegant. And also quickest to implement.
2. “What kind of problem am I trying to solve?”
- Performance problem?
- A feature where time to market is critical?
- Is it a proof of concept?
- Internal tool?
- For learning?
If learning is the goal, you might want to write two or three different implementations of the same feature just to explore and compare. If time to market is important, you might go for the quickest implementation, even if it’s “wrong”.
3. “What level of competency does my teammates have?”
Many juniors? Seniors only? If you will recruit more devs, what are their profile? These are the really important question to take into consideration because it says something about the level of “smartness” and room for creativity you will allow the codebase to have.
4. “Can I make a decision now, and revisit later?”
There are circumstances where the best thing to do is make a good enough solution, and revisit it later. If you think you are going to make it perfect on the first try, there is a risk you over engineer and as a consequence make the code more complicated than it has to be.
You don’t yet know how the code base will develop. Maybe that piece of code wouldn’t grow as big as you thought. And maybe the feature gets removed from the product completely in a month. (has happened to me many times)
Use this question with caution! You don’t want to throw in a lot of quick fixes all over the place. There is a balance.
Every application is unique, and going for generalized solutions is not always the best approach. To find the best solution for the problems in your application requires you to think further than the official documentation and tutorials.
Now you have a tool which takes into consideration many variables to find specialized solutions which will lead to more readable and more maintainable code.
And hopefully in the end more happy end users!
(this post has been translated to Korean here)