Design Dig: ReactJS Design Principals
ReactJS (hereinafter referred to as React) has frontend world by storm, especially Single Page Application world. ReactJS has been introduced to the world in Spring 2019
A JavaScript library for building user interfaces — ReactJS.org
React makes designing complex frontend apps easier using its HOC (Higher Order Components) via simple compositions. Let’s look at its design principals
In “Design Dig Series”, we are looking at various popular open-source software or system to learn and improve upon software design that we know of
Composition
The very basic but important feature on which React ecosystem relies is composition of Components. Component is a very basic unitary entity, designed on Single Responsibility Principle (SRP); when composed with other components to make a complex entity.
Since components are small and should have a single responsibility, adding or removing functionality will not cause rippling effects throughout the codebase. It also increases re-usability of components throughout code without any side effects. Components also make code DRY (Don’t Repeat Yourself), since they can be re-used without duplication.
Components in React uses props and states, props are like variable passed to a function that can be used within that component or passed down to other child components. Whereas, the state can be considered as a local variable to that component that can mutate and hold value.
React uses lifecycle methods in components to manage changes done to it. React compares Virtual DOM to browser DOM and only updates part that has been changed. For the performance purpose, React may bunch together changes in different components and run them together asynchronously. There is nothing bad in using state or lifecycle methods, as long as they are used in moderation
In React, a component can be curated in two ways, function-based components or class-based components. A function-based component is a bare metal javascript function that can have props delivered to it as arguments and can use JSX. However, to have more complex components we need to leverage class-based components that has lifecycle methods, states and other features exposed to it
Interoperability
React is a library, not a framework. Some may not find much difference between these two, but to put things in perspective, a library is less rigid and can live with other libraries. That means our React code can live with non-React code.
If you have noticed, React’s render
method can be bound to any HTML tag in a page and React will peacefully live in that space.
Higher-Order Components
In React, Higher-Order Component (or HOC); also known as a Decorator Pattern, wraps another component by adding extra functionality or extra properties. This allows abstraction from some commonly used logic and keeps your code DRY. It is how you distribute complex component structure between other components in React and a way to decouple your application logic and UI.
Pull updates instead of Push
React uses VirualDOM and it compares it with Browser DOM, and only updated with components that have been changed
Even when your components function-based components, we do not call them directly. It is up to React to “unroll” <SomeButton>
at some point in the future and actually apply changes to the Browser DOM according to the render results of the components recursively.
Sometimes changes to components are bunched together and “unrolled” in a single tick for performance reasons, meaning that changes made to a component can be delayed until React decides them to unroll
This is a common theme in React design. Some popular libraries implement the “push” approach where computations are performed when the new data is available. React, however, sticks to the “pull” approach where computations can be delayed until deemed necessary.
React can delay changes related to components that are offscreen or if changes to components are done faster them frame rate, React could choose to coalesce and perform a batch update. React gives more importance to UI changes that data related. And this exactly why, setState
in React is asynchronous.
Top-Down data binding
React uses a one-way data-binding approach, data flows from parent component to child component. One may ask why not two-way data-binding. Two-way binding leads to confusion for developers and sometimes makes it harder to debug the codebase. Developer’s experience is important to React development teams as they are also using it at Facebook and knows the pain point very well
With one-way binding, the developer knows that where data may be coming from. What is change what, why, and from where? It also upholds composition architecture that is central to React
Thanks for reading this article thus far. If you find this article useful, please clap and do follow for more.