Technical interview questions for React developer positions (+coding challenge tips & TypeScript/JavaScript questions)

This post is a record of all the technical questions I received in interviews for front end developer positions with React.js. I wrote this post so that I can review what type of questions will be expected in the next job interview when React is relevant to the position. Hopefully, this will be helpful for others.

(I wrote answers to those questions. However, please note that these answers were just my thoughts and haven’t been reviewed by anyone).

(UPDATED: At the end of this article, I added questions I received which are relevant to TypeScript)

Interview questions

How do you find performance bottleneck in developer tools?

If you’re using React v16.5+, Profiler API in Chrome Devtools can be used for detecting components that take too long to render. The steps are:

  1. Determine when the UI is working slowly
  2. Open Devtools and click Profiler
  3. Start recording
  4. Find the longest, yellow bar. The bar is taking the longest time to render, so it should worth examining.

Here is a more detailed article on how to use it.

If Profiler API isn’t available, you can still use Performance API in Devtools. How to use it very similar. Once you record the UI’s behavior, click Timing. Here is a detailed article on this feature.

What is the state in React, and when is it useful?

The state in a React component is a JavaScript object, which stores the state of the component.

States are useful when you have to determine the behavior of the component based on the state. For example, if you have to disable (or enable) a button based on the content of an input box, you can update the “disable” attribute of the button based on the value of the input box, which can be bound to the state of the component.

What is Redux, and why is it useful?

Redux is a state management tool. With Redux, the state of a React application is stored in one place, which is called the reducer. The state in the reducer can be accessed by connecting a component with the reducer.

One reason why Redux is useful is that Redux makes it easy to pass state values across components. In order to pass a state value from one component to its child or parent component, you usually do so with props. It’s not difficult if the value has to be passed between a parent and its child component, but it can be quite challenging if you have to do so across multi-levels of components. This can be quite time-consuming and also makes components tightly coupled.

Another reason for using Redux is that state changes will be more predictable by using Redux. In order to update states in Redux, you have to use a function called “action” with a method called “dispatch”. With the same action, Redux always produces the same state, which makes it easy to see (or predict) how states will be updated.

On top of that, it’s easy to debug states with Redux DevTool, which is a Chrome extension. With Redux Devtool, you can see which action was dispatched when a state gets updated.

What is Immutability and how is it relevant to JavaScript and React?

Immutability means unchangeable. In programming, this is often a characteristic of objects. Immutable objects are ones that cannot be directly modified once they are created.

In JavaScript, objects (including arrays) are mutable. For example, if you assign an object (let’s call it original) to a variable (let’s call it copied) and then update a property value of the copied object, you’ll see the same value in both the original object and the copied variable (as per the code below).

const original = { num:1 };
const copied = original;
copied.num = 10
// print :10
original
// print : {num: 10}

Likewise, if you update a property of the original object, the copied object will be updated in the same way.

This can be problematic because you won’t know how the original object looked like once it’s mutated. Also, the mutated objects (the original and copied objects) will have the same reference. So, if you compare them with “===”, you’ll see “true”, which may cause confusion. In order to prevent mutation, you can use “Object.assign” function or the spread operator.

In React components, you are not going to mutate states. Instead, you’ll use the this.setState() function or React Hooks. On top of that, with Redux, you’ll create a brand new state every time you need to update a state value, which is done by dispatching an action. Also, props are immutable.

What is functional programming?

Functional programming is a programming paradigm, which has the following characteristics.

  • The application is composed of pure functions, and application state flows through pure functions
  • Changing state, mutating data, and producing side effects are avoided
  • Declarative rather than imperative

In functional code, the output value of a function depends only on its arguments. So, calling a function with the same value for an argument always produces the same result. (On the contrary, in object-oriented programming, the global state (as well as the argument to the function) can affect a function’s resulting value). 

What are the Pure Functions?

Pure functions are ones that return values solely based on their argument (i.e. what was passed into it). A function is “pure” if it always produces the same result as long as the same value is passed into it. Also, it doesn’t modify values outside of its scope. This makes it independent from any state in the system. Therefore, a pure function can never mutate data, produce no side effects and can be easily reused. An example of a non-pure function will be a function that makes an API call or returns an unpredictable result.

