React is an open-source Javascript library developers use to build user interfaces (UIs) for web and mobile applications. Creating React applications usually requires the use of additional libraries and functionality, and so interviewing React candidates commonly consists of basic and advanced questions to assess technical ability. We sourced these questions from the React community based on developers’ own interview experience and what our clients found important to ask. Could you use help hiring React developers? Scalable Path’s experienced Talent Acquisition team can help.
These are the types of questions typically asked during React interviews. We created them to help you test your understanding of the popular programming language, or guide your initial technical screening with React candidates.
Preferred Solution
let myFunction = a=>b=>c=>a+b+c
(or)
Older Syntax
var myFunction = function(a){ return function(b){ return function(c){ return a+b+c } } }
Explanation, concepts, purposes
It is a curry function to add three numbers. Arrow function - is used for conciseness of code to improve readability. Currying - is the process of decomposing a function with more than one argument into multiple unary functions the last of which returns the final result (as below).
myFunction(3,4,5) -> myFunction(3)(4)(5)
It implicitly uses Closures to capture every argument passed till then so it is possible to send the resulting intermediate function elsewhere to further continue the chain until the final result is collected. Every curry function is a Partial Application but not vice versa.
A transpiler like Babel or Typescript is required to convert JSX into JavaScript since browser standards don't support rendering JSX. It transforms every React component in JSX to corresponding JavaScript syntax using the React.createElement function.
You can use a JSX pragma (a compiler directive) at the top of JSX file to tell Babel to use our custom function instead of React.createElement
/** @jsx myCustomCreateElement */
or, replace @babel/preset-react preset with our custom transformation logic written as Babel plugin in .babelrc file
from
{ "presets": ["@babel/preset-react"] }
to
{ "plugins":["./custom-jsx-transform-plugin", "./jsx-syntax-parser"] }
class Parent extends React.Component { render() { return ( <Child ctrlRef={el => this.inputElement = el} /> ); } } function Child(props) { return ( <div> <input ref={props.ctrlRef} /> </div> ); }
Parent passes its ref callback function as a prop (ctrlRef) to the Child, and the Child sets this to the ref attribute of the DOM element <input> whose reference is required. When the Parent renders, it gets the reference of the DOM node in this.inputElement, which it can now manipulate or read the value from.
When a component (Child) receives a ref and passes it down to its child (InnerChild).
function Child(props) { return ( <div> <input ref={props.ctrlRef} /> <InnerChild ref={props.ctrlRef} /> </div> ); }
Apart from having only one root reducer per application, a redux reducer function should: calculate the new state based only on the state and action arguments. It should also make immutable updates by taking a copy of the existing state and making changes to the copied values, rather than modifying the existing state. Lastly, it shouldn't do any asynchronous logic or other side effects (logging, saving, ajax calls, timers, etc.).
Since they “hook into” react state and lifecycle features from function components, react hooks allow us to avoid refactoring function components to class components to add state. They eliminate the need to bind methods with "this", and easily separate UI and logic, which promotes code reuse and maintainability. Lastly, they gather and wrap common "stateful" logic across components in one place (using custom hooks) and use it, instead of copy-pasting state logic at multiple components.
Initialization (R<16.4) - Not used in V16.4+
Mounting - In this phase, the component is added to the DOM for the first time (constructor is called and initial state and props set).
Updating - In this phase, the component undergoes subsequent props/state changes, this phase updates (re-render) back the DOM.
Unmounting - In this phase, the component is finally removed from the DOM.
An update can be caused by changes to props or state or when parent renders. These methods are called in the following order when a component is being re-rendered:
getDerivedStateFromProps() - Returns an object to update state from props during initial and subsequent mounts.
shouldComponentUpdate() - Returns false stop the render and subsequent methods.
render() - A pure function with no state change allowed and returns react element, fragments, portal, bool or null and builds virtualDOM tree using reconciliation (fiber).
getSnapshotBeforeUpdate() - Captures a snapshot of DOM before virtualDOM overwrites it.
componentDidUpdate() - After DOM is updated.
Components re-render if their state or props change or after their immediate parent component’s render.
For functional components, wrap it with React.memo, which is a HOC to ensure that the component is re-rendered only when its props change. For class components, extend from React.PureComponent instead of React.Components. When rendering list items, adding key props allows React to avoid re-rendering of items when added or removed. Avoid changes in the surrounding DOM structure (adding/removing containers). Avoid unintentional renders when functions or object literals are passed as props changes. Return false in the child component’s ShouldComponentUpdate() lifecycle function to prevent the render().
Inline, html <style> CSS
External .css file
Preprocessors (SASS,LESS)
CSS-in-JS (StyledComponents)
UI-kits (Bootstrap, Material-UI)
Utility-first CSS (Tailwind)
Modular CSS (BEM)
Utility-first CSS provides single-responsibility classes that are named according to their intended purpose and used to style custom components. They are preferred over ui-kit-based frameworks when:
Additionally, some Tailwind-specific advantages include:
While it largely depends on the project and company standards, generally the following organization makes sense for React projects:
Here are the steps to create a React app that syncs with changing data:
A render prop refers to a technique or pattern for passing a function as a prop from one component to another, though the prop name itself is not required to be "render".
< Mychild render={ () => <h1>hello from parent</h1> } />
Use Cases:
Caveats:
React.PureComponent, since shallow prop comparison always returns false and MyChild will always re-render.HOC is a pure component that accepts child/wrapped component(s) at runtime and returns a new component with additional behavior without mutating the original state or behavior of passed component(s) by the use of function composition.
HOC is used in frameworks for bootstrapping, cross-cutting concerns, and code reuse. It ensures the resulting component with added features to still have a similar interface of the wrapped component by passing through all props to the wrapped component(s).
const EnhancedComponent = higherOrderComponent(WrappedComponent);
Caveats of HOC include:
Props Collection returns an object collection of props while Props Getter returns a getter function that when invoked, returns the collection of props. Both are used when creating custom components or hooks that require returning a collection of props.
Props Getter is preferred when the collection needs to be modified or extended. Or when a caller can invoke a function with arguments to override or extend the collection of props returned.
React components pulled in as dynamic imports can be split across multiple bundle files by bundler (webpack) and individually (lazily) served on demand to the browser instead of sending all components at initial load which improves application performance.
A router-based code splitting strategy determines to load such components during page transitions, navigation or similar actions when users are normally not expected to interact with the page, with the help of a navigation/router component (React-Router).
React's built-in Lazy and Suspense components are used to load dynamic imports and display a fallback screen till loaded. Loadable-component library is a popular alternative which also supports code-splitting during server-side rendering.
Coverage - jscoverage, Istanbul
Test runners - jest, mocha, Jasmine
Assertion library - chai
Unit testing - jest
BDD - jest-cucumber
Testing utilities - Enzyme, React-testing-library
Shallow Renderer is a React testing library to test the working internals of a React component. It does so by rendering only “one level deep” and asserting what its render method returns without worrying about the behavior of child components, which are not instantiated or rendered.
It's worth noting that Shallow Renderer doesn’t:
Enzyme allows access to the implementation details by setting state, mocking child components, rendering results and asserting them. It could become brittle when implementation code changes frequently. To compare, the React-testing-library doesn't allow access to the implementation details or to set state. Instead, it encourages BDD-style tests which are less brittle and assert reproducible actions a user could perform instead of concerning implementation details.
This list isn't exhaustive, and interviewing typically includes an assessment of soft skills and technical ability through a take-home assignment or live coding exercise. You can learn more about hiring here.