React Interview Questions 2020
Higher Order Components
A function that receives a component as an argument and then returns a newly augmented component.
Context
Context is a mechanism that allows us to pass data from one component down to another component. This sounds like props but the difference is that props only allows us to take data and pass it down to it's direct child. If the child then wants to take that data and pass it down to it's child, it can still do that with props but this process can only continue one level at a time. Context allows us to pass data from one component down to as many components deep as you want to within that same tree.
Hooks
Hooks allow us to 'hook' into the methods of a React lifecycle component within a functional component without having to define a class. Hooks also allow us to define our own custom hooks which we can then use to share logic across multiple different components, similar to a higher order component or render props. With higher order components and render props, there is an issue known as 'wrapper hell'. In order to use a render prop or higher order component, you have to define a new component and then that component is the one that renders the main component so you're therefore creating a wrapper around the primary component. This becomes a problem when you have wrappers around wrappers around wrappers. Hooks solves this problem by creating custom hooks which allow us to extrapolate logic into a separate function without having to create another wrapper.
Lift State Up
If you have two or more components that are trying to use the same bit of data, take these components and put them together as siblings inside a parent component that lives on top of them and give (lift) the state to the parent. They will now be in sync and whatever changes happens to the state in the parent component will be passed to both children.
Unidirectional Data Flow
In React, data only flows in one direction, from the top to bottom of the tree (parent to child). This is done through props being passed from parent to child. A child is not able to pass data up to it's parent. In React, this data flow looks like: - state is passed to the view and to child components - actions are triggered by the view - actions can update the state - the state change is passed to the view and to child components The benefits of this are: - Easier to debug, as we know what data is coming from where. - Less prone to errors, as we have more control over our data. - More efficient, as the library knows what the boundaries are of each part of the system.
Controlled vs Uncontrolled Components
In a controlled component, the form data is handled by the state within the component. The state within the component serves as "the single source of truth" for the input elements that are rendered by the component. Uncontrolled components act more like traditional HTML form elements. The data for each input element is stored in the DOM, not in the component. Instead of writing an event handler for all of your state updates, you use a ref to retrieve values from the DOM.
Importance of Keys
Keys are a way for React to uniquely identify each individual item within a list. When React tries to make changes to the DOM, it takes the current tree and compares it to the new tree that it will attempt to render based on the changes that have been made to the state. It then takes the new tree and tries to commit to to the DOM in the most efficient way possible by making the least amount of changes necessary. If React is looking at a list without keys, it will automatically assign them based on the index. This is not ideal because if you try to remove the first item, it will see that the 0 index has been removed and will repaint the entire list starting at index 0. It does not look at the value. However, if each item has a unique key, it will simply just remove that item.
React.memo()
React.memo() allows us to make a component only render if the props that it is accepting are changing. The parent component may be re-rendering as it's state updates but if the props being passed to the child are not changing as well then we do no want it to re-render the child component. To achieve this, you would simply import 'memo' from react and wrap the child function in a memo() method. With class components, to achieve this, you would use shouldComponentUpdate() or a pure component.
refs
Refs provide a way to access DOM nodes or React elements created in the render method. In the typical React dataflow, props are the only way that parent components interact with their children. To modify a child, you re-render it with new props. However, there are a few cases where you need to imperatively modify a child outside of the typical dataflow. The child to be modified could be an instance of a React component, or it could be a DOM element. For both of these cases, React provides an escape hatch. When to Use Refs There are a few good use cases for refs: - Managing focus, text selection, or media playback. - Triggering imperative animations. - Integrating with third-party DOM libraries.
useCallback()
Returns a memoized callback. Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).
useMemo()
Returns a memoized value. Pass a "create" function and an array of dependencies. useMemo will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render. Remember that the function passed to useMemo runs during rendering. Don't do anything there that you wouldn't normally do while rendering. For example, side effects belong in useEffect, not useMemo. If no array is provided, a new value will be computed on every render.
Props vs. State
State is when a component defines data locally within itself. Props is when that same data get's passed down to another component. The fundamental difference between these two is that state can be changed, manipulated and mutated whereas props cannot be changed. In order for props to be changed, the child needs to call into the parent component to ask the parent to change it's state.
Render Props
The term "render prop" refers to a technique for sharing code between React components using a prop whose value is a function. A component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic. <DataProvider render={data => ( <h1>Hello {data.target}</h1> )}/>
useEffect
The useEffect hook can effectively do 3 things: - componentDidMount() - for the dependency array, if you set it as an empty array, you are setting this up to run once when the component mounts and never again. - componentDidUpdate() - for the dependency array, if you pass in a variable from useState() as an argument, useEffect will then track this variable and re-run every time the variable updates - componentWillUnmount() - inside useEffect, you define what's known as a cleanup function. You return a function and this function handles your clean up, essentially only running when the component unmounts