1. Two Rules of Hooks
Always use hooks at the top of a component and avoid loops or conditions. Only call hooks inside React components or custom hooks.
Watch section from 0:13 →Engineering video
9:14 · 17 April 2024
Always use hooks at the top of a component and avoid loops or conditions. Only call hooks inside React components or custom hooks.
Watch section from 0:13 →React lazy uses Webpack dynamic imports to separate code into unique bundles for lazy loading, while suspense displays a fallback while loading.
Watch section from 0:43 →Using a unique key attribute helps React identify list items and avoid re-rendering elements that are still present, improving performance.
Watch section from 2:14 →Use memo memorizes expensive computed values across renders, recomputing them only if the dependency array changes.
Watch section from 3:00 →Context allows passing state without prop drilling, but unrelated state in a single context causes unnecessary re-renders across connected components.
Watch section from 4:00 →Class components allow direct access to lifecycle methods, enabling features like error boundaries that are not directly available in functional components.
Watch section from 7:12 →Today we are going to go to some senior React interview questions. These questions cover many topics about React, about depth. Feel free to showcase your uh software engineer skills. First question, senior level question. What are the two rules of hooks in React? Okay, so the two rules of hooks in React are number one, you should always use hooks at the top of your component and avoid using them inside while or for loops, that will probably um trigger very um unexpected behaviors.
And the number two rule is you should only call hooks either in other custom hooks, inside other custom hooks or inside React components, you should never call them inside plain JavaScript functions. Second question, it's, can you explain how React lazy and suspense work under the hood? You know, and you know, what are some pros and cons of using those implementations? Basically, React lazy allows you to lazy load a component.
Under the hood, it instructs Webpack to separate that code into a unique bundle and it will tag that bundle with a dynamic import. That means Webpack will only request that bundle when it's actually being used rather than on the initial load. And we need to wrap it in suspense because suspense needs to show a fallback while we load that component. When it comes to disadvantages, you you got to be careful, I saw people using this left and right, but adding more requests to your critical landing pad, it's a performance anti pattern.
So you really want to lazy load the things that are not needed in the initial loading, and I've seen a lot of people abusing this and end up lazy loading components that should be there in the initial loading and that messes up uh even worse performance rather than improving it. And the other thing is you've got to be careful with service side rendering because they're not uh as far as I know, React lazy is still not yet compatible with it.
Okay, what would be a use case, the perfect use case? For React lazy and suspense to work together, the perfect use case, it's when you have, for example, you want to do router, what they call router base splitting. when you basically at least loading to your different react router pads. And so if I'm on the whole homepage, I do not load all the JavaScript components needed to load maybe the user page.
Um, so you basically can split your code based on different paths. Now, a very specific React question, why do we need the key attribute when rendering an array or a list in React? Um, that's it's probably a linter error that you get and also you get a warning in the console. The reason for that is because if you help React identify your list items, whenever React renders that list, it will not render the elements that are still present.
So let's say you have a list of five items and by any chance you delete one of them, usually this happens in the parent component will trigger a render of all the child, which are all the list elements. If you added that key and that key doesn't change, so it's not in our array index, React knows that it shouldn't render those parts. So it will make everything more efficient. Now, going back to hooks, you know, have you heard about the use memo hooked, you know, when would you use it, um, what's your experience using use memo?
Uh, sure, so use memo is one of the performance hooks. Uh, there's two of them, there's use callback and use memo. Uh, use memo allows you to make a render faster when you have a certain value that's expensive to compute. Um, to be honest and be pragmatic, there's not so many use cases for production for it in the typical web app. Um, for the sake of example, maybe imagine you have something very expensive with you in the component like a foil up that goes to 100,000.
You if you use use memo, you'll only compute that operation. Once when you render the when you render the first time and then reuse the like basically memorize that result and use it in subsequent renders. Um, if the dependency array doesn't change. So use memo comes with the dependency array, if any of the dependency changes, then we need to recompute that method. to use memo. Are you basically use it to make re-renders faster when you have an expensive value in the render method in functional components? Now, moving on to something um quite related, but not so much, we are going to talk about React context. And my question is, you know, have you used it before? What would be the impact that it has over re-renders, talking about the rendering process in React? Basically, context allows you to place state at the top of the component tree and then be able to access that state without doing prop drilling. The problem you might see in production is you want to be very smart about how you split your state in context. If you have state that's totally unrelated in the same context, it means that whenever any of that state property changes, every component connected to this context will re-render. So if you want to optimize for fewer re-renders, it's very smart to split your state into different contexts. And so, whenever that state changes, you won't have to render the whole component, only the ones, the components that actually find that state relevant. You don't want to over-split, you don't want to have like 15 provider layers with 15 different contexts. So you need to find a balance between uh too much splitting and having everything in one React context. If you have everything in a single React context, you'll most likely have a lot of unnecessary re-renders. And what kind of state would you put in React context? Right, we're talking about state, there is global state, there is form state, there is local state, there's all kind of states in a web application. You know, why do we have React? Why do we need React context in the first place? We talked about eliminating the prop drilling. But um, you know, can we use it React context for all of our state? What kind of state would you add to React context? You probably want to add to React context the state, lightweight state that most of your
component will need. A good example is authentication state. If you look at most authentication libraries, they probably use react context under the hood. Um translation state also, it's built on top of react, so people change the language and you want all the components to display like the different um wording matching the the language setting. So that kind of state is perfect for for react context.
Uh I would not raise component or local state or form state to context, it's unnecessary most of the times. As a general rule, keep state as close to where it's being used. Uh it will avoid rendering, it makes things easier to test. And when it comes to uh state that has complex state transitions, like I worked for example in a lot of business applications where you have complex settings, maybe accounting software, the user changes one setting, but you have a nested state object that you need to change.
It's better in that case to do something like Redux or a more professional state machine implementation, which would allow you to very quickly have reducers and actions. You can have that in react context with use reducer. if you combine them, but it's just better to use a state machine. So, react context is just perfect for a lightweight state that you want to distribute to the whole application and you don't have too many complex state transitions.
One final question about the topic of class components and functional components, right? So, what are some things you could do with class components that you cannot do with functional components? Oh, that's a very good one because no one uses class components anymore. Um I would say probably the biggest difference is in functional components, you cannot act you cannot directly access life cycle method life cycle methods.
We do that through hooks, uh, which offers us basically a simpler simpler API to these methods. Um when does that become relevant or interesting? one good example could be for example, error boundaries. You whenever you have a react component, if you have a class component, you could use uh I think it should component through or not through, some of those lifecycle methods, that will actually catch the error and you can provide an error boundary, rather than your whole UI breaking apart because this component failed.
You can't uh necessarily do that with functional components. So, whenever you need an implementation that will hook into a specific life cycle methods, you should probably consider class components. Awesome. Uh thank you, Bogdan. Uh as for the people watching us, this is one video in many where we're making a series about the technical interview for senior JavaScript focused engineers, that means senior React interviews, senior NeoJS, senior frontend, senior backend.
You will see more of those videos coming up. If you have any questions that you want us to answer here, just drop it in the comments. And also if you are interested to join the free community that we've put together for software engineers where you will get quality accountability and feedback, check out the link below uh in comments. Um and also, on top of that, if you want to figure out your skills, where you're at, we have a free 10-call assessment for you to find your gaps to senior level and beyond.
And if you're interested in working personally with Bogdan and I in our premium mentorship program, then you can also book a quick chat with me and see if this could be a fit and if we could actually help you. As for Bogdan and I, we will see you in the next one.