« React interview questions

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

window.removeEventListener('resize', this.updateDimension)

How to pass data between react components?

Parent Component to Child Component (using props)

1import ChildComponent from './Child';
2function ParentComponent(props) {
3 let [counter, setCounter] = useState(0);
4
5 let increment = () => setCounter(++counter);
6
7 return (
8 <div>
9 <button onClick={increment}>Increment Counter</button>
10 <ChildComponent counterValue={counter} />
11 </div>
12 );
13}
14
15function ChildComponent(props) {
16 return (
17 <div>
18 <p>Value of counter: {props.counterValue}</p>
19 </div>
20 );
21}

Child Component to Parent Component (using callbacks)

We follow the steps below:

  • Create a callback in the parent component which takes in the data needed as a parameter.
  • Pass this callback as a prop to the child component.
  • Send data from the child component using the callback.
1function ParentComponent(props) {
2 let [counter, setCounter] = useState(0);
3 let callback = (valueFromChild) => setCounter(valueFromChild);
4 return (
5 <div>
6 <p>Value of counter: {counter}</p>
7 <ChildComponent callbackFunc={callback} counterValue={counter} />
8 </div>
9 );
10}
11
12function ChildComponent(props) {
13 let childCounterValue = props.counterValue;
14 return (
15 <div>
16 <button onClick={() => props.callbackFunc(++childCounterValue)}>
17 Increment Counter
18 </button>
19 </div>
20 );
21}

Name a few techniques to optimize React app performance.

There are many ways through which one can optimize the performance of a React app, let’s have a look at some of them:

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 app performances to a minimum.

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.

1function App() {
2 return (
3 <React.StrictMode>
4 <div classname='App'>
5 <Header />
6 <div>Page Content</div>
7 <Footer />
8 </div>
9 </React.StrictMode>
10 );
11}

To enable StrictMode, React.StrictMode tags need to be added inside the application:

1import React from 'react';
2import ReactDOM from 'react-dom';
3import App from './App';
4const rootElement = document.getElementById('root');
5ReactDOM.render(
6 <React.StrictMode>
7 <App />
8 </React.StrictMode>,
9 rootElement
10);

What are Custom Hooks?

A Custom Hook is a function in Javascript whose name begins with ‘use’ and which calls other hooks. It is a part of React v16.8 hook update and permits you for reusing the stateful logic without any need for component hierarchy restructuring.

In almost all of the cases, custom hooks are considered to be sufficient for replacing render props and HoCs (Higher-Order components) and reducing the amount of nesting required. Custom Hooks will allow you for avoiding multiple layers of abstraction or wrapper hell that might come along with Render Props and HoCs.

The disadvantage of Custom Hooks is it cannot be used inside of the classes.

Why do React Hooks make use of refs?

The refs are used for:

  • Managing focus, media playback, or text selection.
  • Integrating with DOM libraries by third-party.
  • Triggering the imperative animations.

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

There are 2 rules which must be followed while you code with Hooks:

  • React Hooks must be called only at the top level. It is not allowed to call them inside the nested functions, loops, or conditions.
  • It is allowed to call the Hooks only from the React Function Components.

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.

Explain React Hooks.

What are Hooks? Hooks are functions that let us “hook into” React state and lifecycle features from a functional component.

React Hooks cannot be used in class components. They let us write components without class.

Why were Hooks introduced in React?

React hooks were introduced in the 16.8 version of React. Previously, functional components were called stateless components. Only class components were used for state management and lifecycle methods. The need to change a functional component to a class component, whenever state management or lifecycle methods were to be used, led to the development of Hooks.

What is React Hooks?

React Hooks are the built-in functions that permit developers for using the state and lifecycle methods within React components. These are newly added features made available in React 16.8 version. Each lifecycle of a component is having 3 phases which include mount, unmount, and update. Along with that, components have properties and states. Hooks will allow using these methods by developers for improving the reuse of code with higher flexibility navigating the component tree.

Using Hook, all features of React can be used without writing class components. For example, before React version 16.8, it required a class component for managing the state of a component. But now using the useState hook, we can keep the state in a functional component.

error boundary is a component using one or both of the following methods: static getDerivedStateFromError and componentDidCatch.

1class ErrorBoundary extends React.Component {
2 constructor(props) {
3 super(props);
4 this.state = { hasError: false };
5 }
6 static getDerivedStateFromError(error) {
7 return { hasError: true };
8 }
9 componentDidCatch(error, errorInfo) {
10 logErrorToMyService(error, errorInfo);
11 }
12 render() {
13 if (this.state.hasError) {
14 return <h4>Something went wrong</h4>;
15 }
16 return this.props.children;
17 }
18}
1<ErrorBoundary>
2 <CounterComponent />
3</ErrorBoundary>

What is prop drilling in React?

Sometimes while developing React applications, there is a need to pass data from a component that is higher in the hierarchy to a component that is deeply nested. To pass data between such components, we pass props from a source component and keep passing the prop to the next component in the hierarchy till we reach the deeply nested component.

The disadvantage of using prop drilling is that the components that should otherwise be not aware of the data have access to the data.

Note- Props are read-only. They cannot be manipulated or changed inside a component.

