Skip to main content

Other React theory

Explain about types of side effects in React component.​

There are two types of side effects in React component. They are:

Effects without Cleanup: This side effect will be used in useEffect which does not restrict the browser from screen update. It also improves the responsiveness of an application. A few common examples are network requests, Logging, manual DOM mutations, etc.
Effects with Cleanup: Some of the Hook effects will require the cleanup after updating of DOM is done. For example, if you want to set up an external data source subscription, it requires cleaning up the memory else there might be a problem of memory leak. It is a known fact that React will carry out the cleanup of memory when the unmounting of components happens. But the effects will run for each render() method rather than for any specific method. Thus we can say that, before execution of the effects succeeding time the React will also cleanup effects from the preceding render.

What are error boundaries?​

Introduced in version 16 of React, Error boundaries provide a way for us to catch errors that occur in the render phase.

What is an error boundary? Any component which uses one of the following lifecycle methods is considered an error boundary. In what places can an error boundary detect an error?
Render phase
Inside a lifecycle method
Inside the constructor
Without using error boundaries:

class CounterComponent extends React.Component{
constructor(props){
super(props);
this.state = {
counterValue: 0
}
this.incrementCounter = this.incrementCounter.bind(this);
}
incrementCounter(){
this.setState(prevState => counterValue = prevState+1);
}
render(){
if(this.state.counter === 2){
throw new Error('Crashed');
}
return(
<div>
<button onClick={this.incrementCounter}>Increment Value</button>
<p>Value of counter: {this.state.counterValue}</p>
</div>
)
}

In the code above, when the counterValue equals 2, we throw an error inside the render method.

When we are not using the error boundary, instead of seeing an error, we see a blank page. Since any error inside the render method leads to unmounting of the component. To display an error that occurs inside the render method, we use error boundaries.

With error boundaries: As mentioned above, error boundary is a component using one or both of the following methods: static getDerivedStateFromError and componentDidCatch.

Let’s create an error boundary to handle errors in the render phase:

class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
return <h4>Something went wrong</h4>;
}
return this.props.children;
}
}

In the code above, getDerivedStateFromError function renders the fallback UI interface when the render method has an error.

componentDidCatch logs the error information to an error tracking service. Now with the error boundary, we can render the CounterComponent in the following way:

<ErrorBoundary>
<CounterComponent />
</ErrorBoundary>

What are the rules that must be followed while using React Hooks?​

When using React Hooks, there are specific rules that must be followed to ensure they work correctly and to avoid unexpected behavior. These rules are fundamental to the way Hooks function

Only Call Hooks at the Top Level​

Do not call Hooks inside loops, conditions, or nested functions.
Hooks should always be called at the top level of a React function to ensure that they are executed in the same order each time the component renders. This consistent order is crucial for React to correctly manage the state and effects associated with the Hooks.

// Correct usage
function MyComponent() {
const [count, setCount] = useState(0);

// Hook called at the top level
useEffect(() => {
console.log(count);
}, [count]);
}

// Incorrect usage
function MyComponent() {
if (someCondition) {
// Hook inside a condition (Incorrect)
useEffect(() => {
console.log("This might break");
}, []);
}
}

Only Call Hooks from React Functions​

Do not call Hooks from regular JavaScript functions.
Hooks can only be called from within React functional components or custom Hooks. They should not be used in regular JavaScript functions or outside of component bodies.

// Correct usage
function MyComponent() {
const [state, setState] = useState(0);
return <div>{state}</div>;
}

// Incorrect usage
function notAComponent() {
// Hook called outside a component (Incorrect)
const [state, setState] = useState(0);
}

Use Hooks in the Same Order​

Always use Hooks in the same order during each render.
React relies on the order in which Hooks are called to maintain the correct state for each Hook. If the order changes between renders, it can cause state and effect management issues.

// Correct usage
function MyComponent() {
useState(0); // First Hook
useEffect(() => {
// Side effect
}, []); // Second Hook
}

// Incorrect usage
function MyComponent() {
if (someCondition) {
useEffect(() => {
// This can break the order (Incorrect)
}, []);
}
useState(0); // The order is inconsistent
}

Custom Hooks Should Start with use​

Name custom Hooks with a "use" prefix.
This naming convention ensures that React can identify them as Hooks and enforce the rules above.

// Correct usage
function useCustomHook() {
const [state, setState] = useState(0);
return state;
}

// Incorrect usage
function customHook() {
// Should start with "use"
const [state, setState] = useState(0);
return state;
}

By adhering to these rules, you can leverage the full power of React Hooks while maintaining predictable and bug-free component behavior.

What is the use of useEffect React Hooks?​

