React currently sits on top of the throne when it comes to popular Node.js frameworks. And that's because it gets alot right.
It's highly portable, it's fast and it is very well documented on the internet thanks in part to the growing number of developers using it currently.
But it isn't perfect and it certainly isn't for everyone. I use React for my professional development on a daily basis, and I've learned how to navigate through the many quirks that many developers would find to be showstoppers. So I personally find it to be a robust and valuable framework.
But there are things that I don't personally like about it still. A few of these are probably shared among many other developers out there.
5. State management
One of the hardest things to learn (and learn well) about React, is how to effectively use state in order to render components dynamically.
Most JavaScript developers are used to functional code that resembles something like the following:
<div id="element"></div>
<script>
function update(){
document.getElementById('element').innerHTML = 'some new content';
}
</script>
Pretty straightforward code that pretty much any web developer can understand. If you want to update the contents of an element on the page, you simply query select that element and set the appropriate property.
But React is not that. It's even in the name: React, meaning that your code is constantly reacting to something. That something is state changes.
A more React way of writing the previous code would be the following:
function component(){
const [content, setContent] = useState('');
useEffect(() => {
setContent('some new content');
}, []);
return (
<div>{content}</div>
)
}
Essentially, you create the state, you track the state and you update the state and you avoid having to write any pesky query selector code in the process.
But that beneficial feature, is also what makes React a difficult framework to work with. Because most webpages don't have one element. Most web pages have dozens of elements and they all essentially need the same kind of treatment in order to render.
Often times I find myself needing to perform a simple task, such as highlighting an element on the page after it has been selected. While realistically I could just write a one-liner query selector that updated that DOM element directly, it wouldn't be the appropriate way to do it. At least, to do it with React.
Toggling a 'selected' class on an element performs the visual effect that I would want, but it doesn't inform React that this element is selected. And if other elements depended on this state in any way, I would also have to manually keep them updated as well without React.
React handle one-directional data binding very well, to be fair, but it just has a steeper learning curve.
4. Inline styles
For the majority of my career, I was indoctrinated into the world of external CSS. You never ever ever inline anything, because it makes it clutter up the codebase and it makes it difficult to create a proper CSS hierarchy in the process.
React's different though. Because, while you still have the option of externalizing your CSS, it isn't taboo to not do so.
In fact, alot of tutorials online even promote doing so. And they aren't wrong to be honest. Because React is mainly an SPA framework that frequently uses a bundler, such as Webpack, to condense resource files down into single files. It doesn't really matter where you generate your CSS classes, so long as they are easy to find.
But decades of conditioning have made it difficult for me to fully adopt any kind of inlining.
3. Useless error messages
React itself is a relatively complex framework comprised of thousands of lines of code that do all sorts of fanciful things. So right off the bat, you don't know React. You might know how to use React to achieve some goal, but you don't technically know what's happening much of the time.
And often times that translates over into seemingly random and relatively useless error messages appearing in lieu of the actual error.
Aside from console.logging my eyes out, I haven't yet found a viable solution to this issue. And that means that debugging is typically not as straightforward as I would want it to be and I find myself constantly having to delete code in order to backtrack and find where things went south.
Coming from the world of .NET and C#, which has super detailed compilation errors that have never left me astray, this is one of those issues that long term might make me reconsider React for overly complex applications.
On a positive note here though, this shortcoming has made me much more aware of the kind of code that I am writing, because at the end of the day the goal isn't to have easy to read errors. It's to have no errors at all.
2. Prop drilling
If you are working with multiple tiers of components in a parent-child-child fashion, you will inevitably find yourself needing to pass data from the parent to the 3rd grandchild.
React has no direct way for you to target where to send prop data however. In order to achieve this, you pretty much have to continuously pass the data from child to child until it reaches its destination. And depending on the complexity of your components, this could result in difficult to maintain code.
function Parent(){
return (
<Child1 name="walt" />
)}
function Child1({name}){
return (
<Child2 name={name} />
)}
function Child2({name}){
return ({name})}
Fortunately though, you have options here. You don't have to fall victim to long chains of prop propagation if you don't want to.
But much of that will come down to just how you are setting up your applications.
1. Breaking changes
It's no surprise that both frameworks and programming languages get consistent updates and features on a regular schedule. At least the larger and more popular languages and frameworks.
React is no different. It currently sits at version 16.x and I'm sure that version 17 is just around the corner choc full of new things.
Typically, that's a cause for celebration. But in React's case, it might be more the opposite. Because React often times makes big changes from version to version, meaning that your once stable and up to date code, might all of a sudden seem outdated and ancient overnight.
This happened when React introduced functional components not long ago. While class components were still widely used (and very much viable), they were looked down upon for the most part.
And the same thing happened when React Router upgraded to version 6 recently, effectively breaking most code written with anything less than version 5.x.
Needless to say, React isn't perfect. It has flaws just like every other language and framework out on the market today. And for everything that makes it frustrating to work with, it also gets alot of things right in the process.
But it isn't for everyone or for every situation.
So be mindful when choosing it as your next programming platform. And if these quirks that I've pointed out seem like no big deal to you, then perhaps it is the right framework for you.