Impure function:

let result = 0;
const calculateSquare = ( num ) => {
    result  = num * num;
}
calculateSquare(10)
console.log(result)
// 100

Simple Pure function:

const calculateSquare = (num) => num * num;
console.log(calculateSquare(10));
//100

Both the impure and pure functions above return “100” while their argument is “10”, but the pure function doesn’t mutate any data outside of it.

What do “side effects” mean for functional programming?

Side effects refer to state changes that can be observed outside the called function except for its return values. In other words, side effects are any internal or external state changes.

Here are examples of side effects from Wikipedia.

  • modifying a non-local variable
  • modifying a static local variable
  • modifying a mutable argument passed by reference
  • performing I/O or calling other side-effect functions

How is functional programming relevant to React applications?

React applications have some aspects of functional programming.

For example, React components are supposed to return JSX with the render method and are expected to return the same results based on the input values (i.e. props).

Also, React components can be functional components, which are stateless and always render the same elements based on the input.

const Hello = (props) => <div>Hello {props.name}</div>;

What is HOC and what is it used for?

A higher-order component is a technique that wraps a component and returns a new component without changing the data of the original component. HOC is meant to abstract logic in a way that the same logic can be used across multiple components.

For example, react-router, a popular library, has a HOC function called “withRouter”. This function passes props which are relevant to the browsing history and the URL (those props are called history and location, respectively).

Likewise, redux’s “connect” function takes a component and returns a new component with additional props, which are defined by mapStateToProps and mapDispatchToProps. (You can elaborate the connect function other than mapStateToProps and mapDispatchToProps, but that’s off-topic)

What is the two-way binding and is it relevant to React?

The two-way binding means that…

  • When properties in a model are updated, the UI is updated accordingly
  • Likewise, when a UI element is updated, the corresponding property in the model is updated accordingly.

React does not bind data and UI in this way by default. In React, mutable states are supposed to be updated only with the setState() function, and not be changed just by updating a UI element.

Assuming that you’re creating a component that reads a CSV file, the file will have to be processed, and the processed data will be stored in the server, will you make the parsing feature in front end or back end?

(This is a question which I got during an actual job interview after I completed a coding challenge)

It’ll be better to do the parsing task in back end, because if the computer doesn’t have a lot of memories (e.g. smartphones) and the file is really large (let’s say more than 10MB), the browser may run out of memories.

Coding challenge Tips

How do you break the API calls?

This is also a question I received after I completed a coding challenge, which involved both front end and back end development. If you are going to create a REST API route, consider how it can be broken (although this also applies to your daily work as a web developer).

For example, if an API call takes file data (image file, CSV, etc), how much data will be accepted? What if the input value involves an invalid data type (string vs number, etc)?

Stay consistent in using characters, colons/semi-colons, files, etc

You may appear unprofessional if your usage of characters, files, etc is inconsistent. Here are some examples.

  • For imports, use only single or double quotes only (I once used single and double quotes for import, because of the wrong configuration of the text editor. Now I use single quotes only. On VS Code, install prettier-vscode -> manage -> Extention Setting -> tick Prettier: Single Quote. This ensures that “import” will use single quotes. Likewise, if you tick Prettier: Jsx Single Quote, JSX will use single quotes)
  • Use only CSS or SCSS, not both unless you really have to (Once I was in rush and forgot to delete an unnecessary CSS file. Apparently this gave a bad impression to the reviewer.)
  • Be careful about creating a file like “utile.js” or “config.js”. If they are stored along with folders (e.g. components), it’ll be better to create a folder with “index.js” (e.g. “/src/util/index.js”).

If you use the React boilerplate (create-react-app), remove every unnecessary file

The major advantage of using create-react-app is that you don’t have to configure Babel and Webpack manually.

On the other hand, create-react-app comes with files that are not always necessary, such as serviceWorker.js. So, when you use it for your coding challenge, you have to make sure that all the unnecessary files (including the logo) are removed.

Make sure there is no typo

This is self-explanatory. (I’m writing this to myself)

Re-use component

