REACT INTERVIEW QUESTIONS.

Q-1: What is the difference between HTML and React event handling?
In HTML, the event name should be in lowercase:
<button onclick='activateLasers()'>
Whereas in React it follows camelCase convention:
<button onClick={activateLasers}>In HTML, you can return false to prevent default behavior:
<a href='#' onclick='console.log("The link was clicked."); return false;' />Whereas in React you must call preventDefault() explicitly:
function handleClick(event) {
event.preventDefault()
console.log('The link was clicked.')
}In HTML, you need to invoke the function by appending () Whereas in react you should not append () with the function name. (refer "activateLasers" function in the first point for example)
Q-2: How to bind methods or event handlers in JSX callbacks?
There are 3 possible ways to achieve this:
Binding in Constructor: In JavaScript classes, the methods are not bound by default. The same thing applies for React event handlers defined as class methods. Normally we bind them in constructor.
class Component extends React.Componenet {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
} handleClick() {
// ...
}
}Public class fields syntax: If you don’t like to use bind approach then public class fields syntax can be used to correctly bind callbacks.
handleClick = () => {
console.log('this is:', this)
}<button onClick={this.handleClick}>
{'Click me'}
</button>Arrow functions in callbacks: You can use arrow functions directly in the callbacks.
<button onClick={(event) => this.handleClick(event)}>
{'Click me'}
</button>Note: If the callback is passed as prop to child components, those components might do an extra re-rendering. In those cases, it is preferred to go with .bind() or public class fields syntax approach considering performance.
Q-3: What are synthetic events in React?
SyntheticEvent is a cross-browser wrapper around the browser's native event. It's API is same as the browser's native event, including stopPropagation() and preventDefault(), except the events work identically across all browsers.
Q-4: What are “key” props and what is the benefit of using them in arrays of elements?
A key is a special string attribute you should include when creating arrays of elements. Keys help React identify which items have changed, are added, or are removed.
Most often we use IDs from our data as keys:
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
)
When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort:
const todoItems = todos.map((todo, index) =>
<li key={index}>
{todo.text}
</li>
)
Note:
- Using indexes for keys is not recommended if the order of items may change. This can negatively impact performance and may cause issues with component state.
- If you extract list item as separate component then apply keys on list component instead of li tag.
- There will be a warning message in the console if the key prop is not present on list items.
Q-5: Which is preferred option with in callback refs and findDOMNode()?
It is preferred to use callback refs over findDOMNode() API. Because findDOMNode() prevents certain improvements in React in the future.
The legacy approach of using findDOMNode:
class MyComponent extends Component {
componentDidMount() {
findDOMNode(this).scrollIntoView()
} render() {
return <div />
}
}The recommended approach is:
class MyComponent extends Component {
constructor(props){
super(props);
this.node = createRef();
}
componentDidMount() {
this.node.current.scrollIntoView();
} render() {
return <div ref={this.node} />
}
}Q-6: What are uncontrolled components?
The Uncontrolled Components are the ones that store their own state internally, and you query the DOM using a ref to find its current value when you need it. This is a bit more like traditional HTML.
In the below UserProfile component, the name input is accessed using ref.
class UserProfile extends React.Component {
constructor(props) {
super(props)
this.handleSubmit = this.handleSubmit.bind(this)
this.input = React.createRef()
} handleSubmit(event) {
alert('A name was submitted: ' + this.input.current.value)
event.preventDefault()
} render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
{'Name:'}
<input type="text" ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}In most cases, it’s recommend to use controlled components to implement forms.
Q-7: What are the lifecycle methods of React?
React 16.3+
- getDerivedStateFromProps: Invoked right before calling render() and is invoked on every render. This exists for rare use cases where you need derived state. Worth reading if you need derived state.
- componentDidMount: Executed after first rendering and here all AJAX requests, DOM or state updates, and set up event listeners should occur.
- shouldComponentUpdate: Determines if the component will be updated or not. By default it returns true. If you are sure that the component doesn't need to render after state or props are updated, you can return false value. It is a great place to improve performance as it allows you to prevent a re-render if component receives new prop.
- getSnapshotBeforeUpdate: Executed right before rendered output is committed to the DOM. Any value returned by this will be passed into componentDidUpdate(). This is useful to capture information from the DOM i.e. scroll position.
- componentDidUpdate: Mostly it is used to update the DOM in response to prop or state changes. This will not fire if shouldComponentUpdate() returns false.
- componentWillUnmount It will be used to cancel any outgoing network requests, or remove all event listeners associated with the component.
Before 16.3
- componentWillMount: Executed before rendering and is used for App level configuration in your root component.
- componentDidMount: Executed after first rendering and here all AJAX requests, DOM or state updates, and set up event listeners should occur.
- componentWillReceiveProps: Executed when particular prop updates to trigger state transitions.
- shouldComponentUpdate: Determines if the component will be updated or not. By default it returns true. If you are sure that the component doesn't need to render after state or props are updated, you can return false value. It is a great place to improve performance as it allows you to prevent a re-render if component receives new prop.
- componentWillUpdate: Executed before re-rendering the component when there are props & state changes confirmed by shouldComponentUpdate() which returns true.
- componentDidUpdate: Mostly it is used to update the DOM in response to prop or state changes.
- componentWillUnmount: It will be used to cancel any outgoing network requests, or remove all event listeners associated with the component.
Q-8: What is the purpose of using super constructor with props argument?
A child class constructor cannot make use of this reference until super() method has been called. The same applies for ES6 sub-classes as well. The main reason of passing props parameter to super() call is to access this.props in your child constructors.
Passing props:
class MyComponent extends React.Component {
constructor(props) {
super(props) console.log(this.props) // prints { name: 'John', age: 42 }
}
}Not passing props:
class MyComponent extends React.Component {
constructor(props) {
super()console.log(this.props) // prints undefined
// but props parameter is still available
console.log(props) // prints { name: 'John', age: 42 }
}
render() {
// no difference outside constructor
console.log(this.props) // prints { name: 'John', age: 42 }
}
}The above code snippets reveals that this.props is different only within the constructor. It would be the same outside the constructor.
Q-9: What are error boundaries in React v16?
Error boundaries are components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed.
A class component becomes an error boundary if it defines a new lifecycle method called componentDidCatch(error, info) or static getDerivedStateFromError() :
class ErrorBoundary extends React.Component {
constructor(props) {
super(props)
this.state = { hasError: false }
} componentDidCatch(error, info) {
// You can also log the error to an error reporting service
logErrorToMyService(error, info)
} static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
} render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>{'Something went wrong.'}</h1>
}
return this.props.children
}
}After that use it as a regular component:
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
Q-10: What is ReactDOMServer?
The ReactDOMServer object enables you to render components to static markup (typically used on node server). This object is mainly used for server-side rendering (SSR). The following methods can be used in both the server and browser environments:
- renderToString()
- renderToStaticMarkup()
For example, you generally run a Node-based web server like Express, Hapi, or Koa, and you call renderToString to render your root component to a string, which you then send as response.
// using Express
import { renderToString } from 'react-dom/server'
import MyPage from './MyPage'
app.get('/', (req, res) => {
res.write('<!DOCTYPE html><html><head><title>My Page</title></head><body>')
res.write('<div id="content">')
res.write(renderToString(<MyPage/>))
res.write('</div></body></html>')
res.end()
})Q-11: What is CRA and its benefits?
The create-react-app CLI tool allows you to quickly create & run React applications with no configuration step.
Let’s create Todo App using CRA:
# Installation
$ npm install -g create-react-app
# Create new project
$ create-react-app todo-app
$ cd todo-app
# Build, test and run
$ npm run build
$ npm run test
$ npm start
It includes everything we need to build a React app:
- React, JSX, ES6, and Flow syntax support.
- Language extras beyond ES6 like the object spread operator.
- Autoprefixed CSS, so you don’t need -webkit- or other prefixes.
- A fast interactive unit test runner with built-in support for coverage reporting.
- A live development server that warns about common mistakes.
- A build script to bundle JS, CSS, and images for production, with hashes and sourcemaps.
Q-12: How to re-render the view when the browser is resized?
You can listen to the resize event in componentDidMount() and then update the dimensions (width and height). You should remove the listener in componentWillUnmount() method.
class WindowDimensions extends React.Component {
constructor(props){
super(props);
this.updateDimensions = this.updateDimensions.bind(this);
}
componentWillMount() {
this.updateDimensions()
} componentDidMount() {
window.addEventListener('resize', this.updateDimensions)
} componentWillUnmount() {
window.removeEventListener('resize', this.updateDimensions)
} updateDimensions() {
this.setState({width: window.innerWidth, height: window.innerHeight})
} render() {
return <span>{this.state.width} x {this.state.height}</span>
}
}Q-13: Is it possible to use React without rendering HTML?
It is possible with latest version (>=16.2). Below are the possible options:
render() {
return false
}render() {
return null
}render() {
return []
}render() {
return <React.Fragment></React.Fragment>
}render() {
return <></>
}Returning undefined won't work.
Q-13: Why function is preferred over object for setState()?
React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.
This counter example will fail to update as expected:
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
})
The preferred approach is to call setState() with function rather than object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument.
// Correct
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}))
Q-14: How to add Google Analytics for React Router?
Add a listener on the history object to record each page view:
history.listen(function (location) {
window.ga('set', 'page', location.pathname + location.search)
window.ga('send', 'pageview', location.pathname + location.search)
})Q-15: What is the benefit of styles modules?
It is recommended to avoid hard coding style values in components. Any values that are likely to be used across different UI components should be extracted into their own modules.
For example, these styles could be extracted into a separate component:
export const colors = {
white,
black,
blue
}export const space = [
0,
8,
16,
32,
64
]
And then imported individually in other components:
import { space, colors } from './styles'Q-16: How to make AJAX call and in which component lifecycle methods should I make an AJAX call?
You can use AJAX libraries such as Axios, jQuery AJAX, and the browser built-in fetch. You should fetch data in the componentDidMount() lifecycle method. This is so you can use setState() to update your component when the data is retrieved.
For example, the employees list fetched from API and set local state:
class MyComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
employees: [],
error: null
}
} componentDidMount() {
fetch('https://api.example.com/items')
.then(res => res.json())
.then(
(result) => {
this.setState({
employees: result.employees
})
},
(error) => {
this.setState({ error })
}
)
} render() {
const { error, employees } = this.state
if (error) {
return <div>Error: {error.message}</div>;
} else {
return (
<ul>
{employees.map(employee => (
<li key={employee.name}>
{employee.name}-{employee.experience}
</li>
))}
</ul>
)
}
}
}Q-17: What is React Router?
React Router is a powerful routing library built on top of React that helps you add new screens and flows to your application incredibly quickly, all while keeping the URL in sync with what’s being displayed on the page.
Q-18: How to get query parameters in React Router v4?
The ability to parse query strings was taken out of React Router v4 because there have been user requests over the years to support different implementation. So the decision has been given to users to choose the implementation they like. The recommended approach is to use query strings library.
const queryString = require('query-string');
const parsed = queryString.parse(props.location.search);You can also use URLSearchParams if you want something native:
const params = new URLSearchParams(props.location.search)
const foo = params.get('name')
You should use a polyfill for IE11.
Q-19: What are the two ways of formatting in React Intl?
The library provides two ways to format strings, numbers, and dates: react components or an API.
<FormattedMessage
id={'account'}
defaultMessage={'The amount is less than minimum balance.'}
/>
const messages = defineMessages({
accountMessage: {
id: 'account',
defaultMessage: 'The amount is less than minimum balance.',
}
})formatMessage(messages.accountMessage)
Q-20: How to format date using React Intl?
The injectIntl() higher-order component will give you access to the formatDate() method via the props in your component. The method is used internally by instances of FormattedDate and it returns the string representation of the formatted date.
import { injectIntl, intlShape } from 'react-intl'const stringDate = this.props.intl.formatDate(date, {
year: 'numeric',
month: 'numeric',
day: 'numeric'
})const MyComponent = ({intl}) => (
<div>{`The formatted date is ${stringDate}`}</div>
)MyComponent.propTypes = {
intl: intlShape.isRequired
}export default injectIntl(MyComponent)
Q-21: What is Jest?
Jest is a JavaScript unit testing framework created by Facebook based on Jasmine and provides automated mock creation and a jsdom environment. It's often used for testing components.