Common React interview questions and vetted, eloquent answers to rehearse

Alex Booker - Nov 23 '20 - - Dev Community

If you want to land a great React job in 2021, this is the post for you 😌.

I'm bringing you this post on the back of Scrimba's new React Interview Questions module with the awesome @Cassidoo πŸŽ‰.

In that course, Cassidoo draws on her professional experience working at Netlify (and before that, CodePen) to share 26 likely React interview questions and example answers.

You're reading an epic 4500 word version of those same common React interview questions and example answers. Use this as a quick reference or as an exercise to rehearse your answers aloud. I have also included a React Interview questions PDF on the Scrimba blog, in case you'd like something to download and print 😎.

Here, I'm listing the same questions plus vetted answers for you to adapt. Use this as inspiration to phrase eloquent and confident answers that will WOW 🀩 your soon-to-be employer.

For each question, I aim to highlight:

  • πŸ”‘ The key thing to mention in your answer
  • πŸ“ Where to learn more if you happen to identify a gap in your knowledge
  • ⛔️ In some cases, I'll also mention common wrong answers for you to avoid at all costs

Without further ado, here are the questions (listed in the same order that they appear in the module, in case you'd like to use these resources together):

React DOM

What is the difference between the virtual DOM and the real DOM?

The DOM represents an HTML document as a tree structure wherein each node represents part of the document (for example, an element, element attribute, or text):

Using vanilla JavaScript and the DOM API, you can access any element you like (for example, using document.getElementById) and update it directly.

When you do this, the browser traverses the DOM and re-renders each node - even if that node hasn't changed since the previous render. This can be noticeably inefficient 😳

Imagine a scenario where you need to update only one tr of 10,000 in a table. Rendering all 10,000 rows will almost certainly lead to a drop in frames, potentially causing the table to flicker and interrupt the user's experience.

This is where React's virtual DOM (VDOM) comes into play βœ….

React increases your UI's performance by building a "virtual" representation of the DOM (a VDOM πŸ˜‰) to keep track of all the changes it needs to make to the real DOM.

Every time your app's state updates, React builds a new VDOM and diffs with the previous VDOM to determine what changes are necessary before updating the DOM directly and efficiently:

  • πŸ”‘ The important thing to mention here is diffing. If you want to flex a little, you can describe this process by its technical name, which is reconciliation (React reconciles the newly-built VDOM with the previous one)
  • πŸ“ Learn more
  • ⛔️ A common misconception is that the VDOM is a React feature. This is not true! VDOM is a programming concept that predates React and is adopted by many UI libraries, including Vue

Is the virtual DOM the same as the shadow DOM?

In a word, no.

Whereas the virtual DOM is a programming concept implemented by React predominantly to increase rendering performance, the Shadow DOM is a browser technology designed for scoping variables and CSS in web components.

The virtual DOM and Shadow DOM sound similar in name, but that is where the similarity begins and ends - they are totally unrelated.

  • πŸ”‘ Show the interviewer you can think critically about which tool you apply to which problems rather than blindly reaching for React
  • πŸ“ Learn more
    • As a bonus, you can learn about the limitations of React Native - many teams find the "write once run everywhere" idea alluring until they try it

React limitations

What are the limitations of React?

No tool is without its limitations, and React is no exception.

Weighing in at 133kb, React is considered to be a relatively heavy dependency. By comparison, Vue is 58kb. For this reason, React could be considered overkill for small apps.

Comparing React and Vue in file size feels fair because they're both libraries as opposed to frameworks.

Compared to a framework like Angular, React doesn't enforce strong opinions about how to write and structure your code or about which libraries to use for things like data fetching - with Angular, team members will instinctively reach for Angular's built-in HttpClient, whereas with React, teams depend on additional data-fetching libraries like Axios or Fetch.

Because React does not enforce opinions about how to best structure code, teams need to be especially diligent about writing code consistently so that the project can evolve deliberately. This can lead to communication overhead and steepen the learning curve for newbies.

These are important considerations to make when embarking on a new project. Once you commit to React, one limitation is that the documentation is not always linear or up to date πŸ˜‰.

  • πŸ”‘ Show the interviewer you can think critically about which tool you apply to which problems rather than blindly reaching for React
  • πŸ“ Learn more
    • As a bonus, you can learn about the limitations of React Native - many teams find the "write once run everywhere" idea alluring until they try it

JSX

What is JSX?

Similar in appearance to XML and HTML, JavaScript XML (JSX) is used to create elements using a familiar syntax.

JSX is an extension to JavaScript understood only by preprocessors like Babel. Once encountered by a preprocessor, this HTML-like text is converted into regular old function calls to React.createElement:

Can you write React without JSX?

In a word, yes.

JSX is not part of the ECMAScript specification, and therefore no web browser actually understands JSX.

Rather, JSX is an extension to the JavaScript language only understood by preprocessors like Babel.

When a preprocessor encounters some JSX code, it converts the HTML-like syntax into regular old function calls to React.createElement:

React.createElement is part of React's public top-level API just like React.component or React.useRef (to name a couple). Nothing is stopping you from invoking React.createElement in your own code should you choose ✊

  • πŸ”‘ JSX is syntactic sugar for the React.createElement function meaning you you could call React.createElement directly (that does not necessarily mean you should)

Props

How do you pass a value from parent to child?

Pass the value as a prop!

How do you pass a value from child to parent?

To pass a value from a child component to its parent component, the parent must first supply a function for the child component to call with the value. An example would be a custom form component.

Imagine a custom form component to select a language called SelectLanguage.

When the language is selected, we'd like to pass that value back UP to the parent for processing.

To do this, the SelectLanguage child component would need to accept a callback function as a prop, which it can then call with the value. A likely name for this kind of function would be onLanguageSelect.

  • πŸ”‘ Pass a function prop to the child, which the child can call. The best way to communicate this in your answer is with an example like a SelectLanguage component props
  • πŸ“ Learn more:

What is prop drilling?

Prop drilling is where you pass props from some FirstComponent to another SecondComponent, which does not actually need the data and only passes it to another ThirdComponent and maybe beyond.

Prop drilling is sometimes called threading and is considered to be a slippery slope if not an anti-pattern 😱.

Imagine drilling a prop 5, 10, maybe more (!) levels deep - that code would quickly become difficult to understand. The trap happens when you need to share data across many different components - data like locale preference, theme preference, or user data.

While prop drilling is not inherently bad, there are normally more eloquent and maintainable solutions to explore like creating compound components ✳️ or using React Context however, these solutions are not without their limitations.

Can a child component modify its own props?

Nu-huh.

A component can update its own state but cannot update its own props.

Think about it like this: Props belong to the parent component, not the child component - a child component has no business modifying a value it does not own. Props are, therefore, read-only.

Attempting to modify props will either cause obvious problems or, worse, put your React app in a subtly unstable state.
React dictates that to update the UI, update state.

  • πŸ”‘ React needs you to treat props as read-only (even if there are ways of messing with them)
  • πŸ“ Learn more
    • This StackOverflow answer uses example code to illustrate what can happen if you mess with props from a child component
    • While a child cannot update its own props, the value of those props can change if the parent changes them through a state change. Despite the sensational (possibly confusing) title, This FreeCodeCamp post shows a familiar example of what this pattern looks like

State and lifecycle

What is the difference between props and state?

Props are essentially options you initialize a child component with. These options (if you like) belong to the parent component and must not be updated by the child component receiving them.

State, on the other hand, belongs to and is managed by the component.

State is always initiated with a default value, and that value can change over the lifetime of the component in response to events like user input or network responses. When state changes, the component responds by re-rendering.

State is optional, meaning some components have props but no state. Such components are known as stateless components.

  • πŸ”‘ props and state are similar in that they both hold information that influenes the output of a render however, props get paseed to the component (similar to function parameters) whereas state is managed within the component (similar to variables declared within a function).
  • πŸ“ Learn more

How does state in a class component differ from state in a functional component?

State in a class component belongs to the class instance (this), whereas state in a functional component is preserved by React between renders and recalled each time.

In a class component, the initial state is set within the component's constructor function then accessed or set using this.state and this.setState() respectively.

In a functional component, state is managed using the useState Hook. useState accepts an argument for its initial state before returning the current state and a function that updates the state as a pair.

What is the component lifecycle?

React components have 4 distinct phases of "life":

  • 🌱 First, the component is initialized and mounted on the DOM
  • 🌲 Over time the component is updated
  • πŸ‚ Eventually, the component is unmounted or removed from the DOM

Using lifecycle methods in a class component or the useEffect Hook in a functional component, we can run code at particular times in a component's life.

For example, in a class component, we might implement componentDidMount and write code to set-up a new web socket connection. As real-time web socket data trickles in, state is updated, and, in turn, the render lifecycle method is run to update the UI. When the component is no longer needed, we close the web socket connection by implementing componentWillUnmount.

  • πŸ”‘ React components have several lifecycle methods that you can override to run code at particular times in the component's life. Knowing all the functions isn't a bad idea, but it's more important that you can explain when you'd use each. Some lifecycle methods are pretty uncommon, so you're unlikely to have experience with them. Don't lead the interviewer down this path if you don't need to.
  • πŸ“ Learn more

How do you update lifecycle in function components?

Using the useEffect Hook!

You can think of the useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.

Effects

What arguments does useEffect take?

useEffect takes two arguments.

The first argument is a function called effect and is what gives the useEffect Hook its name.

The second argument is an optional array called dependencies and allows you to control when exactly the effect function is run. Think of a dependencies as variables (typically state variables) that the effect function references and therefore depends on.

If you choose not to specify any dependencies, React will default to running the effect when the component is first mounted and after every completed render. In most cases, this is unnecessary, and it would be better to run the effect only if something has changed.

This is where the optional dependencies argument comes in βœ….

When dependencies is present, React compares the current value of dependencies with the values used in the previous render. effect is only run if dependencies has changed ✊

If you want effect to run only once (similar to componentDidMount), you can pass an empty array ([]) to dependencies.

When does the useEffect function run?

When useEffect runs exactly depends on the dependencies array argument:

  • If you pass an empty array ([]), the effect runs when the component is mounted (similar to componentDidMount)
  • If you pass an array of state variables ([var]), the effect runs when the component is mounted, and anytime the values of these variables change
  • If you omit the dependencies argument, the effect is run when the component is mounted and on each state change

That is about the sum of it!

What is the useEffect function's return value?

The useEffect function takes two arguments - an effect function and an optional dependencies array.

The effect function returns either nothing (undefined) or a function we can call cleanup.

This cleanup function executes before the component is removed from the UI to prevent memory likes (similar to componentWillUnmount).

Additionally, if a component renders multiple times (as they typically do), the previous effect is cleaned up before executing the next effect.

Refs

What is the difference between refs and state variables?

Both refs and state variables provide a way to persist values between renders; however, only state variables trigger a re-render.

While refs were traditionally (and still are) used to access DOM elements directly (for example, when integrating with a third-party DOM library), it has become increasingly common to use refs in functional components to persist values between renders that should not trigger a re-render when the value is updated.

There isn't much reason to use refs for this reason in class components because it's more natural to store these values in fields that belong to the class instance and would be persisted between renders regardless.

When is the best time to use refs?

Only use refs when necessary!

Refs are mostly used in one of two ways.

One use of refs is to access a DOM element directly to manipulate it - an example would be when implementing a third-party DOM library. Another example might be to trigger imperative animations.

The second use of refs is in functional components, where they are sometimes a good choice of utility to persist values between renders without triggering the component to re-render if the value changes.

When someone is new to React, refs often feel familiar to them because they are used to freely writing imperative code. For this reason, beginners tend to overreach for refs. We know better. We know that to get the most from React, we must think in React and ideally control every piece of our app with state and component hierarchy. The React documentation describes refs as an "escape hatch" for a good reason!

What is the proper way to update a ref in a function component?

Using the useRef hook!

Context

What is the difference between the context API and prop drilling?

In React, you explicitly pass data from parent component to child components through props.

If the child component that needs the data happens to be deeply nested, we sometimes resort to prop-drilling, which can be a slippery slope. This is often the case when data is shared across many different components - data like locale preference, theme preference, or user data (like the authentication state).

Conversely, the Context API affords us a central data store, which we can implicitly access to consume data from any component without needing to request it as a prop explicitly.

The implicit nature of the Context API allows for terser code that is easier to manage but can also lead to "gotchas!" if the value is updated unexpectedly as it won't be so easy to trace the value and learn where it was modified linearly.

When shouldn't you use the context API?

The Context API's main downside is that every time the context changes, all components consuming the value re-render. This may have negative performance consequences.

For this reason, you should only use Context for infrequently updated data like a theme preference.

Miscellaneous (but important!) questions

What is a Fragment?

Fragment is a newly-introduced component that supports returning multiple children from a component's render method without needing an extraneous div element.

You can either reference it using React's top-level API (React.Fragment) or using JSX syntactic sugar (<>).

  • πŸ”‘ Instead of returning a div from a component's render method, we can instead return a Fragment
  • πŸ“ Learn more

When should you create class-based component versus a function component?

In the world of React, there are two ways of creating React components. One is to use a class that derives from React.Component and the other is to use a functional component with Hooks.

Before Hooks' advent in 2018, it wasn't possible to substitute class-based components with functional components - mainly because there was no way to set state and remember values between renders without writing a class.

With Hooks, classes and functional components are generally interchangeable, and as we enter the new year, the trend is clear: functional components are on the rise and for good reasons πŸ“ˆ.

Functional components unlock all the advantages of hooks, including ease of use, testability, and cleaner code.

At the time of this writing, there are no Hook equivalents to the (uncommon) getSnapshotBeforeUpdate, getDerivedStateFromError, and componentDidCatch lifecycle methods, but they are coming "soon."

  • πŸ”‘ Class components and functional components are mostly interchangeable. Choose whichever the codebase is already using for consistency. For new projects, use Hooks unless you need a lifecycle method Hooks don't yet support.
  • πŸ“ Learn more

What is a higher order component?

A higher-order component (HOC) is a function that takes a component and returns a new, modified component.

While HOCs are associated with React, they aren't a React feature so much as a pattern inspired by a functional programming pattern called higher-order functions whereby you also pass functions to functions.

You can write custom HOCs or import them from libraries.
One example of an open source HOC is React Sortable HOC, whereby you pass a list component (based on ul) and receive an enhanced ul with sorting and drag and drop capabilities.

What is portal?

React ordinarily has one mounting point - the HTML element you pass to ReactDOM.render. From here, React adds new elements to the page in a hierarchy.

Occasionally, you need to break out of this hierarchy.
Imagine a small About component with a button to open a modal. Because the modal "spills" out of the container, this not only feels unnatural, it can also be finicky to pull off because the About component might already have overflow: hidden set or a deliberate z-index.

This is where portal comes in βœ… .

Portal and the createPortal function provide you with a way to render children in an additional mounting point (in addition to the main mounting point passed to ReactDOM.render).

You're not too likely to read or write code using Portal in your own project.

Portal is mainly used when a parent component has an overflow: hidden or z-index, but you need the child to visually "break out" of its container.

Examples include modals, tooltips, and dialogs; however, we normally use third-party components for these things anyway, meaning we're unlikely to need to write Portal code ourselves.

  • πŸ”‘ Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component
  • πŸ“ Learn more

What are uncontrolled and controlled components?

A controlled component is an input component like an input, textarea or select whose value is controlled by React.

Conversely, an uncontrolled component manages its own state - the component is not controlled by React and is, therefore, "uncontrolled".

Imagine if you chuck a textarea on the page and start typing.

Anything you type will be stored in the textarea automatically and accessible through its value property. Although React can access the value with a ref, React does not control the value here. This would be an example of an uncontrolled component.

To take control of this component in React, you would need to subscribe to the textareas onChange event and update a state variable (for example, one called input) in response.

Now React is managing the textareas value, you must also take responsibility for setting the textareas value property also. This way, the content of the textarea can be updated by updating state. It's easy to imagine a function called clearTextArea that sets the input state variable to an empty string causing the textarea to clear.

  • πŸ”‘ The names "controlled component" and "uncontrolled component" are unnecessarily broad. More specific names would be "controlled input component" and "uncontrolled input component" Narrowing your answer to focus on input components will ensure you answer the question eloquently..
  • πŸ“ Learn more
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .