Reactjs

For Beginners To Experts


Reactjs Intermediate

React Fragments

React Fragments enables the bundling of multiple child elements without the need for additional nodes in the DOM.

For this purpose use <React.Fragment> or its shorthand syntax <> ... </>

Syntax 1:



Syntax 2

In above example, MyComponent returns two <div> elements wrapped in a React.Fragment.

The grouping does not add an extra layer to the DOM.

It keeps the structure clean and efficient.

Fragments can accept keys, which is useful when mapping a collection to an array of elements, making them quite handy.

Context API in React

  • The Context API in React is a way for components to effectively produce and use data at different levels of the component tree without needing to explicitly pass props down through every level.
  • It is useful for sharing data that is 'global' for a tree of React components, such as authenticated user information, theme settings, or language preferences.
  • Without Context API we have to pass data through the component tree by passing props down manually at each level, which could be cumbersome and inefficient for certain types of global data.
  • The Context API makes the code cleaner and more maintainable.

How to use Context API

  • 1-Create a Context:
    Creating context is done by using React.createContext(), which returns a Context object.
    The defaultValue argument is only used when a component does not have a matching Provider above it in the tree.
  • 2-Provide a Context Value: Use a Provider component that comes from the created Context object to wrap the part of your component tree that needs access to the context data. Any component within this tree can access the context value.
  • 3-Use or consume the Context Value:
    Components use the data can access it in two primary ways:
    A) Context.Consumer Component: This is a React component that subscribes to context changes.
    It requires a function as a child, which receives the current context value and returns a React node.
  • Syntax:

    B) useContext Hook:

    This is a simpler and modern way to consume or use context
    It is available in functional components.
    It takes the context object itself as an argument and returns the current context value.

    Syntax:

The Context API in React is a tool for:
handling global state
and transmitting data across the component hierarchy.
Nevertheless, it doesn't used for all scenarios of state management.

In React, boundaries refer to defining a separation or limits between different parts of your application's UI or logic.

Creating boundaries improve code organization, maintainability, and scalability.