What are the differences between controlled and uncontrolled components?

Controlled component:

In a controlled component, the value of the input element is controlled by React. We store the state of the input element inside the code, and by using event-based callbacks, any changes made to the input element will be reflected in the code as well. When a user enters data inside the input element of a controlled component, onChange function gets triggered and inside the code, we check whether the value entered is valid or invalid. If the value is valid, we change the state and re-render the input element with the new value.

1function FormValidation(props) {
2 let [inputValue, setInputValue] = useState('');
3 let updateInput = (e) => {
4 setInputValue(e.target.value);
5 };
6 return (
7 <div>
8 <form>
9 <input type='text' value={inputValue} onChange={updateInput} />
10 </form>
11 </div>
12 );
13}

Uncontrolled component:

In an uncontrolled component, the value of the input element is handled by the DOM itself. Input elements inside uncontrolled components work just like normal HTML input form elements. The state of the input element is handled by the DOM. Whenever the value of the input element is changed, event-based callbacks are not called. Basically, react does not perform any action when there are changes made to the input element.

1function FormValidation(props) {
2 let inputValue = React.createRef();
3 let handleSubmit = (e) => {
4 alert(`Input value: ${inputValue.current.value}`);
5 e.preventDefault();
6 };
7 return (
8 <div>
9 <form onSubmit={handleSubmit}>
10 <input type='text' ref={inputValue} />
11 <button type='submit'>Submit</button>
12 </form>
13 </div>
14 );
15}

What is the virtual DOM? How does react use the virtual DOM to render the UI?

As stated by the react team, virtual DOM is a concept where a virtual representation of the real DOM is kept inside the memory and is synced with the real DOM by a library such as ReactDOM.

DOM manipulation is an integral part of any web application, but DOM manipulation is quite slow when compared to other operations in JavaScript. The efficiency of the application gets affected when several DOM manipulations are being done. Most JavaScript frameworks update the entire DOM even when a small part of the DOM changes.

For example, consider a list that is being rendered inside the DOM. If one of the items in the list changes, the entire list gets rendered again instead of just rendering the item that was changed/updated. This is called inefficient updating.

To address the problem of inefficient updating, the react team introduced the concept of virtual DOM.

React uses two virtual DOMs to render the user interface. One of them is used to store the current state of the objects and the other to store the previous state of the objects. Whenever the virtual DOM gets updated, react compares the two virtual DOMs and gets to know about which virtual DOM objects were updated. After knowing which objects were updated, react renders only those objects inside the real DOM instead of rendering the complete real DOM. This way, with the use of virtual DOM, react solves the problem of inefficient updating.

Note- One may think updating every virtual DOM object might be inefficient, but that’s not the case. Updating the virtual DOM is much faster than updating the real DOM since we are just updating the blueprint of the real DOM.

What is JSX?

JSX stands for JavaScript XML. It allows us to write HTML inside JavaScript and place them in the DOM without using functions like appendChild( ) or createElement( ).

As stated in the official docs of React, JSX provides syntactic sugar for React.createElement( ) function.

Note- We can create react applications without using JSX as well.

Let’s understand how JSX works:

Without using JSX, we would have to create an element by the following process:

1const text = React.createElement('p', {}, 'This is a text');
2const container = React.createElement('div', '{}', text);
3ReactDOM.render(container, rootElement);

Using JSX, the above code can be simplified:

1const container = (
2 <div>
3 <p>This is a text</p>
4 </div>
5);
6ReactDOM.render(container, rootElement);

As one can see in the code above, we are directly using HTML inside JavaScript.

Importance of keys -

  • Keys help react identify which elements were added, changed or removed.
  • Keys should be given to array elements for providing a unique identity for each element.
  • Without keys, React does not understand the order or uniqueness of each element.
  • With keys, React has an idea of which particular element was deleted, edited, and added.
  • Keys are generally used for displaying a list of data coming from an API.

Note- Keys used within arrays should be unique among siblings. They need not be globally unique.

What are Higher Order Components?

Simply put, Higher-Order Component(HOC) is a function that takes in a component and returns a new component.

When do we need a Higher Order Component?

While developing React applications, we might develop components that are quite similar to each other with minute differences. In most cases, developing similar components might not be an issue but, while developing larger applications we need to keep our code DRY, therefore, we want an abstraction that allows us to define this logic in a single place and share it across components. HOC allows us to create that abstraction.

1function HOC(WrappedComponent, selectData) {
2 return class extends React.Component {
3 constructor(props) {
4 super(props);
5 this.handleChange = this.handleChange.bind(this);
6 this.state = {
7 data: selectData(GlobalDataSource, props),
8 };
9 }
10 componentDidMount() {
11 // Listens to the changes added
12 GlobalDataSource.addChangeListener(this.handleChange);
13 }
14 componentWillUnmount() {
15 // Listens to the changes removed
16 GlobalDataSource.removeChangeListener(this.handleChange);
17 }
18 handleChange() {
19 this.setState({
20 data: selectData(GlobalDataSource, this.props),
21 });
22 }
23 render() {
24 // Rendering the wrapped component with the latest data data
25 return <WrappedComponent data={this.state.data} {...this.props} />;
26 }
27 };
28}