REACT
React Boundaries (Error, Suspense, Bundle, Context, Server/Client Boundaries)
We see and hear this Boundary concept in many places in React, What is Boundary, What does it do, What are Boundary Types?)
In software development, the term boundaries refers to the conceptual or physical separation between different components, systems or domains within a software application. It represents a clear section or interface that defines the boundaries and responsibilities of each component or system.
Boundaries in software development;
Functional Boundary: A functional boundary defines the scope and responsibilities of a particular component or module within a software system. It sets the boundaries of what this component can do and how it interacts with other components or systems.
System Boundary: The system boundary represents the edge or interface of a software system. It defines the separation between different systems, services or modules and specifies how they communicate and interact with each other.
Security Boundary: A security boundary is a protective measure in software design and architecture that separates trusted and untrusted components or systems. It ensures that sensitive data and transactions are kept secure by implementing access controls and preventing unauthorized access.
Data Boundary: A data boundary defines the boundaries and rules for data flow within a software application. It determines how data is transmitted, stored, validated and transformed between different components or systems and ensures data consistency, integrity and confidentiality.
Process Boundary: A process boundary represents the separation between different processes or threads within a software application. It allows each process to operate in isolation and prevents interaction or conflicts between concurrent processes.
Interface Boundary: The interface boundary defines the negotiation between two components or systems. It ensures interoperability and integration between different parts of the software by determining how data, commands or requests are structured, formatted and the structure of outgoing/incoming data.
Boundaries in software serve various purposes such as encapsulation, modularity, security, maintainability and scalability.
React Boundary Concept
React is a rendering library, and nowadays it has evolved into a Meta Framework that builds applications by combining with Next, Remix, Gatsby or 3rd Party libraries. How to understand React
If we need to understand the Component Model, if we need to understand that components cover each other by Composition, if we need to understand the Hook structures for state code sharing, while sharing util library code for code sharing, we need to understand the React Boundary issue in the same way.
In React, the components, the code flow, the working place of the code need to be separated for certain reasons. React Boundary is used for this (Although we see them as Composition, they are actually React’s separation of different concepts and ways of working without showing them to the end user (DX).
I used similar structures while creating Routing for React Digital Garden (onurdayibasi.dev) .
React Boundary Types
Error Boundary:
If an error occurs while React is drawing on the screen (in the rendering phase), then you will see the screen as white or black. Here you can use the Error Boundary provided by React to capture these situations.
In case you want to catch the error in the components in this section, we should scope the ErrorBoundary related Component.
<ErrorBoundary fallback={<p>Something went wrong</p>}>
<Profile />
</ErrorBoundary>
The ErrorBoundary here is the implementation of the following Class in a class we derive from React.Component.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, info) {
// Example "componentStack":
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
logErrorToMyService(error, info.componentStack);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return this.props.fallback;
}
return this.props.children;
}
}
If a component in this code gets an error as a result of rendering, it catches it with the same ExceptionHandling try, catch structure and prevents us from rendering the component as Fallback and showing a blank white screen on the screen.
Suspense Boundary:
In React, when an Async operation is performed on those components, it is used to tell that an Async operation is performed in this part with some feedback components in the pending state of the component.
import { Suspense } from 'react';
function App() {
return (
<div>
<h1>My App</h1>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
}
Context Boundary:
React provides a Context API to allow components to maintain common context data and share it throughout the component tree. Many libraries use this Context API (ReactRouter, Redux, ReactQuery, ApolloClient) to access common contexts without passing props to individual components.
// Create a context object
const MyContext = React.createContext();
// Create a provider component
function MyProvider({ children }) {
const sharedData = "This is shared data";
return (
<MyContext.Provider value={sharedData}>
{children}
</MyContext.Provider>
);
}
// Component consuming the context
function MyComponent() {
return (
<MyContext.Consumer>
{value => <div>{value}</div>}
</MyContext.Consumer>
);
}
// Usage
function App() {
return (
<MyProvider>
<MyComponent />
</MyProvider>
);
}
Server/Client Boundary (React Server Components):
React divides the components into 2 parts in this section. A Client, that is, the components used in creating the UI we have been using for a long time, and another one focused on Data Fetching running on any server/etc., Server components that allow you to communicate with DB and Cache structures and create component structures on the server side, in the picture below, for example, you can see that the Component tree consists of Server (Orange) and Client (Blue) components in a mixed way.
In an example I get from Next.JS, use client or , client, server separation in the file name will be provided to distinguish the types of components over the files.
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
Tabiki Server / Client Component ’lar aynı yeteneklere ve özelliklere sahip değil Next.JS aldığım aşağıdaki ekran görüntüsünde iki farklı bileşen türünün birbirlerinin yaptığı şeyleri yapamadığını görebilirsiniz.
For example, ClientSide has ClientSide Interactivity, WebAPI, useState/useEffet, while Server Component has fetch data, Cache access capabilities to database via data API.
React Boundary needs to separate these components from each other.
Bundle Boundaries
Bundle Boundaries, Webpack, Vite, etc… is the Boundary that allows React to split them into parts by saying that React will load this JS part separately and the performance, network outgoing and incoming JS can work in a fragmented way.
const MyComponent = React.lazy(() => import('./MyComponent'));
While doing this, the other Suspense, ErrorBoundary mentioned above can wrap these structures, but here this React.lazy() indicates to the bundling tool to split this JS file or its dependencies into separate pieces.
LearnReactUI.dev
Don’t forget to subscribe to LearnReactUI.dev to further your own career in the React Ecosystem. This is a website for React developers who want to develop real-world Web Applications.