A fairly beaten topic, of course, but periodically I want to remind myself and people that wrong abstractions are absolute evil.
One of the key moments in your development as a developer is when you understand that hardcoding something is much cheaper and brings less harm in the future than a not quite successful attempt to reuse something. And in teamwork, sooner or later you also come to the understanding that all developers (surprisingly) don't think the same as you, and they will turn your magnificent abstraction into even bigger spaghetti and uncontrolled chaos than if it wasn't there. And this isn't even related to everyone being fools except you, but to the fact that your tasks can be completely different.
Trying to reuse something we multiply coupling and maintaining it becomes more difficult. Realization comes when you with pleasure approve an MR on code review that lies somewhere to the side of the rest of the code and with what great difficulty you try to figure out what changed in some common thing that is reused on all screens.
And the paradox of this topic in general is that automating, optimizing and simplifying code is our main skill. Making abstractions is what we're taught from the very beginning. But making the right abstractions (and not making unnecessary ones) is a skill that only comes through pain and mistakes.
By the way, this doesn't mean that I'm so smart and only do it this way, I make a ton of mistakes like everyone else. But when you see over time what such mistakes lead to, you pay much less attention on code reviews to someone writing their own bicycle. And let them, doesn't matter, at least they clearly didn't break anything.
If you haven't become so enlightened yet, then you have a real mania to wrap your local solution and take it out somewhere with a look like we're gonna reuse all this now. Read some patterns, and off we go. Wrote some button, well that means this button will be everywhere now, let's put it in the base module. Then we encounter that in another feature this button looks slightly different, this button's number of parameters grows, until it's all easier to forget and write something new and simple. And this cycle repeats. With the button I'm exaggerating, substitute any class in the text, the essence won't change.
In general, this is what I'm getting at, it's incredibly difficult to make abstractions and APIs in general that would satisfy all current requirements and especially all future ones. This can only be done if your component is simple as a door. The fewer abstractions and the less they imagine how they will be used - the better. Good code is not one to which there's nothing to add, but one from which nothing can be removed anymore. That's how you should write. And if you're not confident that it turned out simple, then better hardcode it, seriously.