Guide to interviews — React edition

Joqim
5 min readApr 6, 2022

--

Migration from class-based components to functional components seem to be the trend among organizations. I have put together select topics which cover few atypical concepts in React and how hooks amplify these features.

Higher-order components (HoC)

This is still relevant as HoC has been used extensively in several codebases.

Modern implementation of HoC’s involves hooksand renderProps.

Consider the following example, in the App functional component, the backgroundColor is either red or an empty string depending on the boolean property of props.hovered. This value is returned from our HoC detectHover.

When exporting the App component in export default detectHover(App), we’re also exporting what is getting returned from our HoC.

HoC can be defined as a function that receives a component as an argument and returns a newly augmented component.

The goal for why we’re doing this is to presumably have this logic detectHover in more than one place throughout the app.

Higher-order components are a way to share logic throughout the app without having to re-write the logic over and over.

RenderProps

Similar to HoC, renderPropsare still extensively used in codebases and because companies don’t have the luxury of moving over to hooks.

The render function inside the App component is being called by <DetectHover render={render} />

DetectHoveris a component that will effectively accept a prop called render to which you need to pass a function that will render your JSX.

We are invoking the render function by passing hovered as an argument to the actual function.

Again as a means to re-use logic across our application using the renderProp approach.

Hooks

Hooks allow hooking into React class components’ lifecycle methods within a functional component.

React documentation mentions that with HoC and renderProps, it can result in “wrapperHell”.

Hooks allow extrapolating logic into a separate function without having to create another wrapper.

We have a custom hook termed useHover. We attach the hoverRef to the div.

Within the useEffectwe grab the node out of ref.current and ultimately return the value determining if it is getting hovered or not getting hovered.

useEffect

useEffect simulates the following class component’s lifecycle methods,

1. ComponentDidMount

The useEffect dependency array is an empty array. This will run only the first time.

2. ComponentWillUnmount

The cleanup function inside return under useEffect .

3. ComponentDidUpdate

In this case, useEffectcontains an argument in the dependency array. In the below example, every time the value of numberchanges, the useEffect will be run.

Memo

React.memo makes a component only render if the props that it's accepting are in fact changing. Even if my parent component changes but if the incoming props to my component are not changing, I don't want to render again.

In the above example, the Child component doesn't receive any props but is still re-rendered on state change.

To overcome this issue, we import memofrom React and simply wrap the child component with the memofunction.

For class-based, we use the shouldComponentUpdatelifecycle method or alternatively a pure component. For functional components, we use Memo .

This might be a rather small example where such optimizations don’t mean much but it's the contrary for large-scale applications.

React API’s:

useCallback

In the below example, the Child component takes a function someFunc as a prop. Despite the fact that the Child component is wrapped in a memo and presumably the prop that is passed to it is not changing (because it's just a function), it's still rendering over and over again. Right?

However, that is not true as the argument which is being passed to the Child component is in fact changing. Every time the App component re-renders a new function is getting created which is passed to the Child component. Even though the function is equivalent and doing the same thing, it is a brand new function in memory. Thus Memo thinks a new prop is getting passed in and begins to re-render.

useCallbacktakes 2 arguments, the function you want to memoizeand a dependency array.

useMemo

As useCallbackmemoizes functions, useMemomemoizes values. Consider the below example, where the maximum value is to be returned from a really large array.

This is a very contract example but the point highlighted is that there is a series of inefficiency within our code here because we have a function that is doing expensive work repeatedly even though the outcome is going to be the same because the input is the same.

Implementing useMemo solves this issue. The last time the function ran, it gave us the number 9. So every time the function is run, again and again, it gives the number 9 without having to recompute the function again.

There should be another article emphasizing the compilation of React concepts in the near future. I’d recommend keeping an eye out for them.

--

--

Joqim

React enthusiast and a passion for revolutionizing technologies