Recently I had to come up with a list of interview questions to ask potential senior / intermediate candidates.
I tried to come up with questions that showed understanding of React issues and use cases rather than surface level memorization.
What problem does React solve?
React is a way to develop UIs in a predictable, declarative way. Rather than wiring up changes to the DOM yourself you simply describe what the UI should look like for a given state and React handles the DOM patching.
What is the role of the virtual dom in React, what problems does it attempt to solve?
React makes the assumption that DOM manipulation is expensive (kudos if they explain why) so it holds a copy of the DOM in an in memory data structure known as the virtual dom. Differences in the component tree between renders are computed against this virtual representation and React tries to apply the minimal number of changes to the DOM.
Speak briefly on the component lifecycle
At the very least should mention mounting, rendering, unmounting.
Extra points if they can talk about the class based lifecycle and why it is no longer as relevant.
In the context of React what does one way data flow refer to and what are some of the advantages / disadvantages of this?
One way data flow describes how information moves through a react application, information always moves down the tree from parent to child. One of the advantages of this is that it makes application state easier to reason about since we know information will either be local or coming from a parent node.
One of the disadvantages is that it makes communication between sibling components impossible without an intermediary (parent / state store / context)
Also makes prop drilling a thing, which isn't necessarily bad but can be messy.
Elaborate on a few common approaches to sharing state between sibling components
Lifting state up, using an outside store, react context.
How would you share state between components at different levels of the component tree?
Lifting state up, using an outside store, prop drilling is also an option but has the disadvantage of introducing noise into component APIs and potentially causing extra renders which can be an issue in performance critical applications.
React Context is also an option but setting the value of a context provider will cause the entire subtree to re-render so it is a tool which should be used for values which do not change as often and not for general state management (state usually changes frequently)
What is a pure component and why would you want to use one?
Pure components are components with no side-effects, this allows us to use shouldComponentUpdate or React.memo to compare props and prevent re-renders in performance critical parts of the application.
Pure components are not without cost, in some situations re-rendering the component without comparing props is faster than doing the comparison, this is especially true for smaller components.
In the context of a react component what is a key?
Keys are required when rendering a list of items.
Keys help react keep track of components between renders.
extra points: You can force react to unmount/mount a component by changing the component's key.
What problems do refs solve and when would you want to use them?
The value of the reference is persisted (stays the same) between component re-renders;
Updating a reference doesn't trigger a component re-render.
Refs provide a way to access DOM nodes or React elements created in the render method.
You would want to use refs for:
- Managing focus, text selection, or media playback.
- Triggering imperative animations.
- Integrating with third-party DOM libraries.
What is memoization and why would you want to use it?
Memoization is a programming technique that accelerates performance by caching the return values of expensive function calls. A “memoized” function will immediately output a pre-computed value if it’s given inputs that it’s seen before.
You would want to use it to store expensive components / values and make sure they are only computed when necessary. Memoizing trades memory for computation time.
Describe what the role of the useEffect hook is, how you would use it, and some common pitfalls.
useEffect is used to encapsulate "side-effects" such as data fetching, logging, handling route changes, etc..
useEffect takes in a dependency array and will re-run the body of the hook when those dependencies change.
You can provide a return function that will be called when when the dependencies change before the next body is called.
Gotchas around useEffect usually come from not passing in the required dependencies leading to stale values or from dependencies changing on every render.
How does the useEffect hook compare dependencies across renders and what does this mean for complex types?
useEffect uses reference / shallow equality for complex data types, this leads to a common "bug" in useEffect where the dependencies are complex types and are redeclared on each render, this can cause the effect to fire more times than the developer intends.