For example, let’s assume that you’re creating an application that shows a list of people (employees in your company, your clients, etc). You need to create a page (or a modal) where you show the details of one person, and then you’ll create a page where you can create a new person instance.

Try to use the same component for showing details of a person and creating a person instance.

NEW!

Questions related to TypeScript

Should @types be dependencies or devDevendencies in package.json?

If you are creating your own npm module which needs a module called “Dependency”, the types of the “Dependency” should be in dependencies. Otherwise, if someone uses your module, your module won’t be able to guess the types of “Dependeny”, because it won’t be installed. Here is a moe detailed explanation.

Otherwise, @types should be devDependencies.

Why (or when) is TypeScript useful for React apps?

From my personal experiences, the following are the main reasons why it’s useful.

  • It helps me to refactor components because each component can have its own interface for props. For example, if I have to update props of a component that is used by many other components, TypeScript will tell me which components are affected (and how they are affected) upon compiling. (PropTypes can identify errors caused by types of props, but they do so at runtime. So, I have to run the app just to see whether there is any prop error). This is especially true if the app is already huge.
  • It allows me to create an interface or a type at the variable level too. For example, I like to use a type called “Status” with Redux. This Status type can have three strings, “PENDING”, “FULFILLED”, and “REJECTED” (and it can be null too). When I need to call a REST API call through a Redux action, I can update the status of the REST API call within a reducer, and make sure that the status is always one of them. In this way, I won’t make an error of wrongly updating the status of a reducer.
  • It helps me to understand the code. For example, TypeScript tells me what arguments a function accepts and what the function is going to return at first glance. With vanilla JavaScript, it’s sometimes unclear whether a function returns a value or not, and what type of value will be returned.

How is TypeScript relevant to SOLID?

TypeScript allows me to use Dependency Injection.

Explain Omit and Pick in TypeScript.

Omit allows you to create a new type by choosing an existing type or interface and omitting keys.

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Omit<Todo, "description" | "completed">;

const todo: TodoPreview = {
  title: "Clean room",
  // description: "test", 
  // completed: false,
  // If description or completed is uncommented, it won't be compiled
};

Pick allows you to create a new type by picking keys from an existing type.

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Pick<Todo, "title" | "completed">;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
  // description: "test"
  // 'description' isn't picked, so uncommenting it will show a warning message
};

Explain the difference(s) between Interface and Type.

  • Interfaces can be implemented by classes, but types can’t.
  • An existing interface can have a new field, whereas it’s not allowed to add a new key to an existing object type.
  • Type can be used for creating a new type, such as unions and tuples.

There are more subtle differences (e.g. Interfaces are extended with “extends”, while types are with an intersection (“&”)), but I think these are the ones that are particularly important.

Here’s an excerpt from the official documentation:

Because an interface more closely maps how JavaScript object work by being open to extension, we recommend using an interface over a type alias when possible.

On the other hand, if you can’t express some shape with an interface and you need to use a union or tuple type, type aliases are usually the way to go.

What are the union or tuple types?

A union type indicates that a value can have multiple types.

e.g.
type FooId = string | number;
type RestApiStatus = 'PENDING' | 'FULFILLED' | 'REJECTED' | '';

A tuple type indicates which type is allowed at which index in an array

e.g.
type FooData = [number, string];

NEW!

General Javascript development questions

Explain the difference(s) between dependencies and devDependencies in NPM

Dependencies are required to run. (e.g. react, redux, axios, moment.js)

Dev dependencies are required for development (e.g. jest, enzyme eslint, babel, webpack, node-sass)

Explain the difference(s) between let and var in Javascript

let variables are available within the scope of a block statement, or expression where it is declared.

var variables are available globally, or locally to an entire function regardless of block scope.

link

Explain “this” keyword in Javascript.

The “this” keyword refers to the object it belongs to.

However, depending on the context, what is referred to by this keyword slightly changes. The following is an excerpt from w3school (link).

  • In a method, this refers to the owner object.
  • Alone, this refers to the global object.
  • In a function, this refers to the global object.
  • In a function, in strict mode, this is undefined.
  • In an event, this refers to the element that received the event.
  • Methods like call(), and apply() can refer this to any object.

Leave a Reply

Your email address will not be published. Required fields are marked *