Several types of boundaries in React include:

  1. Component Boundaries:
  2. Functional or component separation or decomposition: Break down the UI into smaller, reusable components(function) that each have a single responsibility.
    This promotes code reuse and makes components easier to understand and maintain.
    This is the most common type of boundary.

    Container Components vs. Presentational Components:

    Container components are responsible for data fetching and state management.
    Presentational components do focus on rendering UI.
    This maintains a clear separation of data and presentation logic.



  3. State boundaries:
  4. Local Component State:
    Use local state within components for managing UI-specific state that doesn't need to be shared with other components.

    Use global State Management with the use of state management libraries like Redux, Context API, or Recoil for managing global application state that can be accessed across multiple components.
    This centralizes state logic and avoid using prop.


  5. Code Splitting boundaries
  6. Dynamic Imports: Employ dynamic import() to partition your code into smaller units that are fetched as needed.
    This approach enhances the initial page loading speed by only loading the code essential for the present view.

    React.lazy() and Suspense:
    React.lazy() and Suspense are two features in React used to do code splitting and improving the performance of your application by loading components asynchronously .

    React.lazy():

    React.lazy() is a function that dynamically import a React component(loads only components that are needed to load th app).
    It significantly improve the initial loading time of the application(especially for large applications that has lots of components).

    Syntax:

    Think we have a component named MyComponent that you want to import lazily:

    Example:

    Import it lazily in another component as follows:


    Suspense:

    Suspense is a React component that specify loading indicators while waiting for some asynchronous code to resolve(like lazy loading of components).
    It is managing the loading state of the application and displaying a fallback UI until the required data or components are loaded.

    Syntax:

    Note:

    In the example above, we see Suspense wraps the lazy-loaded component <LazyLoadedComponent >.
    The fallback prop specifies what should be rendered while the component is loading. /p>

    Example:

    Note:

    While the LazyLoadedComponent is being fetched and loaded asynchronously, We see a loading indicator instead of a blank screen, providing a better user experience.


  7. ErrorBoundary Component
  8. Error Boundaries: Use error boundaries to handle errors (catch JavaScript errors) that occur in your application.
    It prevents the application from crashing when an unexpected error occurs.

    Error boundaries in React catch JavaScript errors occurring in their child component tree.

    Instead of letting these errors disrupt the user experience, error boundaries log them and display a backup UI.


    It is essential to use them for maintaining a smooth interface despite errors.

    These boundaries capture errors during rendering, lifecycle methods, and constructors of all components below them.



  9. Context Boundaries:
  10. Context Providers:
    Use Context API to pass data or functions down through the component tree without manually passing props at each level. Use or define context providers at appropriate boundaries to encapsulate related state or behavior.


  11. Server-Side Boundaries:
  12. API Endpoints:
    Create or define clear boundaries between client-side and server-side logic.

    Use API endpoints to communicate between the frontend and backend parts of your application, ensuring separation of concerns and security.


    Establishing boundaries in React application make the codes cleaner, more maintainable and a better development experience.
    It facilitates collaboration among team members and promotes code reuse and scalability.

  1. Higher-Order Components (HOCs)is an extension of existing components' functionality.
  2. HOCs function as wrappers accept a component as input and yield a new component with supplementary props or behavior.
  3. HOC is an advanced technique in React for reusing component logic.
  4. They are functions that take a component and return a new component(They enhance the original component with additional properties or functionality.
  5. We use HOC when we want ot share same functionality for many components
  6. It makes the code cleaner and maintainable(not use repeated code for many Components).
  7. We can a HOC to modify or add new props to a component before it is rendered.
  8. Wrap the component at the export stage or in the export statement.
  9. HOC modifies props before passing them to a component.
  10. HOC manages state or access lifecycle methods in a reusable way.
  11. HOC conditionally renders components based on certain criteria like user permissions.

Syntax:

Example 1:

Example 2: Data Fetching

Example 3: Loading Spinner

Example 4: Error Handling

Example 5: Authentication

Example 6: Styling

HOC will wrap the component at the export stage or in the export statement.

Or

Example 7: HOC called withLogging that logs props to the console before rendering the wrapped component

Explanation:

We define the withLogging HOC, which takes a WrappedComponent as an argument.

Inside the HOC, we return a new component that renders the WrappedComponent and logs its props before rendering.

We then wrap our MyComponent with the withLogging HOC to create the EnhancedComponent.

When EnhancedComponent is rendered, it logs the props before rendering MyComponent.


Example 6: Adding a greeting to multiple components based on the user's status

Use the above (example 6) to enhance any component

Note:
HOC should pass through props to the wrapped component.


HOC will wrap the component at the export stage or in the export statement.
HOC is a function that takes a component as its input.
We use HOC to avoid code repetition. For example you want to add checks to so many components individually, you can create an HOC that does this check and use it to wrap all these components.
When you want to separate components (functions) such as fetching data, handling authentication use HOC.

Common Use Cases for HOCs:

  1. Code Reuse: HOCs allow you to encapsulate common functionality (e.g., logging, authentication, data fetching) and apply it to multiple components.
  2. Prop Manipulation: HOCs can add, remove, or modify props passed to the wrapped component based on certain conditions or requirements.
  3. State Management: HOCs can inject state into components or manage stateful logic (e.g., form handling, state synchronization).
  4. Conditional Rendering: HOCs can conditionally render components based on certain conditions or user authentication status.
  5. Performance Optimization: HOCs can optimize component rendering by memoizing components, implementing shouldComponentUpdate logic, or lazily loading components.

Note:

HOCs introduce an additional layer of component abstraction, which can sometimes make the component hierarchy more challenging to understand.

HOCs do not modify the original component. Instead, they create a new component with enhanced functionality, which may affect component identity and lifecycle methods.

HOCs are a powerful tool, but overuse can lead to code complexity and reduced readability. Use them judiciously and consider alternative patterns such as Render Props or Hooks when appropriate.

Overall, Higher-Order Components are a valuable tool in the React developer's toolkit for enhancing component functionality, promoting code reuse, and improving application architecture.

HOCs are like kind of wrappers for the components to add additional functionalities (like checking for login, handling errors, loading data) without making changes to the original components. It is helpful in reusing code and keeping components organized.

Testing in React

Jest

It is maintained by Facebook, stands as a JavaScript testing framework, easy to use with rapidity, and robust capabilities. It offers features like snapshot testing and mocking.

Syntax for Running Tests:

Example Test File:


React Testing Library:

React Testing Library, a testing utility designed for React.
It mirrors user interaction with the application.
It provides a user-friendly and simple API for querying and interacting with components.

React Testing Library is a powerful tool for testing React components.

It tests that components behave correctly.

React Testing Library integrates with popular testing frameworks like Jest.
We can write and run tests within our existing testing setup.

Example 1: Test File

Example 2

Key Testing Features

  1. Rendering Components: Use render methods provided by testing libraries to render React components in a test environment.
  2. Querying Elements in the DOM: Use query methods (e.g., getByText, getByTestId) to query and interact with rendered elements in your tests.
  3. Prediction: Use assertion or prediction functions (e.g., expect) to make assertions about the expected behavior or appearance of components.
  4. Mocking Dependencies: Use mocking techniques to replace dependencies (e.g., API calls, external libraries) with mock implementations for isolated testing.
  5. Snapshot Testing: Use snapshot testing to capture the rendered output of components and detect unexpected changes in subsequent test runs.

Integration Testing:

For integration testing, we use tools like Cypress or testing library's testing frameworks.

Example with Cypress

Tips in testing:

  1. Simplified concise targeted tests that analyze individual aspects of component's functionality.
  2. Validate and verify user interactions and guarantee the desired behavior of the components.
  3. It tests responsiveness that covers different screen sizes and browser environments to confirm compatibility across platforms.
  4. Implement Continuous Integration: Embed testing within your continuous integration (CI) workflow to automate testing and detect issues early during development.
  5. Adhering to best practices and utilizing suitable testing frameworks.
    It enhances the reliability and resilience of your React applications.
    It explores a range of testing methods and libraries to determine the most suitable approach for the project.

Styling in React

In React, there are several ways to style components. Here are some common methods to style the React App.

Inline Styles:

W can apply styles directly within the JSX using JavaScript objects.


CSS Stylesheets:

We can create separate CSS files and import them into your components.



Styled Components:

Styled Components offer a way to write CSS directly within your JavaScript files.

CSS-in-JS Libraries (other than Styled Components):

There are other libraries similar to Styled Components that allow you to use CSS-in-JS, such as Emotion.

These libraries let you write CSS directly in your JavaScript, providing dynamic styling capabilities.


Tailwind CSS:

A utility-first CSS framework that can be used in React for rapidly building custom designs by composing utility classes.


SASS/SCSS:

SASS/SCSS is a scripting language that pre-processes code before it's converted into CSS. It offers enhanced capabilities compared to standard CSS, including features like variables, nested rules, mixins, and additional functionalities


Inline CSS with React's style Attribute (Dynamic Styling):

We can dynamically change styles based on props or state.

Example: Dynamic Inline Style



Each of these methods has its own set of advantages.
Inline styles and CSS-in-JS libraries like Styled Components or Emotion are great for components that require dynamic styles based on props or state.
CSS, SASS/SCSS, and CSS Modules are excellent for more static, global styles.
Tailwind CSS is favored for its utility-first approach and rapid prototyping capabilities.
The choice often depends on the project requirements, scalability needs, and developer preference.

Fetching Data in React

The Fetch API comes integrated into contemporary browsers, offering a straightforward and robust mechanism for asynchronously retrieving resources or data.

Syntax:

Example:


Axios

A popular HTTP client library to make AJAX requests in JavaScript.

Syntax

Example


useEffect Hook with Fetch API:

Use of the useEffect hook in combination with the Fetch API for data fetching.

Example:

Three common approaches to fetching data in React:
using the Fetch API
using Axios library,
using the useEffect hook.

Each method has its advantages.
Choose the one that best fits the project requirements and preferences.
Additionally, handle loading and error states appropriately to provide a better user experience.