The useEffect React Hook is used for performing the side effects in functional components. With the help of useEffect, you will inform React that your component requires something to be done after rendering the component or after a state change. The function you have passed(can be referred to as “effect”) will be remembered by React and call afterwards the performance of DOM updates is over. Using this, we can perform various calculations such as data fetching, setting up document title, manipulating DOM directly, etc, that don’t target the output value. The useEffect hook will run by default after the first render and also after each update of the component. React will guarantee that the DOM will be updated by the time when the effect has run by it.

The useEffect React Hook will accept 2 arguments: useEffect(callback[, dependencies]);

Where the first argument callback represents the function having the logic of side-effect and it will be immediately executed after changes were being pushed to DOM. The second argument dependencies represent an optional array of dependencies. The useEffect() will execute the callback only if there is a change in dependencies in between renderings.

Example:

import { useEffect } from "react";
function WelcomeGreetings({ name }) {
const msg = `Hi, ${name}!`; // Calculates output
useEffect(() => {
document.title = `Welcome to you ${name}`; // Side-effect!
}, [name]);
return <div>{msg}</div>; // Calculates output
}

The above code will update the document title which is considered to be a side-effect as it will not calculate the component output directly. That is why updating of document title has been placed in a callback and provided to useEffect().

Consider you don’t want to execute document title update each time on rendering of WelcomeGreetings component and you want it to be executed only when the name prop changes then you need to supply name as a dependency to useEffect(callback, [name]).

Why do React Hooks make use of refs?​

React Hooks make use of refs (useRef) to allow access to the DOM elements or to persist values across renders without causing re-renders.
Here’s why and how refs are used in React Hooks

Accessing DOM Elements​

Direct manipulation of DOM elements
In React, you generally interact with the DOM through declarative code. However, there are scenarios where you need direct access to a DOM element, for example, focusing an input field, measuring its size, or triggering animations. useRef provides a way to hold a reference to a DOM element in functional components.

import React, { useRef, useEffect } from "react";

function FocusInput() {
const inputRef = useRef(null);

useEffect(() => {
// Directly access the DOM element to focus it
inputRef.current.focus();
}, []);

return <input ref={inputRef} />;
}

Persisting Values Between Renders​

Avoiding re-renders
Unlike state, changing the value of a ref does not trigger a component re-render. This makes refs useful for persisting values between renders, such as holding a timer ID, caching previous state values, or tracking mutable values like form inputs.

function Timer() {
const timerIdRef = useRef(null);

const startTimer = () => {
timerIdRef.current = setInterval(() => {
console.log("Timer tick");
}, 1000);
};

const stopTimer = () => {
clearInterval(timerIdRef.current);
};

return (
<div>
<button onClick={startTimer}>Start</button>
<button onClick={stopTimer}>Stop</button>
</div>
);
}

Storing Mutable Values Without Re-rendering​

Avoiding unnecessary re-renders
You can use refs to store mutable values that might need to be updated frequently without causing the component to re-render. This is useful for situations like holding a counter or keeping track of whether a component is mounted.

function Component() {
const countRef = useRef(0);

const incrementCount = () => {
countRef.current += 1;
console.log(`Count: ${countRef.current}`);
};

return <button onClick={incrementCount}>Increment</button>;
}

Tracking Previous State or Props​

Accessing previous values
You can use refs to keep track of the previous state or props, which might be needed for comparison or other logic without triggering a re-render

function Component({ value }) {
const prevValueRef = useRef();

useEffect(() => {
prevValueRef.current = value;
}, [value]);

const prevValue = prevValueRef.current;

return (
<div>
Current: {value}, Previous: {prevValue}
</div>
);
}

Summary​

Refs in React Hooks are powerful for

  • Directly accessing and manipulating DOM elements.
  • Storing and persisting mutable values across renders without causing re-renders.
  • Tracking previous state or props for comparison.
  • This makes useRef a versatile tool for managing component behavior beyond the typical state and prop management, especially in cases where you need to interact with the DOM or manage values that don’t need to trigger a re-render.

Explain Strict Mode in React.​

StrictMode is a tool added in version 16.3 of React to highlight potential problems in an application. It performs additional checks on the application.

function App() {
return (
<React.StrictMode>
<div classname="App">
<Header />
<div>Page Content</div>
<Footer />
</div>
</React.StrictMode>
);
}
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
rootElement,
);

StrictMode currently helps with the following issues:

Identifying components with unsafe lifecycle methods:

Certain lifecycle methods are unsafe to use in asynchronous react applications. With the use of third-party libraries, it becomes difficult to ensure that certain lifecycle methods are not used.
StrictMode helps in providing us with a warning if any of the class components use an unsafe lifecycle method.
Warning about the usage of legacy string API:

