How knowledgable you are about React? See common mistakes people make
Tags: react, javascript
Published: 2020-07-12 11:23:50

## 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:
```jsx
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:
```jsx
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:
```jsx
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:

```jsx
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.