Introduction
In the world of web development, React has become an essential framework. Yet, some design choices continue to frustrate developers. Why? Because they seem counterintuitive and limiting. But these decisions aren't arbitrary. They are responses to deep constraints that every UI model eventually encounters. In this article, we'll dive into two of these unavoidable design choices—and why they make sense.
The Unavoidable Asynchronicity
One of the foundations of our digital world is asynchronicity. Whether it's streaming, data fetching, or distributed updates, everything stems from this reality. In this context, React's deferred states and dependency arrays in effects play a crucial role.
Deferred States
Consider this example:
const [state, setState] = useState(1);
// later
setState(2);
console.log(state); // Still logs 1Why isn't the state immediately updated? Because React needs to manage asynchronicity to ensure your app remains performant and consistent. If every state update were immediate, it could lead to a cascade of unnecessary and heavy re-renders.
Dependency Arrays
Consider this other example:
useEffect(() => {
console.log(state);
}, [state]);Dependency arrays may seem tedious, but they are essential. They allow React to determine when an effect needs to be re-executed. Without them, every re-render could potentially trigger every effect, impacting performance.
Alternatives: Why Nothing is Perfect
Other libraries, like Solid.js, have attempted to circumvent these limitations. Solid uses "Signals" to manage state, promising more direct reactivity. But the reality is that even these alternatives have to deal with the underlying asynchronicity of the web environment.
Real-World Example: Airbnb
Take Airbnb. The company uses React for its user interface. Despite challenges, it has managed to optimize its performance by cleverly adopting deferred states and dependencies. By carefully orchestrating the execution of effects, Airbnb maintains a smooth and responsive interface even for millions of users.
Why These Choices Are Crucial
We can gripe about these choices, but they address a necessity: keeping an app performant and consistent in a fundamentally asynchronous environment. By embracing these practices, you ensure your application is ready to handle the complexity of the real world.
Conclusion
The React design choices we love to hate are, in reality, pragmatic responses to the inherent challenges of modern web development. Rather than seeing them as obstacles, view them as tools to build robust and efficient applications.
Want to automate your operations with AI? Book a 15-min call to discuss.
