Question-21. Explain Strict Mode in React.

Answer- 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 MyApp() {
 return (
   <React.StrictMode>
     <div classname="App">
       <Header/>
       <div>
         Page Content
       </div>
       <Footer/>
     </div>
   </React.StrictMode>
 );
}

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

import React from "react";
import ReactDOM from "react-dom";
import App from "./MyApp";
const rootElement = document.getElementById("root");
ReactDOM.render(
<React.StrictMode>
  <MyApp />
</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).

Question-22. How to prevent re-renders in React?

  • Reason for re-renders in React:
    • Re-rendering of a component and its child components occur when props or the state of the component has been changed.
    • Re-rendering components that are not updated, affects the performance of an application.
  • How to prevent re-rendering:

Consider the following components:

class MyParent extends React.Component {
state = { messageDisplayed: false };
componentDidMount() {
  this.setState({ messageDisplayed: true });
}
render() {
  console.log("Parent is getting rendered");
  return (
    <div className="App">
      <Message />
    </div>
  );
}
}
class MyMessage extends React.Component {
constructor(props) {
  super(props);
  this.state = { message: "Hello, this is vivek" };
}  
render() {
  console.log("Message is getting rendered");
  return (
    <div>
      <p>{this.state.message}</p>
    </div>
  );
}
}
  • The Parent component is the parent component and the Message is the child component. Any change in the parent component will lead to re-rendering of the child component as well. To prevent the re-rendering of child components, we use the shouldComponentUpdate( ) method:

**Note- Use shouldComponentUpdate( ) method only when you are sure that it’s a static component.

class MyMessage extends React.Component {
constructor(props) {
  super(props);
  this.state = { message: "Hello, this is vivek" };
}
shouldComponentUpdate() {
  console.log("Does not get rendered");
  return false;
}
render() {
  console.log("Message is getting rendered");
  return (
    <div>
      <p>{this.state.message}</p>
    </div>
  );
}
}

As one can see in the code above, we have returned false from the shouldComponentUpdate( ) method, which prevents the child component from re-rendering.

Question-23. What are the different ways to style a React component?

Answer- 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 MyRandomComponent 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 MyRandomComponent 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 './MyRandomComponent.css';

class MyRandomComponent 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 MyRandomComponent extends React.Component {
 render() {
   return (
     <div>
       <h3 className="heading">This is a heading</h3>
       <p className={styles.paragraph} >This is a paragraph</p>
     </div>
   );
 }
}

Question-24. Name a few techniques to optimize React app performance.

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

Question-25. How to pass data between react components?

Answer- Parent Component to Child Component (using props)

With the help of props, we can send data from a parent to a child component.

How do we do this?

Consider the following Parent Component:

import MyChildComponent from "./Child";
   function ParentComponent(props) {
    let [counter, setCounter] = useState(0);
   
    let increment = () => setCounter(++counter);
   
    return (
      <div>
        <button onClick={increment}>Increment Counter</button>
        <ChildComponent counterValue={counter} />
      </div>
    );
   }

As one can see in the code above, we are rendering the child component inside the parent component, by providing a prop called counterValue. The value of the counter is being passed from the parent to the child component.

We can use the data passed by the parent component in the following way:

function MyChildComponent(props) {
return (
  <div>
    <p>Value of counter: {props.counterValue}</p>
  </div>
);
}

We use the props.counterValue to display the data passed on by the parent component.

Child Component to Parent Component (using callbacks)

This one is a bit tricky. 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.

We are considering the same example above but in this case, we are going to pass the updated counterValue from child to parent.

Step1 and Step2: Create a callback in the parent component, pass this callback as a prop.

function MyParentComponent(props) {
let [counter, setCounter] = useState(0);
let callback = valueFromChild => setCounter(valueFromChild);
return (
  <div>
    <p>Value of counter: {counter}</p>
    <ChildComponent callbackFunc={callback} counterValue={counter} />
  </div>
);
}

As one can see in the code above, we created a function called callback which takes in the data received from the child component as a parameter.

Next, we passed the function callback as a prop to the child component.

Step3: Pass data from the child to the parent component.

function MyChildComponent(props) {
let childCounterValue = props.counterValue;
return (
  <div>
    <button onClick={() => props.callbackFunc(++childCounterValue)}>
      Increment Counter
    </button>
  </div>
);
}

In the code above, we have used the props.counterValue and set it to a variable called childCounterValue.

Next, on button click, we pass the incremented childCounterValue to the props.callbackFunc.

This way, we can pass data from the child to the parent component.

Question-26. What are Higher Order Components?

Answer- 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.

Example of a HOC:

Consider the following components having similar functionality. The following component displays the list of articles:

// "GlobalDataSource" is some global data source
class MyArticlesList extends React.Component {
 constructor(props) {
   super(props);
   this.handleChange = this.handleChange.bind(this);
   this.state = {
     Myarticles: GlobalDataSource.MygetArticles(),
   };
 }
 componentDidMount() {
   // Listens to the changes added
   GlobalDataSource.addChangeListener(this.handleChange);
 }
 componentWillUnmount() {
   // Listens to the changes removed
   GlobalDataSource.removeChangeListener(this.handleChange);
 }
 handleChange() {
   // States gets Update whenver data source changes
   this.setState({
     Myarticles: GlobalDataSource.getArticles(),
   });
 }
 render() {
   return (
     <div>
       {this.state.articles.map((article) => (
         <ArticleData article={article} key={article.id} />
       ))}
     </div>
   );
 }
}