If one is using an older version of React, callback ref is the recommended way to manage refs instead of using the string refs. StrictMode gives a warning if we are using string refs to manage refs.
Warning about the usage of findDOMNode:

Previously, findDOMNode( ) method was used to search the tree of a DOM node. This method is deprecated in React. Hence, the StrictMode gives us a warning about the usage of this method.
Warning about the usage of legacy context API (because the API is error-prone).

What are the different ways to style a React component?​

There are many different ways through which one can style a React component. Some of the ways are :

Inline Styling: We can directly style an element using inline style attributes. Make sure the value of style is a JavaScript object:

class RandomComponent extends React.Component {
render() {
return (
<div>
<h3 style={{ color: "Yellow" }}>This is a heading</h3>
<p style={{ fontSize: "32px" }}>This is a paragraph</p>
</div>
);
}
}

Using JavaScript object: We can create a separate JavaScript object and set the desired style properties. This object can be used as the value of the inline style attribute.

class RandomComponent extends React.Component {
paragraphStyles = {
color: "Red",
fontSize: "32px",
};

headingStyles = {
color: "blue",
fontSize: "48px",
};

render() {
return (
<div>
<h3 style={this.headingStyles}>This is a heading</h3>
<p style={this.paragraphStyles}>This is a paragraph</p>
</div>
);
}
}

CSS Stylesheet: We can create a separate CSS file and write all the styles for the component inside that file. This file needs to be imported inside the component file.

import "./RandomComponent.css";

class RandomComponent extends React.Component {
render() {
return (
<div>
<h3 className="heading">This is a heading</h3>
<p className="paragraph">This is a paragraph</p>
</div>
);
}
}

CSS Modules: We can create a separate CSS module and import this module inside our component. Create a file with “.module.css”‘ extension, styles.module.css:

.paragraph {
color: "red";
border: 1px solid black;
}

We can import this file inside the component and use it:

import styles from "./styles.module.css";

class RandomComponent extends React.Component {
render() {
return (
<div>
<h3 className="heading">This is a heading</h3>
<p className={styles.paragraph}>This is a paragraph</p>
</div>
);
}
}

Name a few techniques to optimize React app performance.​

Using useMemo( ) - It is a React hook that is used for caching CPU-Expensive functions.
Sometimes in a React app, a CPU-Expensive function gets called repeatedly due to re-renders of a component, which can lead to slow rendering.
useMemo( ) hook can be used to cache such functions. By using useMemo( ), the CPU-Expensive function gets called only when it is needed.
Using React.PureComponent -
It is a base component class that checks the state and props of a component to know whether the component should be updated.
Instead of using the simple React.Component, we can use React.PureComponent to reduce the re-renders of a component unnecessarily.
Maintaining State Colocation -
This is a process of moving the state as close to where you need it as possible.
Sometimes in React app, we have a lot of unnecessary states inside the parent component which makes the code less readable and harder to maintain. Not to forget, having many states inside a single component leads to unnecessary re-renders for the component.
It is better to shift states which are less valuable to the parent component, to a separate component.
Lazy Loading -
It is a technique used to reduce the load time of a React app. Lazy loading helps reduce the risk of web app performances to a minimum.

Does React Hook work with static typing?​

Static typing refers to the process of code check during the time of compilation for ensuring all variables will be statically typed. React Hooks are functions that are designed to make sure about all attributes must be statically typed. For enforcing stricter static typing within our code, we can make use of the React API with custom Hooks.

Explain about types of Hooks in React.​

  1. Built-in Hooks: The built-in Hooks are divided into 2 parts as given below:
  • Basic Hooks: useState(): This functional component is used to set and retrieve the state.
    useEffect(): It enables for performing the side effects in the functional components.
    useContext(): It is used for creating common data that is to be accessed by the components hierarchy without having to pass the props down to each level.

  • Additional Hooks: useReducer() : It is used when there is a complex state logic that is having several sub-values or when the upcoming state is dependent on the previous state. It will also enable you to optimization of component performance that will trigger deeper updates as it is permitted to pass the dispatch down instead of callbacks.
    useMemo() : This will be used for recomputing the memoized value when there is a change in one of the dependencies. This optimization will help for avoiding expensive calculations on each render.
    useCallback() : This is useful while passing callbacks into the optimized child components and depends on the equality of reference for the prevention of unneeded renders.
    useImperativeHandle(): It will enable modifying the instance that will be passed with the ref object.
    useDebugValue(): It is used for displaying a label for custom hooks in React DevTools.
    useRef() : It will permit creating a reference to the DOM element directly within the functional component.
    useLayoutEffect(): It is used for the reading layout from the DOM and re-rendering synchronously.

  1. Custom Hooks:
    A custom Hook is basically a function of JavaScript.
    The Custom Hook working is similar to a regular function. The “use” at the beginning of the Custom Hook Name is required for React to understand that this is a custom Hook and also it will describe that this specific function follows the rules of Hooks. Moreover, developing custom Hooks will enable you for extracting component logic from within reusable functions.

