Optimistic UI is a technique used to improve the perceived performance of web applications by updating the UI instantly in response to user actions, even before getting a response from the server. React's experimental hook useOptimistic() simplifies the implementation of Optimistic UI by providing a way to manage temporary optimistic state alongside the true state. Internally, useOptimistic() leverages React's update mechanism but adds a special revertLane for easy switching between optimistic and true states.
Tuesday, April 9, 2024A new official React doc that explains how to animate a progress element using the new useTransition hook, which lets you update state without blocking UI.
An in-depth YouTube tutorial on modern React.
Excessive null/undefined value checking in React components is difficult to deal with as a codebase grows, especially if the codebase is poorly typed.
The Asynchronous State Handler pattern improves UX in web apps by decoupling data fetching from the UI. It wraps asynchronous queries with meta-queries that track the status (loading, success, error) of the data fetching process. This allows the UI to react dynamically to these states, displaying loading indicators or error messages when needed. The pattern can be implemented in React using a custom hook.
useDeferredValue is a React hook that optimizes performance by prioritizing the rendering of important UI elements over less important ones. It does this by allowing React to interrupt low-priority renders if a higher-priority update occurs, preventing the UI from becoming unresponsive. This hook is best used with components that require complex calculations or slow data fetching. In React 19, useDeferredValue gets the ability to specify an initial value, which can speed up initial renders.
In React, closures combined with the useCallback hook can cause hidden memory leaks by holding onto large objects in the component's context, preventing garbage collection. Memoized functions may inadvertently reference each other and shared data, creating an endless chain of closures. To avoid such issues, keep closure scopes small, avoid unnecessary memoization, and consider using useRef for large objects.
React 19 introduced a change that disables parallel rendering of siblings within the same Suspense boundary. This could have potentially degraded performance for many websites that rely on React, but after facing pushback from the community, the React team decided to revert this change.
Airbnb faced challenges upgrading its massive React codebase due to dependency management and performance concerns. To overcome these, its team developed a React Upgrade System that enabled incremental upgrades, module aliasing, environment targeting, and rigorous testing. The system allowed Airbnb to smoothly transition to React 18 while maintaining code quality and user experience.
React introduced the concept of a "virtual DOM" to optimize web app rendering. Its popularity led to widespread adoption, but also to criticisms regarding its learning curve, state management, and performance. While React's defenders highlight its improvements in recent versions, alternative frameworks like Svelte and Astro offer simpler approaches without relying on the virtual DOM.
This article explains how React compiler works, specifically how it applies memoization techniques for efficiency on functions and hooks. The compilation involves traversing nodes, compiling functions, and replacing original functions with optimized versions. If memoization is applied, the compiler adds an import for `useMemoCache`. The article details the compiler's operation from entry through Babel to function transformation.
This is a practical guide to refactoring a messy React component through gradual improvements. First, one should make sure that tests are written so that no functional changes occur during refactoring. Then, linting rules should be used to prevent future code duplication and dead code. The guide highlights several key areas for refactoring, including splitting components based on responsibilities and extracting utility functions to improve code organization and maintainability.
This article explains how to create a simple React state management library using the `useSyncExternalStore` hook introduced in React 18. It outlines the key components of the library, including subscribing to state changes, retrieving the current state, and updating the state. The article also compares this approach to using React Context and discusses potential improvements like using reducers and immer for state management.
Dependency Injection (DI) is a design pattern that improves flexibility, testability, and maintainability by injecting external dependencies into your code rather than hard-coding them. In React applications, DI can be implemented using createContext and useContext to manage dependencies across components without prop drilling. This approach simplifies testing, makes code less coupled, and provides better separation of concerns, though it does add some complexity.
With the addition of Server Components and Server Actions, React is evolving into a full-stack framework.
- Building a React-like library from scratch to understand its internal workings and design decisions.
This article details the process of building a React-like library from scratch, providing insights into its internal workings and design decisions. It starts by implementing a core rendering model, including components, virtual DOM, and reconciliation, showing how React constructs and updates the UI. It then goes into the implementation of essential hooks like `useState`, `useRef`, `useEffect`, and `useMemo`. Finally, the article discusses the implementation of `useCallback` and `useContext`, showing off the challenges and solutions involved in managing state and context sharing within a component tree.