<

Things I learned when I started using React at work

Until now, I had only used React in my private life. Recently, I've had more opportunities to use React at work, so I thought I'd document what I've learned.

History of React

I was curious about why React was created. I did a little research and summarized it in the following article.

I think React was created to solve the following problem:

  • As the DOM tree grows, the load of cascade updates due to lower changes increases

So, I think React created a mechanism called virtual DOM to solve this problem.

Virtual DOM, Difference Detection Process, and Fiber

React operates on the virtual DOM, not directly on the DOM. The virtual DOM is, as the name suggests, a virtual DOM. To reflect the virtual DOM to the DOM, there is an algorithm called difference detection process (reconciliation), and there seems to be an algorithm called Fiber aimed at optimizing rendering (priority). I think these reduce the load of rendering. (I don't know though)

My understanding is still shallow, so I want to learn more in the future.

When is the rendering timing?

Rendering Timing

Basically, when React renders a parent component, it also renders the child components.

When you call a function that queues re-rendering, such as setState or forUpdate, the component will be rendered.

As the codebase grows, rendering performance deteriorates. Therefore, performance optimization is required.

Performance Optimization

There is no need to optimize performance from the beginning, but it may be necessary depending on the requirements. As a means of optimization, you can use the following three functions in React.

  • memo
    • Can skip the rendering of a component
      • If there is no change between the previous props and the current props
  • useMemo
  • useCallback
    • Can memoize a function
      • Used in conjunction with memo

Performance Optimization – React can also be a reference.

Comparison Algorithm

In React, it seems that Object.is() is used to determine whether a component or state has changed. The sample code for Object.is is as follows.

Object.is("foo", "foo"); // true
Object.is("foo", "bar"); // false
Object.is([], []); // false

var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false

Primitive values such as strings or integers are fine, but non-primitive values (Objects) require consideration. For example, in the case of memo, you can pass a comparison function as the second argument. For example, it looks like this.

function MyComponent(props) {}
function areEqual(prevProps, nextProps) {
  return JSON.stringify(prevProps.foo) === JSON.stringify(nextProps.foo);
}
export default React.memo(MyComponent, areEqual);

As written on the official page, use it only for performance optimization.

Tips

Due to the use of Object.is(), ingenuity is required for state updates of non-primitive values.

const [items, setItems] = useState(["a", "b"]);

// NG
items.push("c");
setItems(items); // 変更されない(Object.is()→true)

// OK
const newItems = [...items, "c"];
setItems(newItems); // 変更される(Object.is()→false)

The NG side is reusing the same object, while the OK side is creating a new object.

Performance Investigation

I think it's better to investigate performance from the top down.

  1. Use Chrome Developer Tools > Lighthouse to check the performance score
  2. Use Chrome Developer Tools > Performance to find areas where processing takes time
  3. Use React Developer Tools > Profiler to investigate areas where rendering of React components takes time

React Component Design Patterns

When implementing components in React, there seem to be the following three patterns.

  • Container and presentation
    • Separate logic and UI
    • Often named XxxContainer, Xxx
  • Higher order component
    • Higher-order components
    • Often named withXxx
  • Function as child
    • Pass a function, not a component, as a child

Extract Logic as Custom Hooks

From the perspective of testability and reusability, it seems better to extract logic as hooks.

Naming often starts with use.

Others

  • I want to place the following files in the same folder as the component code
    • Test code (test)
      • To know the specifications
    • Catalog code (storybook)
      • To see the UI
    • Style code (scss)
  • Use debounce for onChange of input elements, etc.
    • When the processing of onChange is heavy

If it was helpful, support me with a ☕!

Share

Related tags