How does the performance of using Hooks differ in comparison with the classes?​

  • React Hooks will avoid a lot of overheads such as the instance creation, binding of events, etc., that are present with classes.
  • Hooks in React will result in smaller component trees since they will be avoiding the nesting that exists in HOCs (Higher Order Components) and will render props which result in less amount of work to be done by React.

What is React Router?​

React Router refers to the standard library used for routing in React. It permits us for building a single-page web application in React with navigation without even refreshing the page when the user navigates. It also allows to change the browser URL and will keep the user interface in sync with the URL. React Router will make use of the component structure for calling the components, using which appropriate information can be shown. Since React is a component-based framework, it’s not necessary to include and use this package. Any other compatible routing library would also work with React.

The major components of React Router are given below:

BrowserRouter: It is a router implementation that will make use of the HTML5 history API (pushState, popstate, and event replaceState) for keeping your UI to be in sync with the URL. It is the parent component useful in storing all other components.
Routes: It is a newer component that has been introduced in the React v6 and an upgrade of the component.
Route: It is considered to be a conditionally shown component and some UI will be rendered by this whenever there is a match between its path and the current URL.
Link: It is useful in creating links to various routes and implementing navigation all over the application. It works similarly to the anchor tag in HTML.

Can React Hook replace Redux?​

The React Hook cannot be considered as a replacement for Redux (It is an open-source, JavaScript library useful in managing the application state) when it comes to the management of the global application state tree in large complex applications, even though the React will provide a useReducer hook that manages state transitions similar to Redux.
Redux is very useful at a lower level of component hierarchy to handle the pieces of a state which are dependent on each other, instead of a declaration of multiple useState hooks.

In commercial web applications which is larger, the complexity will be high, so using only React Hook may not be sufficient. Few developers will try to tackle the challenge with the help of React Hooks and others will combine React Hooks with the Redux.

Explain conditional rendering in React.​

Conditional rendering refers to the dynamic output of user interface markups based on a condition state. It works in the same way as JavaScript conditions. Using conditional rendering, it is possible to toggle specific application functions, API data rendering, hide or show elements, decide permission levels, authentication handling, and so on.

There are different approaches for implementing conditional rendering in React. Some of them are:

Using if-else conditional logic which is suitable for smaller as well as for medium-sized applications
Using ternary operators, which takes away some amount of complication from if-else statements
Using element variables, which will enable us to write cleaner code.

How to create a switching component for displaying different pages?​

A switching component refers to a component that will render one of the multiple components. We should use an object for mapping prop values to components.

A below-given example will show you how to display different pages based on page prop using switching component:

import HomePage from './HomePage'
import AboutPage from './AboutPage'
import FacilitiesPage from './FacilitiesPage'
import ContactPage from './ContactPage'
import HelpPage from './HelpPage'
const PAGES = {
home: HomePage,
about: AboutPage,
facilitiess: FacilitiesPage,
contact: ContactPage
help: HelpPage
}
const Page = (props) => {
const Handler = PAGES[props.page] || HelpPage
return <Handler {...props} />
}
// The PAGES object keys can be used in the prop types for catching errors during dev-time.
Page.propTypes = {
page: PropTypes.oneOf(Object.keys(PAGES)).isRequired
}

How to re-render the view when the browser is resized?​

It is possible to listen to the resize event in componentDidMount() and then update the width and height dimensions. It requires the removal of the event listener in the componentWillUnmount() method. Using the below-given code, we can render the view when the browser is resized.

class WindowSizeDimensions extends React.Component {
constructor(props) {
super(props);
this.updateDimension = this.updateDimension.bind(this);
}

componentWillMount() {
this.updateDimension();
}
componentDidMount() {
window.addEventListener("resize", this.updateDimension);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateDimension);
}
updateDimension() {
this.setState({ width: window.innerWidth, height: window.innerHeight });
}
render() {
return (
<span>
{this.state.width} x {this.state.height}
</span>
);
}
}

How to perform automatic redirect after login?​

The react-router package will provide the component <Redirect> in React Router. Rendering of a <Redirect> component will navigate to a newer location. In the history stack, the current location will be overridden by the new location just like the server-side redirects.

import React, { Component } from "react";
import { Redirect } from "react-router";
export default class LoginDemoComponent extends Component {
render() {
if (this.state.isLoggedIn === true) {
return <Redirect to="/your/redirect/page" />;
} else {
return <div>{"Please complete login"}</div>;
}
}
}