loading...

How knowledgable you are about React? See common mistakes people make

adamklein profile image adam klein Updated on ・3 min read

Low hanging fruits

From my experience interviewing React developers, there are things that many developers don't know, but are quite easy to learn, and will help them become better React developers, and handle quirks and bugs.

They are knowledge pieces about how to use React, and how React works.

Ready? Here are the the questions:

If we manually change the DOM, will React take this into consideration when rendering our app?

To answer this, you need to know how the virtual DOM works.
Plainly speaking, the virtual DOM is a representation of the DOM tree state, in plain JavaScript objects.
When React renders our application, it renders the new virtual DOM, and compares it to the previous virtual DOM. Notice that it doesn't look at the current state of the DOM at all in this stage.

Meaning - if you manually change the DOM, React will ignore these changes, and/or override them if it re-renders that element.

What causes a component to re-render?

The answer many people give is - either state changes, props change, or context changes.
A more correct answer is - state changes, the parent re-renders, or context changes.
By default, React renders all child components if the parent renders, even if the previous props are exactly the same.

The comparison of props only happens for pure components, or components that implement Memo/shouldComponentUpdate.

What is a functional component?

For some reason, many developers think that all functional components are pure. That is not the case. Functional components used to be stateless, but now with hooks that's not the case either. So the main difference between functional components and class components is just the syntax, and that you can only use hooks inside functional components.
Also, there are some things you can only do with class components, like defining ErrorBoundaries.

Does a component name have to start with a capital letter?

This is a tricky question. While a single variable must start with a capital letter to serve as a component, if you use a nested property then it can be a lowercase letter as well. This syntax is valid:

comps = { myComp: () => <div>hi</div> }
...
return <comps.myComp/>

Does state update asynchronously?

This is a very tricky one, especially since React docs literally say that it is asynchronous.

Take this code for example:

function MyComp() {
  console.log('render');
  const [counter, setCounter] = useState(0);

  const onClick = () => {
    setCounter(prev => prev + 1);
    console.log('after setCounter');
  }

  return <button onClick={onClick}>Click me</button>;
}

The logs will be: 'after setCounter', 'render'.
So it seems like render does happen asynchronously after state update. But what if we add an async log after promise resolve:

function MyComp() {
  console.log('render');
  const [counter, setCounter] = useState(0);

  const onClick = () => {
    Promise.resolve().then(() => console.log('promise'));
    setCounter(prev => prev + 1);
    console.log('after setCounter');
  }

  return <button onClick={onClick}>Click me</button>;
}

Now the logs will be: 'after setCounter', 'render', 'promise'. Which means that render was synchronous (it happened before the promise was resolved).

So what's going on?

It feels async, because React performs our event handlers inside a batch. Meaning the render function will only be invoked after the event handler finishes. All state updates are queued until then.
So it might feel asynchronous, but it happens synchronously after the event handler finishes.

To even complicate this further, in concurrent mode the render might be truly async after all.
So React team's advice is to treat state updates as if they were always asynchronous, and I think that is good advice.

When to use a layoutEffect and when to use an effect?

Layout effects receive much less attention, and many developers don't completely understand them. The main difference between them and effects, is that layout effects happen synchronously after the commit phase (meaning after the actual DOM changes), and effects happen asynchronously.

So when should you use a layout effect? For example, when you want to avoid flickering of the UI. For example:

const ScrollSync = ({ scrollTop }) => {
  const container = useRef();
  useLayoutEffect(() => {
    container.current.scrollTop = scrollTop;
  }, [scrollTop]);
  return <div ref={container}>...</div>
}

We use a layout effect to bind scroll position of an element to state, to ensure it will happen synchronously and not cause any delay.

Is it OK to save a reference to the event parameter from event handlers?

The answer is no.

The event object in React is recycled. Meaning - in the future, the same event reference might point to a different event.

If you must - save a reference to properties of the event, or the native event, or call event.persist() to detach it from the event pool.

Wrap up

I hope you learned something new, or at least got some order or new perspectives about the things you already know.

If you have any feedback or I made a mistake - please let me know in the comments section.

Posted on by:

adamklein profile

adam klein

@adamklein

I'm a web developer and consultant, web GDE, and author of open source libraries. I co-founded 500Tech, a company that specializes in frontend technologies. I love coding, and love speaking about code

Discussion

markdown guide
 

For some reason, many developers think that all functional components are pure. That is not the case. Functional components used to be stateless, but now with hooks that's not the case either. So the main difference between functional components and class components is just the syntax, and that you can only use hooks inside functional components.

Blame the codebases they're working in, and often old versions of React/React curriculum they're learning in e.g. boot camp.

It's common to hear "don't worry about migrating your existing class components to functional with hooks any time soon, just consider FC/hooks for new component development." I disagree. After seeing the difference in transpiled output and getting a feel for the functional variants of lifecycle methods, I've even started looking to port third party dependencies to hooks.

Unfortunately, a lot of the companies they're coming from don't share my opinion.

Also, there are some things you can only do with class components, like defining ErrorBoundaries.

Technically true (c'mon Facebook, I don't ever want to see a class component again), but use-error-boundary is very handy for this (and I wouldn't fault a candidate for referring to it if Error Boundaries are brought up).

 

Thanks for the feedback :)
I agree many bootcamps don't go deep enough, or even mislead developers. I hope some of them read posts like this one and will improve the curriculum :)

 

I've had surprisingly good luck with boot camp grads, quite often better than grads from some of the best CS programs (it helps that they're not wasting a year or more learning Java if they're going to be FEDs, or loaded down with more work for core classes than major classes), but I largely attribute that to personal drive, "spend it like it's your own money" mentality (critical with bootstrapped startups), and higher likelihood to self teach (possibly due to the camps not going deep enough or, as I conversely hear sometimes, the way some of them make students "drink from a fire hose"). If the obsession over degrees weren't so awful when I was trying to break in (and it's still pretty terrible), and boot camps were as widespread as they are now, I might have opted for one instead of all the time and money I wasted on college.

With complete hindsight, though, I would have just saved the money all but completely and spent all that time self teaching, perfecting my portfolio and lighting up the crap out of my GitHub contribution graph (instead of being too busy outside of school building other people's proprietary stuff for way too little pay to work on my portfolio or FOSS, for which college gave me nothing of value to share). I'm trying to do my part to fight that mindset for newer devs:

LinkedIn Education and Certifications sections

Either way, I make "You Don't Know JS" required reading, and get them up to speed on FC, context, and hooks (the shock once it clicks and they realize they may not ever have to write another class component is priceless).

 

How important do you think being able to answer these questions is when it comes to finding good candidates that actually get stuff done for the company?

 

Good question. I don't think everyone on the team must know this in an interview.
But I believe everyone should be interested in it and thrive to learn more and more about the framework.
And it shouldn't come at the expense of the ability to deliver and good work ethics