The following component displays the list of users:

// "GlobalDataSource" is some global data source
class MyUsersList extends React.Component {
 constructor(props) {
   super(props);
   this.handleChange = this.handleChange.bind(this);
   this.state = {
     users: GlobalDataSource.getUsers(),
   };
 }
 componentDidMount() {
   // Listens to the changes added
   GlobalDataSource.addChangeListener(this.handleChange);
 }
 componentWillUnmount() {
   // Listens to the changes removed
   GlobalDataSource.removeChangeListener(this.handleChange);
 }
 handleChange() {
   // States gets Update whenver data source changes
   this.setState({
     users: GlobalDataSource.getUsers(),
   });
 }
 render() {
   return (
     <div>
       {this.state.users.map((user) => (
         <UserData user={user} key={user.id} />
       ))}
     </div>
   );
 }
}

Notice the above components, both have similar functionality but, they are calling different methods to an API endpoint.

Let’s create a Higher Order Component to create an abstraction:

// Higher Order Component which takes a component
// as input and returns another component
// "GlobalDataSource" is some global data source
function MyHOC(WrappedComponent, selectData) {
 return class extends React.Component {
   constructor(props) {
     super(props);
     this.handleChange = this.handleChange.bind(this);
     this.state = {
       data: selectData(GlobalDataSource, props),
     };
   }
   componentDidMount() {
     // Listens to the changes added
     GlobalDataSource.addChangeListener(this.handleChange);
   }
   componentWillUnmount() {
     // Listens to the changes removed
     GlobalDataSource.removeChangeListener(this.handleChange);
   }
   handleChange() {
     this.setState({
       data: selectData(GlobalDataSource, this.props),
     });
   }
   render() {
     // Rendering the wrapped component with the latest data data
     return <WrappedComponent data={this.state.data} {...this.props} />;
   }
 };
}

We know HOC is a function that takes in a component and returns a component.

In the code above, we have created a function called HOC which returns a component and performs functionality that can be shared across both the ArticlesList component and UsersList Component.

The second parameter in the HOC function is the function that calls the method on the API endpoint.

We have reduced the duplicated code of the componentDidUpdate and componentDidMount functions.

Using the concept of Higher-Order Components, we can now render the ArticlesList and UsersList components in the following way:

const ArticlesListWithHOC = HOC(ArticlesList, (GlobalDataSource) => GlobalDataSource.getArticles());
const UsersListWithHOC = HOC(UsersList, (GlobalDataSource) => GlobalDataSource.getUsers());

Remember, we are not trying to change the functionality of each component, we are trying to share a single functionality across multiple components using HOC.

Question-27. What are the different phases of the component lifecycle?

Answer- There are four different phases in the lifecycle of React component. They are:

  • Initialization: During this phase, React component will prepare by setting up the default props and initial state for the upcoming tough journey.
  • Mounting: Mounting refers to putting the elements into the browser DOM. Since React uses VirtualDOM, the entire browser DOM which has been currently rendered would not be refreshed. This phase includes the lifecycle methods componentWillMount and componentDidMount.
  • Updating: In this phase, a component will be updated when there is a change in the state or props of a component. This phase will have lifecycle methods like componentWillUpdateshouldComponentUpdaterender, and componentDidUpdate.
  • Unmounting: In this last phase of the component lifecycle, the component will be removed from the DOM or will be unmounted from the browser DOM. This phase will have the lifecycle method named componentWillUnmount.

Question-28. What are the lifecycle methods of React?

Answer- React lifecycle hooks will have the methods that will be automatically called at different phases in the component lifecycle and thus it provides good control over what happens at the invoked point. It provides the power to effectively control and manipulate what goes on throughout the component lifecycle.For example, if you are developing the YouTube application, then the application will make use of a network for buffering the videos and it consumes the power of the battery (assume only these two). After playing the video if the user switches to any other application, then you should make sure that the resources like network and battery are being used most efficiently. You can stop or pause the video buffering which in turn stops the battery and network usage when the user switches to another application after video play.

So we can say that the developer will be able to produce a quality application with the help of lifecycle methods and it also helps developers to make sure to plan what and how to do it at different points of birth, growth, or death of user interfaces.

The various lifecycle methods are:

  • constructor(): This method will be called when the component is initiated before anything has been done. It helps to set up the initial state and initial values.
  • getDerivedStateFromProps(): This method will be called just before element(s) rendering in the DOM. It helps to set up the state object depending on the initial props. The getDerivedStateFromProps() method will have a state as an argument and it returns an object that made changes to the state. This will be the first method to be called on an updating of a component.
  • render(): This method will output or re-render the HTML to the DOM with new changes. The render() method is an essential method and will be called always while the remaining methods are optional and will be called only if they are defined.
  • componentDidMount(): This method will be called after the rendering of the component. Using this method, you can run statements that need the component to be already kept in the DOM.
  • shouldComponentUpdate(): The Boolean value will be returned by this method which will specify whether React should proceed further with the rendering or not. The default value for this method will be True.
  • getSnapshotBeforeUpdate(): This method will provide access for the props as well as for the state before the update. It is possible to check the previously present value before the update, even after the update.
  • componentDidUpdate(): This method will be called after the component has been updated in the DOM.
  • componentWillUnmount(): This method will be called when the component removal from the DOM is about to happen.

Question-29. Does React Hook work with static typing?

Answer- 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.

Question-30.Explain about types of Hooks in React.

Answer- There are two types of Hooks in React. They are: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.

2. 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.