Frequently asked - React JS Interview Questions and Answers - Part 01
1. What is React?
React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called “components”. React is developed by Facebook.
React doesn’t replace our views, it wants to augment them by allowing us to create highly reusable UI components (like tab bars, comment boxes, pop up modals, lists, sortable tables, etc). However, React is capable of becoming an entire replacement for our views because we can nest components. For example, a web page that is entirely rendered by React will look like below:
<HomePage>
<Header selected="home" />
<Slider />
<MoreInfo />
<p>Enter your info below if you want to get in touch!</p>
<ContactForm />
<Footer />
</HomePage>
2. How React works? How Virtual-DOM works in React?
React creates a virtual DOM. When state changes in a component it firstly runs a “diffing” algorithm, which identifies what has changed in the virtual DOM. The second step is reconciliation, where it updates the DOM with the results of diff.
The HTML DOM is always tree-structured - which is allowed by the structure of HTML document. The DOM trees are huge nowadays because of large apps. Since we are more and more pushed towards dynamic web apps (Single Page Applications - SPAs), we need to modify the DOM tree incessantly and a lot. And this is a real performance and development pain.
The Virtual DOM is an abstraction of the HTML DOM. It is lightweight and detached from the browser-specific implementation details. It is not invented by React but it uses it and provides it for free. ReactElements
lives in the virtual DOM. They make the basic nodes here. Once we defined the elements, ReactElements
can be render into the “real” DOM.
Whenever a ReactComponent
is changing the state, diff algorithm in React runs and identifies what has changed. And then it updates the DOM with the results of diff. The point is - it’s done faster than it would be in the regular DOM.
3. What are the pros and cons of using React?
Every libraries and frameworsk has some pors and cons and React is no exception. Here are the pros of using React:
-
Virtual DOM in ReactJS makes user experience better and developer’s work faster - Unlike other frameworks that work with the Real DOM, ReactJS uses its abstract copy of the Virtual DOM. It updates even minimalistic changes applied by the user, but doesn’t affect other parts of interface.
-
Reusable React components significantly saves time - ReactJS components are isolated and change in one doesn’t affect others. This allows for reusing components that do not produce changes in and of themselves to make programming more precise, ergonomic, and comfortable for developers.
-
One-direction data flow in ReactJS provides a stable code - ReactJS allows for direct work with components and uses downward data binding to ensure that changes of child structures don’t affect their parents. That makes code stable.
-
An open-source library: constantly developing and open to contributions - ReactJS was one of the first JavaScript-connected projects released as open source by Facebook. Now ReactJS is 7th in Trending on GitHub with over 67,000 stars. And, there are more than 1000 open-source contributors working with the library., Some of the cons:
-
High pace of development - The environment constantly changes, and developers must regularly relearn the new ways of doing things. Everything is evolving, and some developers are not comfortable with keeping up with such a pace.
-
Poor documentation - Developers struggle with integrating new tools like Redux or Reflux tools with ReactJS. Some members of the community think that React technologies are updating and accelerating so fast that there is no time to write proper instruction.
-
JSX as a barrier - ReactJS uses JSX. It’s a syntax extension, which allows mixing HTML with JavaScript. JSX has its own benefits (for instance, protecting code from injections), but some members of the development community consider JSX to be a serious disadvantage.
4. What is JSX?
JSX is a syntax extension to JavaScript and comes with the full power of JavaScript. JSX produces React “elements”. You can embed any JavaScript expression in JSX by wrapping it in curly braces. After compilation, JSX expressions become regular JavaScript objects. This means that you can use JSX inside of if statements and for loops, assign it to variables, accept it as arguments, and return it from functions. Eventhough React does not require JSX, it is the recommended way of describing our UI in React app.
For example, below is the syntax for a basic element in React with JSX and its equivalent without it.
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
Equivalent of the above using React.createElement
const element = React.createElement(
'h1',
{"className": "greeting"},
'Hello, world!'
);
5. What is React.createClass
?
React.createClass
allows us to generate component “classes.” But with ES6, React allows us to implement component classes that use ES6 JavaScript classes. The end result is the same — we have a component class. But the style is different. And one is using a “custom” JavaScript class system (createClass) while the other is using a “native” JavaScript class system.
When using React’s createClass()
method, we pass in an object as an argument. So we can write a component using createClass
that looks like this:
import React from 'react';
const Contacts = React.createClass({
render() {
return (
<div></div>
);
}
});
export default Contacts;
Using an ES6 class to write the same component is a little different. Instead of using a method from the react
library, we extend an ES6 class that the library defines, Component
.
import React from 'react';
class Contacts extends React.Component({
constructor(props) {
super(props);
}
render() {
return (
<div></div>
);
}
}
export default Contacts;
constructor()
is a special function in a JavaScript class. JavaScript invokes constructor()
whenever an object is created via a class.
6. What is React.createElement
?
React.createElement
is used to create React nodes using JavaScript. An example is as follows:
var reactNodeLi = React.createElement('li', {id:'li1'}, 'one');
The React.createElement()
arguments are explained below:
- type (string |
React.createClass()
): - Can be a string which represents an HTML element (or custom HTML element) or React component instance (i.e., an instance ofReact.createClass()
) - props (null | object): - Can be
null
or an object containing attributes/props and values - children (null | string |
React.createClass()
|React.createElement()
): - Children can benull
, a string that gets turned into a text node, an instance ofReact.createClass()
orReact.createElement()
,
7. What is ReactDOM
and what is the difference between ReactDOM
and React
?
Prior to v0.14, all ReactDOM
functionality was part of React
. But later, React
and ReactDOM
were split into two different libraries.
As the name implies, ReactDOM
is the glue between React and the DOM. Often, we will only use it for one single thing: mounting with ReactDOM
. Another useful feature of ReactDOM
is ReactDOM.findDOMNode()
which we can use to gain direct access to a DOM element.
For everything else, there’s React
. We use React to define and create our elements, for lifecycle hooks, etc. i.e. the guts of a React application.
8. What is the difference between a Presentational component and a Container component?
Presentational components are concerned with how things look. They generally receive data and callbacks exclusively via props. These components rarely have their own state, but when they do it generally concerns UI state, as opposed to data state.
Container components are more concerned with how things work. These components provide the data and behavior to presentational or other container components. They call Flux actions and provide these as callbacks to the presentational components. They are also often stateful as they serve as data sources.
For a better understanding, the component below is having both a presentation and data concern which is not a good idea.
import React from "react";
class BooksList extends React.Component {
constructor() {
super();
this.state = { books: [] }
}
componentDidMount() {
fetch("/my-books.json")
.then(res => res.json())
.then(books => this.setState({ books }))
}
render() {
return (
<ul>
{this.state.books.map(({ title, author }) =>
<li>{title}-{author}</li>
)}
</ul>
);
}
}
It would then be split into two components. The first is like a traditional template, concerned only with presentation.
// BookList.js
import React from "react";
const Booklist = books => (
<ul>
{books.map(({ title, author }) =>
<li>{title}-{author}</li>
)}
</ul>
)
The second is tasked with fetching data and rendering the related view component.
// BookListContainer.js
import React from "react";
import BookList from "./BookList";
class BookListContainer extends React.Component {
constructor() {
super();
this.state = { comments: [] }
}
componentDidMount() {
fetch("/my-books.json")
.then(res => res.json())
.then(books => this.setState({ books }))
}
render() {
return <Booklist books={this.state.books} />;
}
}
9. What are the differences between a class component and functional component?
Class components allows us to use additional features such as local state and lifecycle hooks. Also, to enable our component to have direct access to our store and thus holds state.
When our component just receives props and renders them to the page, this is a ‘stateless component’, for which a pure function can be used. These are also called dumb components or presentational components.
From the previous question, we can say that our Booklist
component is functional components and are stateless.
// BookList.js
import React from "react";
const Booklist = books => (
<ul>
{books.map(({ title, author }) =>
* {title}-{author}</li>
)}
</ul>
)
On the other hand, the BookListContainer
component is a class component.
10. What is the difference between state and props?
The state is a data structure that starts with a default value when a Component mounts. It may be mutated across time, mostly as a result of user events.
Props (short for properties) are a Component’s configuration. Props are how components talk to each other. They are received from above component and immutable as far as the Component receiving them is concerned. A Component cannot change its props, but it is responsible for putting together the props of its child Components. Props do not have to just be data - callback functions may be passed in as props.
There is also the case that we can have default props so that props are set even if a parent component doesn’t pass props down.
Class SearchBar extends Component {
constructor(props) {
super(props);
this.state = { term: '' };
}
render() {
return (
<div className="search-bar">
<input
value={this.state.term}
onChange={event => this.onInputChange(event.target.value)} />
</div>
);
}
onInputChange(term) {
this.setState({term});
this.props.onSearchTermChange(term);
}
}
Props and State do similar things but are used in different ways. The majority of our components will probably be stateless. Props are used to pass data from parent to child or by the component itself. They are immutable and thus will not be changed. State is used for mutable data, or data that will change. This is particularly useful for user input.
11. Name the different React lifecycle methods.
React offers many lifecycle methods that we can hook and they are as follows:
componentWillMount
- This is most commonly used for App configuration in our root component. At this state, there is no component to play with yet, so we can’t do anything involving the DOM.componentDidMount
- After called the component is mounted and ready to be used. Here we want to do all the setup we couldn’t do without a DOM, and start getting all the data you need. Also if we want to set up eventListeners etc. this lifecycle hook is a good place to do that. This is also a good place to start AJAX calls to load in data for our component since there is a component to update.componentWillReceiveProps
- This lifecyclye acts on particular prop changes to trigger state transitions. Whenever a mew property is being passed down and before our component does anything with the new props,componentWillReceiveProps
is called, with the next props as the argument. We can check if the props will change in a way that is significant, and then act on it.componentWillReceiveProps
is not called on initial render. That is the component is receiving props, but there aren’t any old props to compare to, so doesn’t count. We can callthis.setState
to change the component state.shouldComponentUpdate
- Whenever we have new properties,shouldComponentUpdate
method called withnextProps
as the first argument, andnextState
is the second. We can check thenextProps
andnextState
with currentprops
andstate
and decide whether the component can update or not. It should always return a boolean value and default is true. It is an awesome place to improve performance.componentWillUpdate
- It can be used instead ofcomponentWillReceiveProps
on a component that also hasshouldComponentUpdate
. But it has no access to previous props. Functionally, it’s basically the same ascomponentWillReceiveProps<//code>, except we are not allowed to call
this.setState`. It is rarely used.componentDidUpdate
- It is commonly used to update the DOM in response toprop
orstate
changes.componentWillUnmount
- Here, we can cancel any outgoing network requests, or remove all event listeners associated with the component. Basically, clean up anything to do that solely involves the component in question.
12. Where in a React component should you make an AJAX request?
componentDidMount
is where an AJAX request should be made in a React component. This method will be executed when the component “mounts” (is added to the DOM) for the first time. This method is only executed once during the component’s life. Importantly, we can’t guarantee the AJAX request will have resolved before the component mounts. If it doesn’t, that would mean that we would be trying to setState
on an unmounted component, which would not work. Making our AJAX request in componentDidMount
will guarantee that there’s a component to update.
13. What are controlled components?
In HTML, form elements such as <input>
, <textarea>
, and <select>
typically maintain their own state and update it based on user input. When a user submits a form the values from the aforementioned elements are sent with the form. With React it works differently. The component containing the form will keep track of the value of the input in it’s state and will re-render the component each time the callback function e.g. onChange
is fired as the state will be updated. A form element whose value is controlled by React in this way is called a “controlled component”.
With a controlled component, every state mutation will have an associated handler function. This makes it straightforward to modify or validate user input.
14. What are refs used for in React?
Refs are used to get reference to a DOM node or an instance of a component in React. Good examples of when to use refs are for managing focus/text selection, triggering imperative animations, or integrating with third-party DOM libraries. You should avoid using string refs and inline ref callbacks. Callback refs are advised by React.
Refs are created using React.createRef()
and attached to React
elements via the ref
attribute. Refs are commonly assigned to an instance property when a component is constructed so they can be referenced throughout the component.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
When a ref is passed to an element in render
, a reference to the node becomes accessible at the current
attribute of the ref.
const node = this.myRef.current;
The value of the ref differs depending on the type of the node:
- When the
ref
attribute is used on an HTML element, theref
created in the constructor withReact.createRef()
receives the underlying DOM element as itscurrent
property. - When the
ref
attribute is used on a custom class component, theref
object receives the mounted instance of the component as itscurrent
. - We may not use the ref attribute on functional components because they don’t have instances.
15. What is a higher order component?
A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API. They are a pattern that emerges from React’s compositional nature.
A higher-order component is a function that takes a component and returns a new component.
HOC’s allow you to reuse code, logic and bootstrap abstraction. HOCs are common in third-party React libraries. The most common is probably Redux’s connect function. Beyond simply sharing utility libraries and simple composition, HOCs are the best way to share behavior between React Components. If you find yourself writing a lot of code in different places that does the same thing, you may be able to refactor that code into a reusable HOC.
16. How do you pass data from child to parent component?
If we have some data in child that the parent needs access to, we can do the following:
- Define a callback in parent which takes the data we need in as a parameter.
- Pass that callback as a prop to the child (see above).
- Call the callback using
this.props.[callback]
in the child, and pass in the data as the argument., The parent component:
class ParentComponent extends React.Component{
state: { language: '' }
handleLanguage = (langValue) => {
this.setState({language: langValue});
}
render() {
return (
<div className="col-sm-9">
<SelectLanguage onSelectLanguage={this.handleLanguage}/>>
</div>
)
}
}
The child component:
export class SelectLanguage extends React.Component {
state = {
selectedCode: '',
selectedLanguage: jsonArray[0],
}
handleLangChange = () => {
var lang = this.dropdown.value;
this.props.onSelectLanguage(lang);
}
render() {
return (
<div>
<DropdownList ref={(ref) => this.dropdown = ref}
data={jsonArray}
valueField='lang' textField='lang'
caseSensitive={false}
minLength={3}
filter='contains'
onChange={this.handleLangChange} />
</div>
);
}
}
17. How do you this
in constructor?
If we use React.createClass
, React autobinds all functions to this
. So the this
keyword is bound to our component’s instance automatically:
//This works inside React.createClass
onChange={this.handleChange}
However, with the advent of ES6 classes, this non-standard approach to creating classes isn’t the future of React. If we are using ES6 class, React no longer autobinds. we can follow one of the below.
One way to resolve this
is to call bind in render:
onChange={this.handleChange.bind(this)}
This approach is clear, however, there are performance implications since the function is reallocated on every render. Another approach is using Arrow functions. This approach has the same potential performance impact as above approach.
onChange={e => this.handleChange(e)}
One way to avoid binding in render is to bind in the constructor.
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
This is the approach currently recommended in the React docs for “better performance in our application”.
Lastly, use Arrow Function in Class Property.
handleChange = () => {
// call this function from render
// and this.whatever in here works fine.
};
18. When rendering a list what is a key and what is it’s purpose?
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity. The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys. When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort. It is not recommend to use indexes for keys if the items can reorder, as that would be slow.
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
If we run the above code without the key
in li
, we will get a warning that a key should be provided for list items.
The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. When we don’t have stable IDs for rendered items, we can use the item index
as a key as a last resort.
19. What’s the difference between super()
and super(props)
in React when using ES6 classes?
The React documentation says “Class components should always call the base constructor with props.”. However, there are no reasons provided. But we can speculate it is either because of subclassing or for future compatibility.
But When we want to access this.props
in constructor, we must pass props
to super()
. Consider the below example:
class MyComponent extends React.Component {
constructor(props) {
super(props)
// passed props
console.log(this.props)
// can access this.props -> { icon: 'home', � }
}
}
If we don’t pass the props
:
class MyComponent extends React.Component {
constructor(props) {
super()
// Not passed props
console.log(this.props)
// Can not access this.props -> undefined
// Props parameter is still available
console.log(props)
// -> { icon: 'home', � }
}
render() {
// No difference outside constructor
console.log(this.props)
// -> { icon: 'home', � }
}
}
20. What is Children
?
In JSX expressions that contain both an opening tag and a closing tag, the content between those tags is passed to components automatically as a special prop: props.children
.
The core of React is components. We can nest these components like we would nest HTML tags. Let’s say we have a <Grid />
component which can contain <Row />
components. We’d use it like so:
<Grid>
<Row />
<Row />
<Row />
</Grid>
These three Row components are passed to the Grid component as props.children. Using an expression container parents can render their children:
class Grid extends React.Component {
render() {
return <div>{this.props.children}</div>
}
}
There are a number of methods available in the React API to work with this prop. These include React.Children.map
, React.Children.forEach
, React.Children.count
, React.Children.only
, React.Children.toArray
.