When we talk about ReactJS, some of the keywords that come to mind include virtual DOM, JSX, unidirectional data flow, declarative programming, component-based UI development, hooks, state management, React Native, Redux, performance, and a lot more.
Let us look at the key react js features that make it so versatile and popular-
Key Features of React
ReactJS follows a declarative programming paradigm. In React, you declare (/define) how the UI should look when the state changes, and React core takes care of rendering the user interface.
In other words, React allows you to focus on the output without you having to worry about how to achieve the output. Many other modern app development frameworks like Vue and Flutter also follow a declarative programming style.
Declarative programming is generally high level and aids in speed development, debugging, collaborative coding as well as app scalability.
Assembly of Components
One of the notable features of ReactJS is component-based user interface development. A typical React app is an assembly of multiple components. These components are either core ReactJS components, app-specific custom components, or reusable components provided by external libraries.
React enables you to create standalone isolated components that you can use across apps. This feature of React helps improves reusability, faster development, and lesser UI defects.
While JSX is not mandatory but without using JSX in ReactJS your code will become complex and difficult to maintain. Given below is a small example of JSX-
React Virtual DOM is something that changed the game of frontend development. React framework was the first mainstream UI development framework to use the Virtual DOM design pattern. Technically speaking, Virtual DOM is an in-memory copy of the actual DOM generated by the browser.
How Does VDOM Help?
Changing the UI requires updating the real DOM, and touching the real DOM way too frequently results in expensive computations at the browser level and can make UI look sluggish.
Virtual DOM enables developers with an option to batch state changes at the Virtual DOM level. The changes can then be pushed to the real DOM to update the UI in a much more optimal manner.
An example below is where color and text are updated in two steps at the Virtual DOM level but are updated to the real DOM together.
Having said the above, there are other frameworks like Svelte and SolidJS that do not use Virtual DOM but still provide excellent UI performance. You might want to check out Svelte vs React Comparison to know more.
Data Flow Pattern
Defining the overall data flow pattern is critical to the core design of any application or framework. In React, you can implement a unidirectional data flow pattern easily.
Below is how unidirectional data flow works in React-
- Components subscribe to the data store for state changes
- State change is passed to the components listening to the state change events in the store.
- Associates then either use the new state to update the UI or pass the state further to the child components.
- Child components do the same as parents but never change the data received from the parents.
- Any new state created by any component in the hierarchy is dispatched to the store (or child components) but never back to the parent.
- If the parent component is listening to the store, it gets the new state from the store, and the cycle continues.
The above pattern makes it really easy for developers to debug the application in case something goes wrong. Though you can implement two-way data binding as well in React, that may be counterproductive.
ReactJS utilizes one of the most sophisticated state management libraries like Redux. Typically, for small apps that include only a few UI components, you can keep Redux aside and manage the state within the components.
However as the application grows, managing the state in individual components becomes challenging and a central app-level state store comes in handy. State management library like Redux provides developers with the capabilities to retrieve and set state from components to the state store.
In short, State management is one of the most useful features of react js and helps developers write maintainable and scalable code.
Automatic batching was introduced as one of the key features in React 18. With the automated batching feature, ReactJS now provides out-of-the-box batching for state updates, timeouts, intervals, event handlers as well as asynchronous operations.
Prior to React 18, you were able to batch state changes but with complicated app-level coding. ReactJS out of the box was capable of batching only browser event-related changes. For example, if a state change was asynchronously supplied, that needed a lot of app-level development for batching.
Batching helps in the below two-
- Avoids multiple re-renders for every state change
- Prevents half-finished state updates to the UI. There are typical scenarios where it is important to update multiple variables on the screen together.
In my personal experience, automated batching has increased both productivity and performance, specifically since batching now relies lesser on app developers and more on the core ReactJS.
Concurrent Rendering Preparation: React 18 Feature
Concurrent is one of the most important features that came with React 18. With concurrency, React proactively prepares multiple UI versions in the backend. The version needed for a specific state is then delivered with minimum delay.
To give you some idea, the concurrency feature of React enables React to pause, abort and reprioritize DOM updates. It might seem that concurrency may disrupt user experience but React evaluates the entire DOM tree including any in-between aborts in the memory. While the DOM tree evaluation is done, the mutations to the DOM tree are kept to the very last and take place only when everything is signaled as green for the user screen updating.
Note that Concurrency is more of a backend mechanism abstracted away from the frontend developers. It is part of the React core and works behind the scene.
Suspense relates to suspending the component or code from rendering the user interface. In the earlier versions of React, the Suspense feature allowed you to do code splitting on the client-side using “React.lazy”.
With React 18 release, Suspense now works on the server-side and works hand in hand with concurrent rendering. From a functional standpoint, Suspense prevents screen updates from the fallbacks and delays the render until the required data is received for a good UI state.
With React beyond 18, the suspense feature will further enhance the rendering on the server-side using server-side streaming. The server-side renderer in React would allow you to create a continuous stream of HTML back to the client instead of sending synchronous HTML strings.
The biggest advantage of hooks is that you can build the application with just function components, ditching class components altogether. Some of the most used React hooks include useState, useEffect, useContext, useReducer, and useMemo. React 18 has included many additional hooks in the core library, a couple of these include useTransition and useDeffered.
You can check out complete React 18 Features to know more about hooks and other new features released in React 18.
More on React Features
Apart from the core features, there is much more that makes React so powerful and popular. This includes features that enable cross-platform app development with React Native, Ionic, Capacitor, and other similar frameworks.
Let us look at a few such aspects-
React Native is a cross-platform app development framework built on top of React. With React native you can create Android, iOS, and web apps from a single code base.
React native uses all the basic features of React, like state management, components, JSX, hooks, and automated batching. The key difference is that React Native utilizes native components of iOS and Android instead of web components.
UI Performance is not directly a feature but is the most important aspect of ReactJS. High-level frameworks typically lack performance due to a lot of boilerplate and backend computations. Angular 1 for example became popular but died off since it lacked performance.
ReactJS comes as a high-level declarative components framework that helps you maintain UI performance even when the app becomes complex and huge.
Meta is heavily invested in ReactJS, their own web ecosystem relies on React. Apart from Meta and many other large corporates, ReactJS has a huge footprint in open source projects too. Due to such a large ecosystem, React continuously sees improvements and brings in new features with every release.
For the next release of ReactJS, the Facebook research team is working on revamping its core architecture to improve performance and developer experience. The new architecture is termed fiber architecture.
React Fiber Architecture
Fiber architecture aims to improve rendering performance by including features like incremental rendering to split the UI rendering over multiple frames. Additional features include pausing and prioritization of rendering logic.
ReactJS already includes a little bit of these features. The transition feature in React is an example that enables ReactJS to prioritize state updates into urgent and low priority. With this feature, it becomes an absolute breeze to define if a state update (like dropdown selection) requires an immediate update or can be queued for batching.
Even after a decade after its first release, React still holds the number one spot among the frontend UI libraries. One of the key reasons is that Meta & React community keeps enhancing ReactJS by adding new features regularly.
Hope you liked the article. Do share the article with friends and colleagues!
You may also like to read-